使用后置摄像头的人脸检测无法使用 camera2 API 正常工作
Posted
技术标签:
【中文标题】使用后置摄像头的人脸检测无法使用 camera2 API 正常工作【英文标题】:Face detection with back camera is not working properly using camera2 API 【发布时间】:2020-06-07 07:29:39 【问题描述】:我正在使用 camre2 api 进行人脸检测。这适用于前置摄像头,但不适用于后置摄像头。 谁能证明后置摄像头的人脸检测矩阵
前置摄像头人脸检测矩阵为
if (facing == CameraCharacteristics.LENS_FACING_FRONT)
StreamConfigurationMap map = mCameraCharacteristics.get(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
if (map == null)
continue;
// For still image captures, we use the largest available size.
Size largest = Collections.max(
Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)),
new CompareSizesByArea());
/*maxImages = mCameraCharacteristics.get(
CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT);*/
mImageReader = ImageReader.newInstance(largest.getWidth(), largest.getHeight(),
ImageFormat.JPEG, 1);
mImageReader.setOnImageAvailableListener(
mOnImageAvailableListener, mBackgroundHandler);
// Find out if we need to swap dimension to get the preview size relative to sensor
// coordinate.
int displayRotation = this.getWindowManager().getDefaultDisplay().getRotation();
//noinspection ConstantConditions
mSensorOrientation = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
mSwappedDimensions = false;
switch (displayRotation)
case Surface.ROTATION_0:
case Surface.ROTATION_180:
if (mSensorOrientation == 90 || mSensorOrientation == 270)
mSwappedDimensions = true;
break;
case Surface.ROTATION_90:
case Surface.ROTATION_270:
if (mSensorOrientation == 0 || mSensorOrientation == 180)
mSwappedDimensions = true;
break;
default:
Log.e(TAG, "Display rotation is invalid: " + displayRotation);
Point displaySize = new Point();
this.getWindowManager().getDefaultDisplay().getSize(displaySize);
int rotatedPreviewWidth = width;
int rotatedPreviewHeight = height;
int maxPreviewWidth = displaySize.x;
int maxPreviewHeight = displaySize.y;
if (mSwappedDimensions)
rotatedPreviewWidth = height;
rotatedPreviewHeight = width;
maxPreviewWidth = displaySize.y;
maxPreviewHeight = displaySize.x;
if (maxPreviewWidth > MAX_PREVIEW_WIDTH)
maxPreviewWidth = MAX_PREVIEW_WIDTH;
if (maxPreviewHeight > MAX_PREVIEW_HEIGHT)
maxPreviewHeight = MAX_PREVIEW_HEIGHT;
// Danger, W.R.! Attempting to use too large a preview size could exceed the camera
// bus' bandwidth limitation, resulting in gorgeous previews but the storage of
// garbage capture data.
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
maxPreviewHeight, largest);
// We fit the aspect ratio of TextureView to the size of preview we picked.
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE)
textureView.setAspectRatio(
mPreviewSize.getWidth(), mPreviewSize.getHeight());
else
textureView.setAspectRatio(
mPreviewSize.getHeight(), mPreviewSize.getWidth());
// Check if the flash is supported.
Boolean available = mCameraCharacteristics.get(CameraCharacteristics.FLASH_INFO_AVAILABLE);
FlashSupported = available == null ? false : available;
this.cameraId = "0";
int orientationOffset = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
Rect activeArraySizeRect = mCameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);
// Face Detection Matrix
mFaceDetectionMatrix = new Matrix();
// TODO - I guess that is not enough if we have a landscape layout too...
mFaceDetectionMatrix.setRotate(orientationOffset);
Log.i("Test", "activeArraySizeRect1: (" + activeArraySizeRect + ") -> " + activeArraySizeRect.width() + ", " + activeArraySizeRect.height());
Log.i("Test", "activeArraySizeRect2: " + mPreviewSize.getWidth() + ", " + mPreviewSize.getHeight());
float s1 = mPreviewSize.getWidth() / (float)activeArraySizeRect.width();
float s2 = mPreviewSize.getHeight() / (float)activeArraySizeRect.height();
//float s1 = mOverlayView.getWidth();
//float s2 = mOverlayView.getHeight();
boolean mirror = true; // we always use front face camera
boolean weAreinPortrait = true;
mFaceDetectionMatrix.postScale(mirror ? -s1 : s1, s2);
if (mSwappedDimensions)
mFaceDetectionMatrix.postTranslate(mPreviewSize.getHeight(), mPreviewSize.getWidth());
else
// TODO - ...
// here i am using same code just making mirror
//value false.
这适用于前置摄像头。谁能有后置摄像头人脸检测矩阵的解决方案。
【问题讨论】:
任何人都可以解决这个问题 【参考方案1】:在 if (face == CameraCharacteristics.LENS_FACING_FRONT) 中对 else 条件使用 boolean mirror = false
【讨论】:
以上是关于使用后置摄像头的人脸检测无法使用 camera2 API 正常工作的主要内容,如果未能解决你的问题,请参考以下文章
使用 CameraX 时,前置摄像头的 Facebase MLKit 人脸检测失败