可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
There is not enough info about camera2 face recognition mechanism. I used Camera2 sample from Google: android-Camera2Basic
I set face recognition mode to FULL.
mPreviewRequestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, CameraMetadata.STATISTICS_FACE_DETECT_MODE_FULL);
Also I checked
STATISTICS_INFO_MAX_FACE_COUNT
and STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES
:
int max_count = characteristics.get( CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT); int modes [] = characteristics.get( CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES);
Output: maxCount : 5 , modes : [0, 2]
My CaptureCallback:
private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() { private void process(CaptureResult result) { Integer mode = result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE); Face [] faces = result.get(CaptureResult.STATISTICS_FACES); if(faces != null && mode != null) Log.e("tag", "faces : " + faces.length + " , mode : " + mode ); } @Override public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult) { process(partialResult); } @Override public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) { process(result); }
Output: faces : 0 , mode : 2
public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2;
Faces length is constantly 0. Looks like it doesn't recognise a face properly or I missed something.
I know approach with FaceDetector. I just wanted to check how it works with new camera2 Face.
回答1:
My attempts were on android 5.0(API 21). After update to 5.1(API 22) it started working without code changes.
回答2:
I think your phone is not working good with the Google Face detection. Are you sure that it use HAL3 and can use API2?.
For example, in my code I'm using face detection without any problem like this:
private CameraCaptureSession.CaptureCallback mPhotoCaptureCallback = new CameraCaptureSession.CaptureCallback() { //more code... private void process(CaptureResult result) { switch (mState) { case STATE_PREVIEW: { checkFaces(result.get(CaptureResult.STATISTICS_FACES)); //more code.... break; } //more code... }
Here is the checkFaces method:
private void checkFaces(Face[] faces) { if (faces != null) { CameraUtil.CustomFace[] mMappedCustomFaces; mMappedCustomFaces = computeFacesFromCameraCoordinates(faces); if (faces != null && faces.length > 0) { mHandler.sendEmptyMessage(SHOW_FACES_MSG); mLastTimeRenderingFaces = System.currentTimeMillis(); } } else { if (System.currentTimeMillis() > (mLastTimeRenderingFaces + 100)) { mHandler.sendEmptyMessage(HIDE_FACES_MSG); } } }
my custom Face class:
// public static class CustomFace extends Camera.CustomFace{ public static class CustomFace { private int score = 0; private Rect rect = null; public CustomFace(Rect rect, int score) { this.score = score; this.rect = rect; } public int getScore() { return score; } public Rect getBounds() { return rect; } }
finally with this method you can draw the faces correctly(you can use the default android one, but rectangles doesn't work so good in 4:3 or 16:9 sizes or when you rotate the phone:
public static RectF rectToRectF(Rect r) { return new RectF(r.left, r.top, r.right, r.bottom); } private CameraFaceUtil.CustomFace[] computeFacesFromCameraCoordinates(Face[] faces) { CameraFaceUtil.CustomFace[] mappedFacesList = new CameraFaceUtil.CustomFace[faces.length]; mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE); float toStandardAspectRatio = ((float) mPreviewRect.bottom / (float) mPreviewRect.right) / AutoFitTextureView.RATIO_STANDARD; // for (int i = 0; i
What I'm doing is drawing the faces based in the screen ratio and size. It's a bittle tought code, but I hope that it will help you!
Have a nice day, feel free to ask if you need something else about camera2API.
回答3:
回答4:
I found that only in case STATE_PREVIEW, you can process the result to show faces lenth. Change from
private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() { private void process(CaptureResult result) { Integer mode = result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE); Face[] faces = result.get(CaptureResult.STATISTICS_FACES); if(faces != null && mode != null) { Log.e("tag", "faces : " + faces.length + " , mode : " + mode); } switch (mState) { case STATE_PREVIEW: { // We have nothing to do when the camera preview is working normally. break; } ...
to
private CameraCaptureSession.CaptureCallback mCaptureCallback = new CameraCaptureSession.CaptureCallback() { private void process(CaptureResult result) { switch (mState) { case STATE_PREVIEW: { Face[] faces = result.get(CaptureResult.STATISTICS_FACES); if (faces != null && faces.length > 0) { Log.e("tag", "faces : " + faces.length); } break; }
Please try this to see if it works.