使用Kinect进行面部识别

Ray*_*Ray 10 image-processing face-detection kinect

最近,我一直在使用新的Developer Toolkit(v1.5.1)尝试使用Kinect进行面部识别.可以在此处找到FaceTracking工具的API: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
Run Code Online (Sandbox Code Playgroud)

这些只是我获得的一些价值.所以我的下一步是使用excel绘制它们.我的预期结果是深度和距离之间的非常线性的趋势.因为随着深度的增加,距离应该更小,反之亦然.因此,对于人X的数据,趋势是相当线性的.但是对于我的朋友(Y人)来说,情节到处都是.所以我得出结论,我不能使用这种方法进行面部识别.我无法获得跟踪如此小距离所需的精度.

我的目标是能够识别进入房间的人,保存他们的"个人资料",然后一旦他们退出就将其删除.对不起,如果这有点多,但我只是想解释一下到目前为止我取得的进展.那么,你们怎么看待我如何实现面部识别?任何想法/帮助将不胜感激.

Lia*_*roy 4

如果您使用EnumIndexableCollection<FeaturePoint, PointF> so 您可以使用 aFaceTrackFrameGetProjected3DShape()方法。你像这样使用它:

  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();
Run Code Online (Sandbox Code Playgroud)

然后您可以使用图像中的每个点。我希望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.
Run Code Online (Sandbox Code Playgroud)

然后您就可以了解List<>要搜索的距离。我还建议你有一个List<>布尔值,它与距离相一致,如果结果匹配,则设置为真,这样你就可以跟踪哪个布尔值是真/假。
例子:

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


        List<bool> IsMatch = new List<bool>
        {
            false,
            false,
            false //etc
        };
Run Code Online (Sandbox Code Playgroud)

然后使用for循环进行搜索。

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

希望这可以帮助!