Не удается получить сенсор Camera2 API для фокусировки на работу
Я не могу заставить фокусировку работать правильно на Camera2 API. При прикосновении я, кажется, фокусируюсь на секунду, а затем он становится очень размытым. Телефон Nexus 5X. Вот мой код для прикосновения, чтобы сосредоточиться.
private void refocus(MotionEvent event, View view){
//Handler for autofocus callback
CameraCaptureSession.CaptureCallback captureCallbackHandler = new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
super.onCaptureCompleted(session, request, result);
if (request.getTag() == "FOCUS_TAG") {
//the focus trigger is complete -
//resume repeating (preview surface will get frames), clear AF trigger
previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER, null);
try{
mSession.setRepeatingRequest(previewRequest.build(), null, null);}
catch (Exception e){
}
}
}
@Override
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
super.onCaptureFailed(session, request, failure);
Log.e(TAG, "Manual AF failure: " + failure); }
};
try {
final Rect sensorArraySize = manager.getCameraCharacteristics(mCameraDevice.getId()).get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
//Find area size
int x = (int)(event.getX()/(float)view.getWidth() * (float)sensorArraySize.width());
int y = (int)(event.getY()/(float)view.getHeight() * (float)sensorArraySize.height());
final int halfTouchWidth = 150; //(int)motionEvent.getTouchMajor(); //TODO: this doesn't represent actual touch size in pixel. Values range in [3, 10]...
final int halfTouchHeight = 150; //(int)motionEvent.getTouchMinor();
MeteringRectangle rect = new MeteringRectangle(Math.max(x - halfTouchWidth, 0),
Math.max(y - halfTouchHeight, 0),
halfTouchWidth * 2,
halfTouchHeight * 2,
MeteringRectangle.METERING_WEIGHT_MAX - 1);
mSession.stopRepeating();
transparentLayer.drawFeedback(rect);
//Cancel requests
previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_CANCEL);
previewRequest.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_OFF);
mSession.capture(previewRequest.build(), captureCallbackHandler, null);
//Now add a new AF trigger with focus region
if (isMeteringAreaAFSupported()) {
previewRequest.set(CaptureRequest.CONTROL_AF_REGIONS, new MeteringRectangle[]{rect});
}
previewRequest.set(CaptureRequest.CONTROL_MODE, CameraMetadata.CONTROL_MODE_AUTO);
previewRequest.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO);
previewRequest.set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START);
previewRequest.setTag("FOCUS_TAG"); //we'll capture this later for resuming the preview
//then we ask for a single request (not repeating!)
mSession.capture(previewRequest.build(), captureCallbackHandler, null);
}catch (Exception e){
e.printStackTrace();
}
}
Также есть еще одна вспомогательная функция:
private boolean isMeteringAreaAFSupported() {
try {
return manager.getCameraCharacteristics(mCameraDevice.getId()).get(CameraCharacteristics.CONTROL_MAX_REGIONS_AF) >= 1;
}catch (Exception e){
return false;
}
}
Какова может быть причина, по которой фокус работает в течение короткой секунды, а затем перезапускается или становится полностью размытым? Я не могу найти решения, которое может помочь.
Спасибо всем!
1 ответ
Я бы попытался установить AF_TRIGGER в IDLE в onCaptureCompleted - удаление его не совсем точно указано.
Кроме того, мне не ясно, как вы переводите координаты касания экрана в координаты активного массива камеры для областей измерения. Похоже, вы предполагаете, что координаты идентичны, что не соответствует действительности. Это не должно вызывать размытости, но заставит вас сосредоточиться на другой области, чем вы думаете.
Вам необходимо правильно масштабировать x и y (в зависимости от текущей области обрезки, которая определяет видимое поле зрения при использовании цифрового масштабирования и прямоугольник активного массива)