camera2拍摄的照片模糊 [英] camera2 pictures taken are blurred

查看:474
本文介绍了camera2拍摄的照片模糊的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Samsung Galaxy S7边缘设备上拍摄照片时,我遇到不良行为.

I'm experiencing a bad behavior when capturing a photo on a Samsung Galaxy S7 edge device.

在拍照之前,我同时等待对焦和曝光,但是最后,与本地相机应用程序的输出相比,我有一种模糊的图像.

I wait simultaneously for focus and exposure before taking the picture but at the end I have a kind of blurred image compared to the native camera app output.

该问题在缩放的图像上尤其明显,但在未缩放时也存在.我还尝试启用光学图像稳定功能,但问题并未解决.

The problem is especially visible on zoomed images but is present also when not zoomed. I've also tried to enable the optical image stabilization but the problem isn't fixed.

下面是说明问题的链接示例图像.

Below are linked sample images explaining the problem.

本机摄像头图像

我的相机图像

这是代码:

图片捕获方法第1步:

public void capturePicture() {
    CameraState state = getState();
    if (state != IDLE && state != CLOSING && state != TAKE_PICTURE) {
            boolean af = false;
            boolean ae = false;
            if (isAFEnabled()) {
                af = true;
            } else if (isAEEnabled()) {
                ae = true;
            }

            if (!af && !ae) {
                takePicture();
            } else {
                triggerFocusAndExposure(true);
            }
    }

    return;
}

触发焦点和曝光的方法:

Method for triggering focus and exposure:

private void triggerFocusAndExposure(boolean picture) {
    setState(WAIT_PRECAPTURE_PICTURE);

    if (isAFEnabled()) {
        previewBuilder.set(CONTROL_AF_TRIGGER, CONTROL_AF_TRIGGER_START);
    }

    if (isAEEnabled()) {
        previewBuilder.set(CONTROL_AE_PRECAPTURE_TRIGGER, CONTROL_AE_PRECAPTURE_TRIGGER_START);
    }

    try {
        cameraSession.capture(previewBuilder.build(), new SCameraCaptureSession.CaptureCallback() {
            @Override public void onCaptureCompleted(SCameraCaptureSession session, SCaptureRequest request, STotalCaptureResult result) {
                setState(PRECAPTURE_TRIGGERED_PICTURE);
            }
        }, backgroundHandler);
    } catch (CameraAccessException e) {
        return;
    }

    try {
        previewBuilder.set(CONTROL_AF_TRIGGER, CONTROL_AF_TRIGGER_IDLE);
        previewBuilder.set(CONTROL_AE_PRECAPTURE_TRIGGER, CONTROL_AE_PRECAPTURE_TRIGGER_IDLE);
        cameraSession.setRepeatingRequest(previewBuilder.build(), mSessionCaptureCallback, backgroundHandler);
    } catch (CameraAccessException e) {
    }
}

等待焦点和曝光的方法:

Methods for waiting focus and exposure:

private void waitPrecapture(STotalCaptureResult result, boolean picture) {
    // Check if AF/AE triggered and/or finished
    if ((!isAFTriggered(result) || isAfFinished(result)) && (!isAETriggered(result) || isAEFinished(result))) {
        takePicture();
    }
}

private boolean isAFTriggered(STotalCaptureResult result) {
    Integer afMode = result.get(SCaptureResult.CONTROL_AF_MODE);
    return afMode != CONTROL_AF_MODE_OFF &&
            afMode != CONTROL_AF_MODE_EDOF;
}

private boolean isAfFinished(STotalCaptureResult result) {
    int afState = result.get(SCaptureResult.CONTROL_AF_STATE);
    return afState == CONTROL_AF_STATE_FOCUSED_LOCKED || afState == CONTROL_AF_STATE_NOT_FOCUSED_LOCKED
            || afState == CONTROL_AF_STATE_PASSIVE_FOCUSED || afState == CONTROL_AF_STATE_PASSIVE_UNFOCUSED;
}

private boolean isAETriggered(STotalCaptureResult result) {
    boolean aeMode = result.get(SCaptureResult.CONTROL_AE_MODE) != SCaptureResult.CONTROL_AE_MODE_OFF;
    return aeMode && cameraCharacteristics.get(SCameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
            != SCameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY;
}

private boolean isAEFinished(STotalCaptureResult result) {
    Integer aeState = result.get(SCaptureResult.CONTROL_AE_STATE);
    return aeState == null || aeState == SCaptureResult.CONTROL_AE_STATE_CONVERGED || aeState == SCaptureResult.CONTROL_AE_STATE_FLASH_REQUIRED
            || aeState == SCaptureResult.CONTROL_AE_STATE_LOCKED;
}

图片捕获方法第2步:

public void takePicture(){
    imageReader.setOnImageAvailableListener(reader -> {
        Image image = reader.acquireLatestImage();
        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes);
        image.close();
        singleSubscriber.onSuccess(bytes);
    }, imageSavingHandler);

    try {
        cameraSession.capture(captureBuilder.build(), new SCameraCaptureSession.CaptureCallback() {
             @Override
             public void onCaptureCompleted(SCameraCaptureSession session, SCaptureRequest request, STotalCaptureResult result) {
                 if (getState() == CameraState.CLOSING) {
                     return;
                 }
                 cancelAF();
             }

             @Override
             public void onCaptureStarted(SCameraCaptureSession session, SCaptureRequest request, long timestamp, long frameNumber) {
                 super.onCaptureStarted(session, request, timestamp, frameNumber);
                 shutterCallback.call();
             }    

             @Override public void onCaptureFailed(SCameraCaptureSession session, SCaptureRequest request, SCaptureFailure failure) {
                  singleSubscriber.onError(new RuntimeException("Error taking picture, onCaptureFailed"));
                  if (getState() == CameraState.CLOSING) {
                      return;
                  }
                  cancelAF();
             }
         }, backgroundHandler);

         setState(CameraState.TAKE_PICTURE);
     } catch (CameraAccessException e) {
         singleSubscriber.onError(new RuntimeException("Error capturing image", e));
     }
}

推荐答案

我已经找到了解决方法. captureBuilder自动设置CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITYCaptureRequest.EDGE_MODE_HIGH_QUALITY,但就我而言,设备在处理这些选项时遇到一些问题.设置CaptureRequest.NOISE_REDUCTION_MODE_FASTCaptureRequest.EDGE_MODE_FAST可以解决此问题.

I've found the fix. captureBuilder automatically sets CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY and CaptureRequest.EDGE_MODE_HIGH_QUALITY but in my case the device has some problem handling these options. Setting CaptureRequest.NOISE_REDUCTION_MODE_FAST and CaptureRequest.EDGE_MODE_FAST fixes the problem.

这篇关于camera2拍摄的照片模糊的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