Firebase ML Kit的人脸检测不准确

时间:2019-03-11 04:34:48

标签: android firebase machine-learning

我正在尝试使用Firebase ml套件+来自({'com.otaliastudios:cameraview:2.0.0-beta04')的cameraview +我创建的自定义叠加层视图来制作过滤器应用。问题是它非常不准确。它确实在相机视图中绘制了一个框,但不在我的脸部周围。这是我的代码:

private void startFaceProcessor() {
    FirebaseVisionFaceDetectorOptions options =
            new FirebaseVisionFaceDetectorOptions.Builder().setPerformanceMode(FirebaseVisionFaceDetectorOptions.ACCURATE)
            .setLandmarkMode(FirebaseVisionFaceDetectorOptions.ALL_LANDMARKS).build();
    FirebaseVisionFaceDetector detector = FirebaseVision.getInstance()
            .getVisionFaceDetector(options);
    cameraView.addFrameProcessor(new FrameProcessor() {
        @Override
        public void process(@NonNull Frame frame) {
            int rotation = frame.getRotation() / 90;
            FirebaseVisionImageMetadata metadata = new FirebaseVisionImageMetadata.Builder()
                    .setWidth(frame.getSize().getWidth())   // 480x360 is typically sufficient for
                    .setHeight(frame.getSize().getHeight())  // image recognition
                    .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21)
                    .setRotation(rotation)
                    .build();
            FirebaseVisionImage image = FirebaseVisionImage.fromByteArray(frame.getData(), metadata);
            detector.detectInImage(image).addOnSuccessListener(new OnSuccessListener<List<FirebaseVisionFace>>() {
                @Override
                public void onSuccess(List<FirebaseVisionFace> firebaseVisionFaces) {
                    if (firebaseVisionFaces.size() > 0) {
                        FirebaseVisionFace face = firebaseVisionFaces.get(0);
                        Rect faceRect = face.getBoundingBox();
                        overlayView.setRect(faceRect);
                    } 
                }
            }).addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
        }
    });
}

OverviewView绘制框

public class OverlayView extends View {

    private Paint mBoxPaint;
    private Rect rect;
    private Frame frame;
    private FirebaseVisionFace face;

    private float widthScaleFactor = 1f;
    private float heightScaleFactor = 1f;

    public OverlayView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mBoxPaint = new Paint();
        mBoxPaint.setStrokeWidth(2);
        mBoxPaint.setColor(Color.WHITE);
        mBoxPaint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(rect != null) {
            canvas.drawRect(rect, mBoxPaint);
        }

        postInvalidate();
    }

    public void setFrame(Frame frame) {
        this.frame = frame;
    }

    public void setRect(Rect rect) {
        this.rect = rect;
        //this.face = face;
    }

    private float translateX(float x) {
        return frame.getSize().getWidth() - scaleX(x);
    }

    private float translateY(float y) {
        return scaleY(y);
    }

    private float scaleX(float x) {
        return x * widthScaleFactor;
    }

    private float scaleY(float y) {
        return y * heightScaleFactor;
    }

}

XML文件:

 <FrameLayout
        android:id="@+id/frameLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1.5">

        <com.otaliastudios.cameraview.CameraView
            android:id="@+id/camera_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:keepScreenOn="true"
            app:cameraFacing="front" />

        <com.gbcapps.camerafilter.OverlayView
            android:id="@+id/overlay_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </FrameLayout>

从昨天开始我一直在尝试尝试,但是我无法使其正常工作。

1 个答案:

答案 0 :(得分:0)

我不知道这是否有用,但我设法从捕获的帧中裁剪了检测到的面部的位图。当我在图像视图上显示faceBmp时,它会正确裁剪框架。

detectedFace = face.getBoundingBox();
Bitmap faceBmp = Bitmap.createBitmap(frameBmp, detectedFace.left, detectedFace.top, detectedFace.width(), detectedFace.height());

从示例快速入门应用中:

float x = translateX(face.getBoundingBox().centerX());
float y = translateY(face.getBoundingBox().centerY());

float xOffset = scaleX(face.getBoundingBox().width() / 2.0f);
float yOffset = scaleY(face.getBoundingBox().height() / 2.0f);
float left = x - xOffset;
float top = y - yOffset;
float right = x + xOffset;
float bottom = y + yOffset;

canvas.drawRect(left, top, right, bottom, boxPaint);