2012-06-29 64 views
10

最近,我一直在努力使用新的開發人員工具包(v1.5.1)嘗試使用Kinect進行面部識別。 FaceTracking工具的API可以在這裏找到:http://msdn.microsoft.com/en-us/library/jj130970.aspx。基本上我迄今爲止所做的努力是獲得每個人獨有的「面部簽名」。要做到這一點,我參考了這些面部點Kinect軌道:(http://i.msdn.microsoft.com/dynimg/IC584330.png)。使用Kinect進行面部識別

然後我追蹤了我的臉(加上幾個朋友),並使用基本代數計算了點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

請添加一些代碼/甚至你正在使用的代數和距離的圖表 –

回答

4

如果使用EnumIndexableCollection<FeaturePoint, PointF> 所以你可以使用一個FaceTrackFrameGetProjected3DShape()方法。 你使用這樣的:

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的首選版本和深度由下式

preferredDistance/currentDistance

例子:

 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<>布爾值,它與 距離一致,如果結果匹配,則設置爲true,所以你可以跟蹤哪個 bool是真/假。
實施例:

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

希望能幫到你!

+0

謝謝你聽起來像一個好主意,我會研究這一點。 – Ray

+2

@射線如果這回答了您的問題,接受 –

+0

仍在工作中......我開始懷疑Kinect的面部識別功能。 – Ray

0

您附加的圖片是指2D模型。 GetProjected3DShape與圖片無關。

使用IFTResult.Get2DShapePoints可以獲得2D麪點。如果您使用FaceTrackingBasics-WPF示例,則必須爲該方法編寫C#包裝器。

+0

這是我的[封裝爲Get2DShapePoints](https://gist.github.com/OndroNR/ed20afdd6b1a62efa1a8#file-facetrackframe-cs) –

0

我正在研究這樣一個項目,爲我的碩士學位,我使用mahalanobis距離來計算距離,這是一個尺度不變的距離。這裏是公式:d(x,y)= sqrt(Pow((Xi-Yi),2)/ Pow(Si,2)); i:1 - > N,其中Si是樣本集上Xi和Yi的標準差。這裏是維基百科的鏈接:http://en.wikipedia.org/wiki/Mahalanobis_distance