7

我正在尝试制作一个相机应用程序,它使用带有自定义相机实例的谷歌移动视觉 API 来检测人脸,这与谷歌 API 中的“CameraSource”不同,因为我也在处理帧以检测颜色,而使用 Camerasource 我不是允许获取相机帧。

搜索此问题后,我发现的唯一结果是关于将移动视觉与它的 CameraSource 一起使用,而不是与任何自定义 camera1 API 一起使用。我试图覆盖帧处理,然后对输出的图片进行检测,如下所示:

camera.setPreviewCallback(new Camera.PreviewCallback() {
            @Override
            public void onPreviewFrame(byte[] data, Camera camera) {
                Log.d("onPreviewFrame", "" + data.length);
                Camera.Parameters parameters = camera.getParameters();
                int width = parameters.getPreviewSize().width;
                int height = parameters.getPreviewSize().height;
                ByteArrayOutputStream outstr = new ByteArrayOutputStream();
                Rect rect = new Rect(0, 0, width, height);
                YuvImage yuvimage = new YuvImage(data, ImageFormat.NV21, width, height, null);
                yuvimage.compressToJpeg(rect, 20, outstr);
                Bitmap bmp = BitmapFactory.decodeByteArray(outstr.toByteArray(), 0, outstr.size());
                detector = new FaceDetector.Builder(getApplicationContext())
                        .setTrackingEnabled(true)
                        .setClassificationType(FaceDetector.ALL_LANDMARKS)
                        .setMode(FaceDetector.FAST_MODE)
                        .build();

                detector.setProcessor(
                        new MultiProcessor.Builder<>(new GraphicFaceTrackerFactory())
                                .build());

                if (detector.isOperational()) {
                    frame = new Frame.Builder().setBitmap(bmp).build();
                    mFaces = detector.detect(frame);
//                    detector.release();
                }
            }
        });

那么有什么方法可以将移动视觉与我的相机实例链接起来,以便进行帧处理并用它来检测人脸?你可以在这里看到我到目前为止所做的事情: https ://github.com/etman55/FaceDetectionSampleApp

**新更新

在找到 CameraSource 类的开源文件后,我解决了大部分问题,但现在在尝试检测面部时,检测器会正确接收帧但它无法检测到任何内容>>您可以在 github 存储库中看到我的最后一次提交。

4

2 回答 2

4

我可以为您提供一些非常有用的提示。

  • 为相机提供的每一帧构建一个新的 FaceDetector 是非常糟糕的主意,也是不必要的。您只需在相机帧接收器之外启动一次。

  • 无需获取 YUV_420_SP(或 NV21)帧,然后将其转换为 YUV 实例,然后将其转换为 Bitmap,然后使用 Bitmap 创建 Frame.Builder()。如果您查看Frame.Builder 文档,您会发现它允许直接从相机预览中使用 NV21。像这样:

    @override public void onPreviewFrame(byte[] data, Camera camera) {detector.detect(new Frame.Builder().setImageData(ByteBuffer.wrap(data), previewW, previewH, ImageFormat.NV21));}

于 2017-04-11T20:46:01.670 回答
1

和 Kotin 版本:

    import com.google.android.gms.vision.Frame as GoogleVisionFrame
    import io.fotoapparat.preview.Frame as FotoapparatFrame

    fun recogniseFrame(frame: FotoapparatFrame) = detector.detect(buildDetectorFrame(frame))
        .asSequence()
        .firstOrNull { it.displayValue.isNotEmpty() }
        ?.displayValue

    private fun buildDetectorFrame(frame: FotoapparatFrame) =
        GoogleVisionFrame.Builder()
            .setRotation(frame.rotation.toGoogleVisionRotation())
            .setImageData(
                ByteBuffer.wrap(frame.image),
                frame.size.width,
                frame.size.height,
                ImageFormat.NV21
            ).build()
于 2019-02-25T12:35:03.590 回答