如何使用Camera2 API在Android中锁定自动曝光

时间:2019-05-01 13:31:36

标签: android android-camera2

我正在使用android-Camera2Basic Google示例。我正在尝试使用CONTROL_AF_REGIONSCONTROL_AE_REGIONS添加区域重点和区域曝光度。我对锁定自动曝光算法有一些疑问。

这是我到目前为止所做的:

1-取消以前的自动曝光和自动对焦触发:

mState = STATE_PREVIEW;
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, false);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_CANCEL);
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);

2-添加自动对焦和自动曝光所需的区域:


mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_REGIONS, meteringRectangleArr);
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_REGIONS, meteringRectangleArr);

3-设置焦点触发器:

mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
mState = STATE_WAITING_LOCK;
mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);

4-在mCaptureCallback中,我有以下代码设置了相机锁定焦点时的自动曝光触发:

try {                                                                                                                                        
    switch(mState) {                                                                                                                         
        case STATE_PREVIEW: {                                                                                                                
            break;                                                                                                                           
        }                                                                                                                                    
        case STATE_WAITING_LOCK: {                                                                                                           
            Integer afState = result.get(CaptureResult.CONTROL_AF_STATE);                                                                    
            if (CaptureResult.CONTROL_AF_STATE_FOCUSED_LOCKED == afState ||                                                                  
                CaptureResult.CONTROL_AF_STATE_NOT_FOCUSED_LOCKED == afState) {
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER, CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER_START);
                mState = STATE_WAITING_PRECAPTURE;
                mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
            }                                                                                                                                
        }                                                                                                                                    
        case STATE_WAITING_PRECAPTURE: {
            Integer aeState = result.get(CaptureResult.CONTROL_AE_STATE);
            if (CaptureRequest.CONTROL_AE_STATE_CONVERGED == aeState || CaptureRequest.CONTROL_AE_STATE_FLASH_REQUIRED == aeState) { //2, 4  
                mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AE_LOCK, true);
                mCaptureSession.capture(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);
        } else if(CaptureRequest.CONTROL_AE_STATE_LOCKED == aeState) {                                                                   
                mState = STATE_PREVIEW;
                mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);                                  
            }                                                                                                                                
        }                                                                                                                                    
    }                                                                                                                                        
} catch (CameraAccessException e) {                                                                                                          
    e.printStackTrace();                                                                                                                     
}

使用这些代码,自动对焦和自动曝光将在Samsung Note8上正常工作。但是问题是相同的代码不适用于Samsung J5。问题是当相机尝试对焦时(在J5中),它处于CONTROL_AF_STATE_NOT_FOCUSED_LOCKEDCONTROL_AF_STATE_ACTIVE_SCAN之间的无限循环中,并且预览将冻结。如果我将mCaptureSession.setRepeatingRequest(mPreviewRequestBuilder.build(), mCaptureCallback, mBackgroundHandler);更改为mCaptureSession.setRepeatingRequest(mPreviewRequest, mCaptureCallback, mBackgroundHandler);,则J5可以在自动对焦区域上正常工作(J5不支持自动曝光区域。因此我注释掉了J5的自动曝光部分!)。但是,当我在Note8上应用此修改时,曝光将适用但不会锁定,几帧后,它将恢复到之前的曝光。

那么,怎么了?我应该在mPreviewRequestBuilder.build()方法中使用mPreviewRequest还是mCaptureSession.setRepeatingRequest吗?为什么我使用mPreviewRequestBuilder.build()来选择J5股票?

0 个答案:

没有答案