Распознавание лица с помощью Kinect

В последнее время я работал над попыткой распознавания лиц с помощью Kinect, используя новый Developer Toolkit (v1.5.1). API для инструментов FaceTracking можно найти здесь: http://msdn.microsoft.com/en-us/library/jj130970.aspx. В основном то, что я пытался сделать до сих пор, - это "подпись лица", уникальная для каждого человека. Для этого я указал на эти лицевые точки на дорожки Kinect: (http://i.msdn.microsoft.com/dynimg/IC584330.png).

Затем я отследил свое лицо (плюс пару друзей) и вычислил расстояние между точками 39 и 8, используя базовую алгебру. Я также получил значения для текущей глубины головы. Вот пример данных, которые я получил:

DISTANCE FROM RIGHT SIDE OF NOSE TO LEFT EYE: 10.1919198899636
CURRENT DEPTH OF HEAD: 1.65177881717682
DISTANCE FROM RIGHT SIDE OF NOSE TO LEFT EYE: 11.0429381713623
CURRENT DEPTH OF HEAD: 1.65189981460571
DISTANCE FROM RIGHT SIDE OF NOSE TO LEFT EYE: 11.0023324541865
CURRENT DEPTH OF HEAD: 1.65261101722717

Это лишь некоторые из значений, которые я достиг. Таким образом, мой следующий шаг заключался в том, чтобы их использовать, используя excel. Мой ожидаемый результат был очень линейным трендом между глубиной и расстоянием. Поскольку по мере увеличения глубины расстояние должно быть меньше и наоборот. Таким образом, для данных человека X тренд был довольно линейным. Но для моего друга (человека Y) сюжет был повсюду. Поэтому я пришел к выводу, что не могу использовать этот метод для распознавания лиц. Я не могу получить точность, необходимую для отслеживания такого небольшого расстояния.

Моя цель - определить людей, когда они войдут в комнату, сохранить их "профиль", а затем удалить их после их выхода. Извините, если это было немного, но я просто пытаюсь объяснить прогресс, который я сделал до сих пор. Итак, что вы, ребята, думаете о том, как я могу реализовать распознавание лица? Любые идеи/помощь будут высоко оценены.

Ответ 1

Если вы используете EnumIndexableCollection<FeaturePoint, PointF>  поэтому вы можете использовать метод FaceTrackFrame GetProjected3DShape().  Вы используете его следующим образом:

  private byte[] colorImage;

  private ColorImageFormat colorImageFormat = ColorImageFormat.Undefined;

  private short[] depthImage;

  private DepthImageFormat depthImageFormat = DepthImageFormat.Undefined;

  KinectSensor Kinect = KinectSensor.KinectSensors[0];

  private Skeleton[] skeletonData;

  colorImageFrame = allFramesReadyEventArgs.OpenColorImageFrame();
  depthImageFrame = allFramesReadyEventArgs.OpenDepthImageFrame();
  skeletonFrame = allFramesReadyEventArgs.OpenSkeletonFrame();
  colorImageFrame.CopyPixelDataTo(this.colorImage);
  depthImageFrame.CopyPixelDataTo(this.depthImage);
  skeletonFrame.CopySkeletonDataTo(this.skeletonData);
  skeletonData = new Skeleton[skeletonFrame.SkeletonArrayLength];

  foreach(Skeleton skeletonOfInterest in skeletonData)
  {
       FaceTrackFrame frame = faceTracker.Track(
           colorImageFormat, colorImage, depthImageFormat, depthImage, skeletonOfInterest);
  }

  private EnumIndexableCollection<FeaturePoint, PointF> facePoints = frame.GetProjected3DShape();

Затем вы можете использовать каждую из точек вашего изображения.  Я бы имел const double preferedDistance, чтобы вы могли умножить текущий  глубины и x и y разных точек, чтобы найти предпочтительную версию x и y и глубиной по формуле

Предпочтительное сопротивление/сопротивление тока

Пример:

        const double preferredDistance = 500.0;//this can be any number you want.

        double currentDistance = //however you are calculating the distance

        double whatToMultiply = preferredDistance / currentDistance;

        double x1 = this.facePoints[39].X;
        double y1 = this.facePoints[39].Y;
        double x2 = this.facePoints[8].X;
        double y2 = this.facePoints[8].Y;

        double result = whatToMultiply * //however you are calculating distance.

Тогда у вас может быть List<> того, что расстояния должны искать.  Я бы также предположил, что у вас есть List<> bool, которые согласны с расстояния до значения true, если результат совпадает, поэтому вы можете отслеживать, какие  bool - true/false.
Пример:

        List<double> DistanceFromEyeToNose = new List<double>
        {
            1,
            2,
            3 //etc
        };


        List<bool> IsMatch = new List<bool>
        {
            false,
            false,
            false //etc
        };

Затем выполните поиск с помощью цикла for.

        for (int i = 0; i < DistanceFromEyeToNose.Count; i++)
        {
            if (result == DistanceFromEyeToNose[i]) IsMatch[i] = true;
        } 

Надеюсь, что это поможет!

Ответ 2

Прикрепленное изображение относится к 2D-модели. GetProjected3DShape не имеет ничего общего с изображением.

Используйте IFTResult.Get2DShapePoints, чтобы получить двумерные граничные точки. Если вы используете пример FaceTrackingBasics-WPF, вам нужно написать оболочку С# для этого метода.

Ответ 3

Я работаю над таким проектом, как этот для моей магистерской степени, и я вычисляю расстояние, используя расстояние махаланобиса, которое является масштабно-инвариантным. Вот формула: d (x, y) = sqrt (Pow ((Xi-Yi), 2)/Pow (Si, 2)); i: 1 → N, где Si - стандартное отклонение Xi и Yi над образцом. Вот ссылка на wikipedia: http://en.wikipedia.org/wiki/Mahalanobis_distance