К основному контенту

Про мобильный FaceDetection (NatCam, OpenCV, Dlib).


Несколько дней провозился с изучением вопроса распознавания лиц на разных платформах используя Unity. Сделал для себя несколько выводов.

Для Unity основным решением можно считать OpenCV for Unity, который является портом через Java. Примеров здесь множество, включая распознавание лица. Из коробки отслеживание «расхлебаное», поэтому для более плавного определения нужно докупить Dlib FaceLandmark Detector. Отслеживание положения лица становиться значительно лучше, количество опорных точек теперь 68.


Производительность печальна, особенно это чувствуется на мобильных устройствах. Большую часть производительности кушает сама «магия» определения, и преобразование специального материала для распознавания в текстуру и обратно. Чем выше разрешение вашей текстуры — тем больше времени займет распознавание. Решение который предлагает сам набор плагинов — уменьшение размера текстуры для определения в меньшую строну и производить расчет каждые N кадров. Такой вариант визуально на первый взгляд увеличивает работу приложения, но если присмотреться - кадр для расчета все равно просаживает картинку. Уменьшение размера для определения влияет на расстояние от камеры — чем лицо дальше тем труднее определить. Выбор — баланс этих двух параметров.
Если вы думаете что замена стандартной камеры webCam Unity на NatCam решит проблему, как подумал я — то вы ошибаетесь.
Как это работает? Берем текстуру с камеры (1280*720) превращаем ее в материал, выводим текстуру на UI или Renderer, если прошло 5 кадров скейлим текстуру (320*180), определяем лицо и пересчитываемым опорные точки относительно скейла.


NatCam Professional.
Картинка выдаваемая плагином действительно выглядит немного лучше, разработчик даже постарался создать пример для соединения плагинов (NatCam+OpenCV) – довольно далекий от «вставил и заработало». Вообще, нужно заметить, что в возможностях плагина и функционале описанному в магазине и на сайте много вещей, которые еще не реализованы, и находятся в закрытых бетах, которые еще нужно выпросить.
Плагин предоставит вам текстуру быстрее нежели стандартный, но обрабатывать texture-Mat-texture вы все равно будете на стороне OpenCV, так что никакого прироста производительность, единственное — мусор он убирать за собой в памяти умеет.

NatCam Extended умеет использовать Google Mobile Vision. Эту реализацию я тоже рассмотрел, в 1.5f2 работала с частотой 1-2 раза в секунду (LG Nexus5x) и плохо понимает поворот лица, в бете вообще не работало. Разработчик обещает будет лучше...

Вывод: чтобы использовать правильно и быстро необходимо распараллеливать обработку в разные потоки, что, видимо, делать нужно на уровне плагина OpenCV при портировании. На этом и выросли передовые Китайские и Индийские компании по передовым алгоритмам :)

Комментарии

  1. Этот комментарий был удален автором.

    ОтветитьУдалить
    Ответы
    1. I cant post a project.
      This can help: http://docs.natcam.io/Members/NatCam_PreviewMatrix.html

      Main idea is here:

      using UnityEngine;
      using NatCamU.Core;
      using OpenCVForUnity;

      namespace NatCamU.Examples
      {
      public class MyNatCamMat : NatCamBehaviour
      {
      private Mat matrix;
      private Texture2D texture;
      private Color32[] colors;

      public override void OnPreviewStart() { }

      public override void OnPreviewUpdate()
      {
      // Get the preview matrix for this frame
      if (!NatCam.PreviewMatrix(ref matrix)) return;
      //Dev should do this themselves
      OpenCVForUnity.Core.flip(matrix, matrix, 0);
      // Check the color buffer
      colors = colors ?? new Color32[matrix.cols() * matrix.rows()];
      // Check the destination texture
      texture = texture ?? new Texture2D(matrix.cols(), matrix.rows(), TextureFormat.ARGB32, false, false);
      // Draw a diagonal line on our image
      //Imgproc.line(matrix, new Point(0, 0), new Point(matrix.cols(), matrix.rows()), new Scalar(255, 0, 0, 255), 4);
      // Update our destination texture with the line drawn above
      Utils.matToTexture2D(matrix, texture, colors);
      // Set our UI Panel's RawImage texture to our destination texture
      preview.texture = texture;
      //texture = NatCam.Preview as Texture2D;
      //if (preview != null) preview.texture = NatCam.Preview;
      }

      public Mat GetMat()
      {
      return matrix;
      }

      public Texture2D GetTex()
      {
      return texture;
      }

      public Color32[] GetColors()
      {
      return colors;
      }

      public Mat GetDownScaleMat(float ratio)
      {
      Mat result = new Mat();
      Imgproc.resize(matrix, result, new Size(), 1f / ratio, 1f / ratio, Imgproc.INTER_LINEAR);
      //Debug.Log(result.rows());
      return result;
      }
      }
      }

      Удалить
  2. Actually, I have checked these code. But It always crashed in my phone. That is why I want to get a whole project to test? If possible, can you share me a link with your project. (ruihuili.lee@gmail.com) Thanks

    ОтветитьУдалить

Отправить комментарий