android - 如何在 Tracker 事件中获取 android facedetector 的当前帧(作为位图)?

标签 android vision

我有标准的 com.google.android.gms.vision.Tracker example在我的 android 设备上成功运行,现在我需要对图像进行后处理以找到已在 Tracker 的事件方法中通知的当前面部的虹膜。

那么,我如何获得与我在 Tracker 事件中收到的 com.google.android.gms.vision.face.Face 完全匹配的位图帧? 这也意味着最终位图应匹配网络摄像头分辨率,而不是屏幕分辨率。

一个不好的替代解决方案是每隔几毫秒在我的 CameraSource 上调用 takePicture 并使用 FaceDetector 单独处理这张照片。虽然这有效,但我有视频流在拍照期间卡住的问题,并且我收到大量 GC_FOR_ALLOC 消息,导致单个 bmp facedetector 内存浪费。

最佳答案

您必须创建自己的人脸跟踪器版本,它将扩展 google.vision 人脸检测器。在您的 mainActivity 或 FaceTrackerActivity(在谷歌跟踪示例中)类中创建您的 FaceDetector 类版本,如下所示:

class MyFaceDetector extends Detector<Face> {
    private Detector<Face> mDelegate;

    MyFaceDetector(Detector<Face> delegate) {
        mDelegate = delegate;
    }

    public SparseArray<Face> detect(Frame frame) {
        YuvImage yuvImage = new YuvImage(frame.getGrayscaleImageData().array(), ImageFormat.NV21, frame.getMetadata().getWidth(), frame.getMetadata().getHeight(), null);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, frame.getMetadata().getWidth(), frame.getMetadata().getHeight()), 100, byteArrayOutputStream);
        byte[] jpegArray = byteArrayOutputStream.toByteArray();
        Bitmap TempBitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.length);

        //TempBitmap is a Bitmap version of a frame which is currently captured by your CameraSource in real-time
        //So you can process this TempBitmap in your own purposes adding extra code here

        return mDelegate.detect(frame);
    }

    public boolean isOperational() {
        return mDelegate.isOperational();
    }

    public boolean setFocus(int id) {
        return mDelegate.setFocus(id);
    }
}

然后您必须通过修改您的 CreateCameraSource 方法,将您自己的 FaceDetector 与 CameraSource 结合起来,如下所示:

private void createCameraSource() {

    Context context = getApplicationContext();

    // You can use your own settings for your detector
    FaceDetector detector = new FaceDetector.Builder(context)
            .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
            .setProminentFaceOnly(true)
            .build();

    // This is how you merge myFaceDetector and google.vision detector
    MyFaceDetector myFaceDetector = new MyFaceDetector(detector);

    // You can use your own processor
    myFaceDetector.setProcessor(
            new MultiProcessor.Builder<>(new GraphicFaceTrackerFactory())
                    .build());

    if (!myFaceDetector.isOperational()) {
        Log.w(TAG, "Face detector dependencies are not yet available.");
    }

    // You can use your own settings for CameraSource
    mCameraSource = new CameraSource.Builder(context, myFaceDetector)
            .setRequestedPreviewSize(640, 480)
            .setFacing(CameraSource.CAMERA_FACING_FRONT)
            .setRequestedFps(30.0f)
            .build();
}

关于android - 如何在 Tracker 事件中获取 android facedetector 的当前帧(作为位图)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37623264/

相关文章:

ios - 提高 VNDetectHumanBodyPoseRequest 的 body 跟踪性能

opencv - 使用 OpenCV 检测表格

machine-learning - 保存视频中每一帧的边界框坐标

Android编码良好习惯的例子?

java - 如何在 android 的自动完成 TextView 中设置联系人号码?

android - 如何使用 Android XML 定义在末尾定义一个带圆圈的矩形

java - 使用 Intent 在 Activity 之间传递字符串值

java - 如何授权谷歌云视觉API android

android - Android 中的光流

android - 如何调用另一个应用程序android的子 Activity ?