如何使用Camera2 FaceDection,Faces.getBound()获得真实值



我正在在Android中编写一些代码,我必须使用Camera2 API进行面部检测。我的代码基于android-camera2-api-face-recon样本,我不知道为什么,但是当我使用 face.getBound()时,它返回的值不在视图中。

这是针对Android Studio,在Java中,该代码应该在头部绘制一个矩形,并且它识别出头部,但是矩形在任何地方都绘制在任何地方,并且不遵循头部。

private void process(CaptureResult result) {
    Integer mode = result.get(CaptureResult.STATISTICS_FACE_DETECT_MODE);
    Face[] faces = result.get(CaptureResult.STATISTICS_FACES);
    mFaceDetectionMatrix=new Matrix();
    if (faces != null && mode != null) {
        if (faces.length ==1) {
            for(int i = 0; i < faces.length; i++) {
                if (faces[i].getScore() > 50) {
                    int left = faces[i].getBounds().left;
                    int top = faces[i].getBounds().top;
                    int right = faces[i].getBounds().right;
                    int bottom = faces[i].getBounds().bottom;
                    float points[] = {(float)bottom, (float)right, (float)top, (float)left};
                    Log.i("Test", "faces : " + faces.length + " , mode : " + mode + " left " + left + " top " + top + " right " + right);
                    Rect uRect = new Rect(left, top, right, bottom); //The function I'm supposed to use
                    //Rect uRect = new Rect(+2000-bottom, 1500-left, +1500-top, 3500-right) the function I'm using in order to fix this problem

当头部向下移动或向上移动时,矩形向左或向右移动,反之亦然。如您所见,我正在尝试一些无法使用的事情来修复它,我必须完全改变主菜。
我想正确解决此问题并理解为什么它不起作用,如果我不能,我想更改以矩形为单位的常数,以便能够在所有设备上使用此代码。
你有一些想法吗?

为了控制传感器的方向,我使用此代码:


 int orientationOffset;
                orientationOffset = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
                Rect activeArraySizeRect = characteristics.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);
                //mFaceDetectionMatrix.postRotate(orientation);
                if (mSwappedDimensions) {
                    mFaceDetectionMatrix.postTranslate(mPreviewSize.getHeight(), mPreviewSize.getWidth());
                } else {
                    // TODO - ...
                }

就像...矩形在景观中,肖像中的头部。

谢谢

[编辑]我找到了修复它的方法!在oflayview类中,在OnDraw中,我添加此:


 canvas.scale(-1, 1, getWidth()/2, getHeight()/2);

我在fragment_camera2_basic.xml中修改了overlayview,添加一个android:rotation =" 90"现在,矩形移动了。

它已经改变了问题,根据二手设备,矩形没有相同的位置。

我已经修改了顶部,左,右和底部:

int left = (int)((float)(faces[i].getBounds().left)/MGpix.getWidth()*mTextureView.getHeight());
                            int top = (int)((float)(faces[i].getBounds().top)/MGpix.getHeight()*mTextureView.getWidth());
                            int right = (int)((float)(faces[i].getBounds().right)/MGpix.getWidth()*mTextureView.getHeight());
                            int bottom =(int)((float)(faces[i].getBounds().bottom)/MGpix.getHeight()*mTextureView.getWidth());

mgpix等于特征。

现在它快要工作了,但是矩形是,取决于设备,无论是头部还是旁边,但它都按照头部遵循。例如,在荣誉5C上,矩形放置得很好,但是有了Huawey P9 Lite,矩形的向上弯道就在鼻子上。 为了解决它有什么想法吗?

您如何从传感器活动数组坐标系统中的面矩形坐标转换为预览视图的坐标?

您需要考虑传感器的方向以及应用程序相对于设备的本机取向的当前方向。

编辑:您当前对S1/S2的计算对于肖像设备上的景观传感器(描述大多数手机(的计算也不正确,即使您的应用程序被锁定到肖像方向也是如此。

如果您的应用程序和传感器的方向不匹配,则需要在S1/S2计算之前交换预览或ActiveArray的高度。

旋转之后,只会互相交换两个错误计算的坐标。

最健壮的选项是获得当前显示的方向(与设备的本机取向相对(,并使用它和传感器方向来确定传感器和应用程序的相对方向,以决定何时交换坐标。类似:

int displayRotation = WindowManager.getDefaultDisplay().getRotation();
boolean displayIsRotated = (displayRotation == Surface#ROTATION_90) ||
    (displayRotation == Surface#ROTATION_270)
int cameraOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION)
boolean cameraIsRotated = (cameraRotation == 90) || (cameraRotation == 270)
boolean flipAxes = displayIsRotated ^ cameraIsRotated;
if (flipAxes) {
   float s1 = mPreviewSize.getWidth()  / (float)activeArraySizeRect.height();
   float s2 = mPreviewSize.getHeight() / (float)activeArraySizeRect.width();
} else {
   float s1 = mPreviewSize.getWidth()  / (float)activeArraySizeRect.width();
   float s2 = mPreviewSize.getHeight() / (float)activeArraySizeRect.height();
}

最新更新