问题
I'm trying to use the face detector in the camera2 api. I set the preview builder to use the face detector:
previewBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,
CameraMetadata.STATISTICS_FACE_DETECT_MODE_FULL);
CR = previewBuilder.build();
CS = session;
CS.setRepeatingRequest(CR, CScallback, null);
But I don't understand where the code hits when it detects a face? Does it return a face in the CameraCaptureSession.CaptureCallback? Where does it send back the info about the detected faces?
回答1:
I just figured out using the Camera2 Basic sample that it is relatively easy to get the Face array from Camera2 preview after you set the capture session correctly.
In the setUpCameraOutputs method of the Camera2 Basic sample add the following check:
int[] FD =characteristics.get(CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);
int maxFD=characteristics.get(CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT);
if (FD.length>0) {
List<Integer> fdList = new ArrayList<>();
for (int FaceD : FD
) {
fdList.add(FaceD);
Log.d(TAG, "setUpCameraOutputs: FD type:" + Integer.toString(FaceD));
}
Log.d(TAG, "setUpCameraOutputs: FD count" + Integer.toString(maxFD));
if (maxFD > 0) {
mFaceDetectSupported = true;
mFaceDetectMode = Collections.max(fdList);
}
}
Then in the createCameraPreviewSession() method that creates the capture session add the following call for face detection method:
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (null == mCameraDevice) {
return;
}
// When the session is ready, we start displaying the preview. ...
// Flash is automatically enabled when necessary.
setAutoFlash(mPreviewRequestBuilder);
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>HERE>>>>>>>>>>>>>>>>
//Face detection setup
setFaceDetect(mPreviewRequestBuilder,mFaceDetectMode);...
Where the setFaceDetect(mPreviewRequestBuilder,mFaceDetectMode); code can be like this:
private void setFaceDetect(CaptureRequest.Builder requestBuilder , int faceDetectMode){
if (mFaceDetectSupported){
requestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,faceDetectMode);
}
}
Face detection can be done in CameraCaptureSession.CaptureCallback by adding just few lines of code:
private CameraCaptureSession.CaptureCallback mCaptureCallback
= new CameraCaptureSession.CaptureCallback() {
private void process(CaptureResult result) {
switch (mState) {
case STATE_PREVIEW: {
// We have nothing to do when the camera preview is working normally.
//But we can for example detect faces
Face face[]=result.get(CaptureResult.STATISTICS_FACES);
if (face.length>0 ){
Log.d(TAG, "face detected " + Integer.toString(face.length));
takePicture();
}
break;
}
I tested this change of the code and it works (I capture selfie once my face is detected... You can look into more options of the Face class here: Face
回答2:
http://developer.android.com/reference/android/hardware/camera2/CaptureResult.html
So it seems that the face data is only available after the picture is taken or in other words not while the preview is happening. When you set face detect mode on for the preview builder that means the captureresult will get the metadata when the picture is taken. I will try to find a way to do it while in preview, I think I can take snapshots of the preview and run a face detection using a background thread. I will open a separate question for that scenario.
来源:https://stackoverflow.com/questions/33748760/camera2-face-detection-call-back