2016-06-03 13 views
6

Ich habe den Standard com.google.android.gms.vision.Tracker example erfolgreich auf meinem Android-Gerät ausgeführt und jetzt muss ich das Bild nachbearbeiten, um die Iris des aktuellen Gesichtes zu finden, die in den Ereignismethoden der angezeigt wurde Tracker.Wie bekomme ich den aktuellen Frame (als Bitmap) für den Android-Facedetector in einem Tracker-Event?

Also, wie bekomme ich den Bitmap-Rahmen, der genau der com.google.android.gms.vision.face.Face entspricht, die ich in den Tracker-Events erhalten habe? Dies bedeutet auch, dass die endgültige Bitmap mit der Webcam-Auflösung und nicht mit der Bildschirmauflösung übereinstimmen sollte.

Eine schlechte Alternative ist, alle paar ms auf meiner CameraSource takePicture aufzurufen und dieses Bild mit dem FaceDetector separat zu bearbeiten. Obwohl dies funktioniert, habe ich das Problem, dass der Video-Stream während des Aufnehmens einfriert und ich eine Menge von GC_FOR_ALLOC-Nachrichten wegen des einzelnen bmp-Gesichtsdetektor-Speicherabfalls bekomme.

+1

Was Sie suchen, scheint bei 'FaceDetector.SparseArray Detect (Frame var1)' verfügbar sein. Sobald Sie ein Frame-Objekt halten, haben Sie getBitmap(), was sehr vielversprechend klingt. Leider ist diese Klasse endgültig, was bedeutet, dass das Abfangen von Frames durch Reflexion möglich sein sollte. – Fabio

+0

Ich bin mir nicht sicher, ob ich bekomme, was Sie vorschlagen. Habe ich recht, dass Sie davon ausgehen, dass ich ein Frame-Objekt zur Hand habe? Denn das ist das Problem, vor dem ich stehe. Ich habe ein erkanntes Gesichtsobjekt ohne den aktuellen Rahmen und ich brauche den Rahmen, der einem bestimmten Gesichtsobjekt entspricht. Zum Beispiel hat der Link in meiner Frage eine Methode onUpdate() am unteren Rand. Wie kann ich mit dieser Methode den aktuellen Frame erhalten, der dem Face-Argument der Methode entspricht? –

+0

Wir haben keinen Zugriff auf einen Frame, es sei denn, Sie haben alle Methoden in FaceDetector und die Intercept Detect-Methode eingeschlossen (Reflektion hilft anscheinend nicht, weil sie endgültig ist). Speichern Sie den Frame und erstellen Sie einen Getter, und rufen Sie ihn an anderen Stellen im richtigen Moment auf. – Fabio

Antwort

2

Sie müssen Ihre eigene Version von Face Tracker erstellen, die den google.vision Face Detector erweitert. In Ihrem mainActivity oder FaceTrackerActivity (in google Tracking-Probe) Klasse erstellen Sie Ihre Version von FaceDetector Klasse wie folgt:

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); 
    } 
} 

Dann müssen Sie Ihre eigene FaceDetector mit CameraSource verbinden, indem Sie Ihre CreateCameraSource Methode wie folgt zu ändern:

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(); 
}