2016-06-03 10 views
6

У меня есть стандартный com.google.android.gms.vision.Tracker example успешно работает на моем устройстве Android, и теперь мне нужно обработать изображение, чтобы найти радужную оболочку текущего лица, которое было уведомлено в методах события Tracker.Как получить текущий фрейм (как растровое изображение) для андеграунда-андеграунда в событии Tracker?

Итак, как мне получить растровое изображение, которое соответствует именно com.google.android.gms.vision.face.Face, полученному в событиях Tracker? Это также означает, что окончательное растровое изображение должно соответствовать разрешению веб-камеры, а не разрешению экрана.

Одним из плохих альтернативных решений является вызов takePicture каждые несколько мс на моем CameraSource и обработка этого изображения отдельно с помощью FaceDetector. Хотя это работает, я столкнулся с проблемой, что поток видео зависает во время takepicture, и я получаю много сообщений GC_FOR_ALLOC из-за одиночной потери памяти bmp frontetector.

+1

То, что вы ищете, похоже, доступно в 'FaceDetector.SparseArray detect (Frame var1)'. Как только вы удержите объект Frame, у вас есть getBitmap(), который звучит очень многообещающе. К сожалению, этот класс является окончательным, что означает, что перехват Frame должен быть возможен с использованием отражения. – Fabio

+0

Я не уверен, что получаю то, что вы предлагаете. Правильно ли, что вы предполагаете, что у меня есть объект Frame? Потому что это проблема, с которой я сталкиваюсь. У меня есть обнаруженный объект лица без текущего кадра, и мне нужен кадр, соответствующий данному объекту Face. Например, ссылка i, указанная в моем вопросе, имеет метод onUpdate() внизу. Учитывая этот метод, как я могу получить текущий кадр, соответствующий аргументу Face метода? –

+0

У нас нет доступа к кадру, если вы не обернете все методы в FaceDetector и метод обнаружения перехвата (отражение, по-видимому, не поможет, потому что оно окончательное). Сохраните фрейм и создайте геттер, а затем вызовите его в других местах в нужный момент. – Fabio

ответ

2

Вам необходимо создать собственную версию Face Tracker, которая расширит детектор лица 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); 
    } 
} 

Затем вы должны присоединиться свой собственный FaceDetector с CameraSource путем изменения метода CreateCameraSource следующим образом:

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