关于camera2人脸识别机制的信息不足。我使用了Google的Camera2样本:android-Camera2Basic
我将人脸识别模式设置为FULL。
mPreviewRequestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE,
CameraMetadata.STATISTICS_FACE_DETECT_MODE_FULL);
我也查了一下
STATISTICS_INFO_MAX_FACE_COUNT
和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);
输出:maxCount:5,模式:[0,2]
我的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);
}
输出:面:0,模式:2
public static final int STATISTICS_FACE_DETECT_MODE_FULL = 2;
面部长度始终为0.看起来它不能正确识别面部或我错过了什么。
我知道与FaceDetector的方法。我只是想检查它是如何工作的新camera2 Face。
我的尝试是在Android 5.0(API 21)。更新到5.1(API 22)后,它开始工作而无需更改代码。
https://github.com/rajktariya/Android-Camera2-Front-with-Face-Detection
发现这个工作样本用于前置摄像头和人脸检测
我发现只有在STATE_PREVIEW的情况下,你才能处理结果以显示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;
}
...
至
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;
}
请试试看它是否有效。
我认为您的手机无法正常使用Google Face检测功能。你确定它使用HAL3并且可以使用API2吗?
例如,在我的代码中我使用面部检测没有任何问题,如下所示:
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...
}
这是checkFaces方法:
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);
}
}
}
我的自定义Face类:
// 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;
}
}
最后使用这种方法你可以正确地绘制面部(你可以使用默认的android面,但矩形在4:3或16:9尺寸或旋转手机时效果不佳:
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 < faces.length; i++) {
RectF mappedRect = new RectF();
Log.i(TAG, "[computeFacesFromCameraCoordinates] toStandardAspectRatio: " + toStandardAspectRatio);
Log.i(TAG, "[computeFacesFromCameraCoordinates] preview rect: " + mPreviewRect);
Log.i(TAG, "[computeFacesFromCameraCoordinates] raw rect: " + faces[i].getBounds());
mCameraToPreviewMatrix.mapRect(mappedRect, CameraUtil.rectToRectF(faces[i].getBounds()));
Log.i(TAG, "[computeFacesFromCameraCoordinates] mapped rect: " + mappedRect);
Rect auxRect = new Rect(CameraUtil.rectFToRect(mappedRect));
Log.i(TAG, "[computeFacesFromCameraCoordinates] aux rect: " + auxRect);
int cameraSensorOrientation = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
Log.i(TAG, "[computeFacesFromCameraCoordinates] cameraSensorOrientation: " + cameraSensorOrientation);
switch (cameraSensorOrientation) {
case 90:
mappedRect.top = auxRect.left;
mappedRect.bottom = auxRect.right;
mappedRect.left = (mPreviewRect.right - auxRect.bottom);
mappedRect.right = (mPreviewRect.right - auxRect.top);
break;
case 180:
mappedRect.top = (mPreviewRect.bottom - auxRect.bottom) * toStandardAspectRatio;
mappedRect.bottom = (mPreviewRect.bottom - auxRect.top) * toStandardAspectRatio;
mappedRect.left = (mPreviewRect.right - auxRect.right) * toStandardAspectRatio;
mappedRect.right = (mPreviewRect.right - auxRect.left) * toStandardAspectRatio;
break;
case 270:
mappedRect.top = (mPreviewRect.bottom - auxRect.right) * toStandardAspectRatio;
mappedRect.bottom = (mPreviewRect.bottom - auxRect.left) * toStandardAspectRatio;
mappedRect.left = auxRect.top;
mappedRect.right = auxRect.bottom;
break;
}
Log.i(TAG, "[computeFacesFromCameraCoordinates] rotated by camera driver orientation rect without scale: "
+ mappedRect + ", with score: " + faces[i].getScore());
float topOffset = mappedRect.top;
float leftOffset = mappedRect.left;
mappedRect.top = mappedRect.top * toStandardAspectRatio;
mappedRect.bottom = mappedRect.bottom * toStandardAspectRatio;
mappedRect.left = mappedRect.left * toStandardAspectRatio;
mappedRect.right = mappedRect.right * toStandardAspectRatio;
Log.i(TAG, "[computeFacesFromCameraCoordinates] rotated by camera driver orientation rect with scale: "
+ mappedRect + ", with score: " + faces[i].getScore());
topOffset = mappedRect.top - topOffset;
leftOffset = mappedRect.left - leftOffset;
mappedRect.top -= topOffset /*- (mMirror ? mPreviewRect.height() : 0)*/;
mappedRect.bottom -= topOffset /* - (mMirror ? mPreviewRect.height() : 0)*/;
mappedRect.left -= leftOffset;
mappedRect.right -= leftOffset;
Log.i(TAG, "[computeFacesFromCameraCoordinates] rotated by camera driver orientation rect with offset: "
+ mappedRect + " topOffset " + topOffset + " leftOffset " + leftOffset);
// set the new values to the mapping array to get rendered
mappedFacesList[i] = new CameraFaceUtil.CustomFace(CameraUtil.rectFToRect(mappedRect), faces[i].getScore());
}
return mappedFacesList;
}
我正在做的是根据屏幕比例和大小绘制面部。随意询问您是否需要有关camera2API的其他信息。