2017-04-12 5 views
0

J'essaie de détection de visage et l'ajout de masque (superposition graphique) en utilisant google vision api, le problème est que je ne pouvais pas obtenir l'appareil photo après la détection et l'ajout de masque. J'ai essayé cette solution de github, https://github.com/googlesamples/android-vision/issues/24, basé sur ce problème, j'ai ajouté une classe de détecteur personnalisé, Mobile Vision API - concatenate new detector object to continue frame processing. et ajouté ceci sur la classe mydetector How to create Bitmap from grayscaled byte buffer image?.Impossible d'obtenir la sortie de caméra, la détection de visage android

MyDetectorClass

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

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

    public SparseArray<Face> detect(Frame frame) { 
     // *** add your custom frame processing code here 
     ByteBuffer byteBuffer = frame.getGrayscaleImageData(); 
     byte[] bytes = byteBuffer.array(); 
     int w = frame.getMetadata().getWidth(); 
     int h = frame.getMetadata().getHeight(); 
     YuvImage yuvimage=new YuvImage(bytes, ImageFormat.NV21, w, h, null); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     yuvimage.compressToJpeg(new Rect(0, 0, w, h), 100, baos); // Where 100 is the quality of the generated jpeg 
     byte[] jpegArray = baos.toByteArray(); 
     Bitmap bitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.length); 
     Log.e("got bitmap","bitmap val " + bitmap); 
     return mDelegate.detect(frame); 
    } 

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

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

traitement de trame

public SparseArray<Face> detect(Frame frame) 
{ 
    // *** add your custom frame processing code here 
    ByteBuffer byteBuffer = frame.getGrayscaleImageData(); 
    byte[] bytes = byteBuffer.array(); 
    int w = frame.getMetadata().getWidth(); 
    int h = frame.getMetadata().getHeight(); 
    YuvImage yuvimage=new YuvImage(bytes, ImageFormat.NV21, w, h, null); 
    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    yuvimage.compressToJpeg(new Rect(0, 0, w, h), 100, baos); // Where 100 is the quality of the generated jpeg 
    byte[] jpegArray = baos.toByteArray(); 
    Bitmap bitmap = BitmapFactory.decodeByteArray(jpegArray, 0, jpegArray.length); 
    Log.e("got bitmap","bitmap val " + bitmap); 
    return mDelegate.detect(frame); 
} 

Je reçois une image bitmap pivotée, qui est sans masque (superposition graphique) j'ai ajouté .Comment puis-je obtenir la sortie de la caméra avec un masque .

Merci d'avance.

Répondre

1

La réponse simple est: Vous ne pouvez pas.

Pourquoi? Cadres de sortie de caméra Android dans NV21 ByteBuffer. Et vous devez générer vos masques en fonction des points de repère dans une image Bitmap séparée, puis les joindre. Désolé, mais c'est comme ça que fonctionne l'API Android Camera. Rien ne peut être fait. Vous devez le faire manuellement.

En outre, je ne voudrais pas obtenir l'aperçu de la caméra puis le convertir en YuvImage puis en Bitmap. Ce processus consomme un lot de ressources et fait l'aperçu très très lent. Au lieu de cela, j'utiliser cette méthode qui sera beaucoup plus rapide et tourne votre interne aperçu afin de ne pas perdre le temps de le faire:

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

Tout le code se trouve dans CameraSource.java