android-vision icon indicating copy to clipboard operation
android-vision copied to clipboard

How to face tracking with FaceDetector and Bitmap?

Open wdgk opened this issue 8 years ago • 5 comments
trafficstars

This is a question.

I want to face tracking with FaceDetector like this. https://github.com/googlesamples/android-vision/tree/master/visionSamples/FaceTracker

In this sample, set ByteBuffer to Frame.imageData like this.

 outputFrame = new Frame.Builder()
            .setImageData(mPendingFrameData, mPreviewSize.getWidth(),
                                mPreviewSize.getHeight(), ImageFormat.NV21)
            .setId(mPendingFrameId)
            .setTimestampMillis(mPendingTimeMillis)
            .setRotation(mRotation)
            .build();

But, I set bitmap to Frame like this.

//data is image data as byte.
bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
outputFrame = new Frame.Builder()
            .setBitmap(bitmap)
            .setId(frameId)
            .setTimestampMillis(time)
            .build();

And use FaceDetector like this.

    FaceDetector fd = new FaceDetector.Builder(this.context)
                        .setTrackingEnabled(true)
                        .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
                        .build();
        
        fd.setProcessor(new MultiProcessor.Builder<Face>(new GraphicFaceTrackerFactory()).build());
        fd.receiveFrame(frame);

     private class GraphicFaceTrackerFactory implements MultiProcessor.Factory<Face> {
        @Override
        public Tracker<Face> create(Face face) {
            return new GraphicFaceTracker();
        }
     }

private class GraphicFaceTracker extends Tracker<Face> {

    GraphicFaceTracker() {}

    @Override
    public void onNewItem(int faceId, Face face) {
        Log.d(Constants.LOG_TAG, "onNewItem. Face Id => "+faceId);//here
    }

    @Override
    public void onUpdate(FaceDetector.Detections<Face> detectionResults, Face face) {
    }

    @Override
    public void onMissing(FaceDetector.Detections<Face> detectionResults) {
        
    }

    @Override
    public void onDone() {

    }
}

I expected that same faceId will be entered in onNewItem() as long as same face remain in the frame, but entered id was different every time. If I use bitmap instead of the bytebuffer, does it not works properly?

【Additional info】 ・In my application, it takes still pictures continuously at 7.5fps.

wdgk avatar Apr 12 '17 02:04 wdgk

The faceId does not represent the results of facial recognition, and the API does not support facial recognition (i.e., identifying a specific individual).

The API does support continuous tracking of a face, based upon the position and motion of the face over time. When tracking a face in video, if the motion was relatively steady then the ID will be the same. But if the face is lost and a new face is detected (even if it was the same face as before), it will issue a new faceId to represent the start of a new face tracking session.

pm0733464 avatar Apr 12 '17 14:04 pm0733464

Thank you for your reply.

What I care about is that in the sample application we can track the face, but it is not possible in case of my own application.

I think that the difference between the sample application and my application is whether you are using bytebuffer or using bitmap.

Do you know why it is possible to face tracking on sample application and not possible to face tracking on my application?

wdgk avatar Apr 12 '17 16:04 wdgk

Not sure. The choice of bytebuffer or bitmap shouldn't affect tracking.

If you're only looking to track one face -- the largest face visible -- you probably want to use LargestFaceFocusingProcessor instead of MultiProcessor. See this example:

https://github.com/googlesamples/android-vision/blob/master/visionSamples/googly-eyes/app/src/main/java/com/google/android/gms/samples/vision/face/googlyeyes/GooglyEyesActivity.java#L302

pm0733464 avatar Apr 12 '17 17:04 pm0733464

umm... I want to track multi face finally but I tried LargestFaceFocusingProcessor instead of MultiProcessor.

FaceDetector fd = new FaceDetector.Builder(this.context)
                .setTrackingEnabled(true)
                .setClassificationType(FaceDetector.ALL_CLASSIFICATIONS)
                .build();

fd.setProcessor(new LargestFaceFocusingProcessor.Builder(fd, new GraphicFaceTracker()).build());

As a result, there was no difference with LargestFaceFocusingProcessor and MultiProcessor.

FaceId coming to onNewItem () is a different Id every time.

wdgk avatar Apr 14 '17 08:04 wdgk

Hi, did you find the solution?

Kostanos avatar Apr 09 '19 14:04 Kostanos