2016-05-11 3 views
1

У меня есть код, который позволяет мне обнаружить лица в предварительном просмотре в реальном времени и нарисовать несколько GIF-файлов над их ориентирами, используя библиотеку видения игровых услуг, предоставляемую Google.play-services-vision: Как синхронизировать скорость обнаружения лиц с частотой просмотра камеры?

Он работает достаточно хорошо, когда лицо статично, но когда лицо движется с умеренной скоростью, детектор лица занимает больше времени, чем частота кадров камеры, чтобы обнаружить ориентиры в новом положении лица. Я знаю, что это может иметь какое-то отношение к скорости рисования растровых изображений, но я сделал шаги, чтобы свести к минимуму задержку.

(В основном я получаю жалобы, что ГИФС репозиционирование не „достаточно гладкое“)

EDIT: Я попытаться получить координату кода обнаружения ...

List<Landmark> landmarksList = face.getLandmarks(); 
    for(int i = 0; i < landmarksList.size(); i++) 
    { 
     Landmark current = landmarksList.get(i); 
     //canvas.drawCircle(translateX(current.getPosition().x), translateY(current.getPosition().y), FACE_POSITION_RADIUS, mFacePositionPaint); 
     //canvas.drawCircle(current.getPosition().x, current.getPosition().y, FACE_POSITION_RADIUS, mFacePositionPaint); 
     if(current.getType() == Landmark.LEFT_EYE) 
     { 
      //Log.i("current_landmark", "l_eye"); 
      leftEyeX = translateX(current.getPosition().x); 
      leftEyeY = translateY(current.getPosition().y); 
     } 
     if(current.getType() == Landmark.RIGHT_EYE) 
     { 
      //Log.i("current_landmark", "r_eye"); 
      rightEyeX = translateX(current.getPosition().x); 
      rightEyeY = translateY(current.getPosition().y); 
     } 
     if(current.getType() == Landmark.NOSE_BASE) 
     { 
      //Log.i("current_landmark", "n_base"); 
      noseBaseY = translateY(current.getPosition().y); 
      noseBaseX = translateX(current.getPosition().x); 
     } 
     if(current.getType() == Landmark.BOTTOM_MOUTH) { 
      botMouthY = translateY(current.getPosition().y); 
      botMouthX = translateX(current.getPosition().x); 
      //Log.i("current_landmark", "b_mouth "+translateX(current.getPosition().x)+" "+translateY(current.getPosition().y)); 
     } 
     if(current.getType() == Landmark.LEFT_MOUTH) { 
      leftMouthY = translateY(current.getPosition().y); 
      leftMouthX = translateX(current.getPosition().x); 
      //Log.i("current_landmark", "l_mouth "+translateX(current.getPosition().x)+" "+translateY(current.getPosition().y)); 
     } 
     if(current.getType() == Landmark.RIGHT_MOUTH) { 
      rightMouthY = translateY(current.getPosition().y); 
      rightMouthX = translateX(current.getPosition().x); 
      //Log.i("current_landmark", "l_mouth "+translateX(current.getPosition().x)+" "+translateY(current.getPosition().y)); 
     } 
    } 
    eyeDistance = (float)Math.sqrt(Math.pow((double) Math.abs(rightEyeX - leftEyeX), 2) + Math.pow(Math.abs(rightEyeY - leftEyeY), 2)); 
    eyeCenterX = (rightEyeX + leftEyeX)/2; 
    eyeCenterY = (rightEyeY + leftEyeY)/2; 
    noseToMouthDist = (float)Math.sqrt(Math.pow((double)Math.abs(leftMouthX - noseBaseX), 2) + Math.pow(Math.abs(leftMouthY - noseBaseY), 2)); 

... в отдельный поток в методе View draw, но он просто передает мне ошибку SIGSEGV.

Мои вопросы:

  1. синхронизирует скорость обработки поверхности детектора в с камерой предварительного просмотра фреймрейт, что нужно делать в этом случае, или это наоборот, или это какой-то другой способ?
  2. Как детектор лица обнаруживает лица в кадре предварительного просмотра камеры, следует ли мне отбрасывать кадры, которые предварительные фиды перед завершением FD? Если да, то как я могу это сделать?
  3. Должен ли я использовать setClassificationMode(NO_CLASSIFICATIONS) и setTrackingEnabled(false) в предварительном просмотре камеры, чтобы ускорить обнаружение?
  4. Использует ли библиотека просмотра игровых сервисов OpenCV, и что на самом деле лучше?

EDIT 2:

Я читал одну научно-исследовательскую работу, что, используя OpenCV, обнаружение лица и другие функции, доступные в OpenCV быстрее в Android из-за их более высокой мощности. Мне было интересно, могу ли я использовать это, чтобы ускорить обнаружение лица.

