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

Posted

技术标签:

【中文标题】如何在 Tracker 事件中获取 android facedetector 的当前帧(作为位图)?【英文标题】:How to get the current frame (as a Bitmap) for android facedetector in a Tracker event? 【发布时间】:2016-10-04 01:04:14 【问题描述】:

我的标准 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.SparseArray<Face> detect(Frame var1) 获得。一旦你掌握了一个 Frame 对象,你就有了 getBitmap() ,这听起来很有希望。不幸的是,该类是最终的,这意味着应该可以使用反射拦截 Frame。 我不确定我得到你的建议。我是对的,您认为我手头有一个框架对象吗?因为这就是我面临的问题。我检测到了一个没有当前帧的人脸对象,我需要与给定人脸对象对应的帧。例如,我在问题中提供的链接底部有一个方法 onUpdate() 。给定这个方法,如何获取该方法的 Face 参数对应的当前 Frame? 我们无法访问帧,除非您将所有方法包装在 FaceDetector 中并拦截检测方法(反射显然无济于事,因为它是最终的)。保存框架并创建一个 getter,然后在适当的时候在其他地方调用它。 我明白了 - 谢谢你的帮助 如果您尝试这样做并且有效,请发布作为答案 【参考方案1】:

您必须创建自己的人脸跟踪器版本,该版本将扩展 google.vision 人脸检测器。在您的 mainActivity 或 FaceTrackerActivity(在 google 跟踪示例中)类中,创建您的 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();

【讨论】:

以上是关于如何在 Tracker 事件中获取 android facedetector 的当前帧(作为位图)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在Android设备中获取设备日历事件列表?

如何在android webview中获取完成youtube视频的事件

如何在android中获取主屏幕小部件列表项的点击事件[重复]

Android Multi-tracker 示例项目运行但未显示任何形式的检测

Android:如何在用户关闭位置设置时获取地理围栏事件?

如何在 Mixpanel 中跟踪匿名事件