+0

Можете ли вы, ребята, помочь в решении этой проблемы? https://stackoverflow.com/questions/45141098/google-vision-drawing-mask-on-face-with-animations –

ответ

0

Вы не можете гарантировать, что обнаружение лица будет достаточно быстрым, чтобы не было видимой задержки даже при умеренном движении головы. Даже если вам удастся оптимизировать его на своем устройстве разработки, вы наверняка найдете еще одну модель среди тысяч там, которая будет слишком медленной.

Ваш код должен быть устойчивым к таким ситуациям. Вы можете предсказать положение лица на секунду вперед, полагая, что он движется плавно. Если пользователи решают подержать голову или устройство, ни один алгоритм не может помочь.

Если вы используете устаревшиеCamera API, вы должны предварительно выделить буфер и использовать setPreviewCallbackWithBuffer(). Таким образом, вы можете гарантировать, что кадры будут поступать на ваш процессор изображений по одному за раз. Вы также не должны забывать open the Camera on a background thread, так что обратный вызов [onPreviewFrame()] (http://developer.android.com/reference/android/hardware/Camera.PreviewCallback.html#onPreviewFrame(byte[], android.hardware.Camera)), где происходит обработка вашего большого изображения, не будет блокировать поток пользовательского интерфейса.

  • Да, в некоторых случаях обнаружение лица в OpenCV может быть быстрее, но, что более важно, более надежным является детектор лица Google.
  • Да, лучше отключить классификатор, если вам не нравятся улыбки и открытые глаза. Производительность может отличаться.
  • Я считаю, что отключение слежения замедлит детекцию лица Google, но вы должны сделать свои собственные измерения и выбрать лучшую стратегию.
  • Самый значительный выигрыш может быть достигнут поворотом setProminentFaceOnly(), но снова я не могу предсказать фактический эффект этого параметра для вашего устройства.
+0

Я работаю над предсказанием местоположения, о котором вы говорили во втором абзаце. Как это работает? Это так же просто, как получить разницу в координатах X и Y между текущим положением лица и положением лица предыдущей итерации, умножая их на 2 и добавив их к координатам X и Y текущего лица? – Gensoukyou1337

+0

Я бы, вероятно, попробовал параболическую экстраполяцию: дал 3 последних позиции, поместил их на кривой и вычислил x, y для некоторых моментов в будущем, со скоростью 30 FPS –

+0

Могу ли я использовать математическую библиотеку Apache для этого? – Gensoukyou1337

0

Всегда будет какое-то отставание, так как любой детектор лица требует определенного количества времени для запуска. К тому времени, когда вы нарисуете результат, вы, как правило, рисуете его над будущим кадром, в котором лицо может немного переместиться.

Вот некоторые предложения по минимизации запаздывания:

Реализация CameraSource обеспечивается библиотекой зрения Google автоматически обрабатывает сбросив просмотра кадров, когда это необходимо, чтобы он мог следить за самое лучшее, что он может. См. Версию этого кода с открытым исходным кодом, если вы хотите включить подобный подход в свое приложение: https://github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java#L1144

Использование более низкого разрешения предварительного просмотра камеры, например 320x240, ускорит обнаружение лица.

Если вы только отслеживаете одно лицо, использование параметра setProminentFaceOnly() ускорит обнаружение лица. Использование этого и LargestFaceFocusingProcessor также сделает это еще быстрее.

Чтобы использовать LargestFaceFocusingProcessor, установите его как процессор детектора лица. Например:

Tracker<Face> tracker = *your face tracker implementation* 
detector.setProcessor(
    new LargestFaceFocusingProcessor.Builder(detector, tracker).build()); 

Реализация вашего трекера получит обновления для лица только для самой большой поверхности, которую он изначально обнаружил. Кроме того, он будет сигнализировать детектору, что ему нужно отслеживать только это лицо до тех пор, пока оно будет видимым.

Если вам не нужно обнаруживать более мелкие грани, использование setMinFaceSize() больше сделает обнаружение лица быстрее. Быстрее обнаруживать только большие лица, так как не нужно тратить время на поиск небольших лиц.

Вы можете повернуть классификацию, если вам не нужны открытые глаза или улыбка. Однако это только даст вам небольшое преимущество в скорости.

Использование опции отслеживания сделает это быстрее, но с некоторой точностью. Это использует алгоритм прогнозирования для некоторых промежуточных кадров, чтобы избежать расходования полного обнаружения лица на каждом кадре.

+0

Как именно построить LargestFaceFocusingProcessor? – Gensoukyou1337

+0

Я добавил еще несколько на LargestFaceFocusingProcessor выше. – pm0733464

 Смежные вопросы

  • Нет связанных вопросов^_^