最近,我一直在使用新的Developer Toolkit(v1.5.1)尝试使用Kinect进行面部识别。 FaceTracking工具的API可以在以下位置找到:http://msdn.microsoft.com/en-us/library/jj130970.aspx。到目前为止,基本上我一直试图做的是获得每个人唯一的“面部特征”。为此,我引用了Kinect跟踪的这些面部点:()。
然后,我跟踪了我的脸(加上几个 friend ),并使用基本代数计算了第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
这些只是我获得的一些值(value)。所以我的下一步是使用excel绘制它们。我的预期结果是深度和距离之间的线性趋势。因为随着深度增加,距离应该更小,反之亦然。因此,对于X人的数据,趋势是线性的。但是对于我的 friend (Y人)来说,情节到处都是。因此,我得出的结论是,我无法使用此方法进行面部识别。我无法获得跟踪这么短距离的精度。
我的目标是能够在人们进入房间时识别他们,保存他们的“个人资料”,然后在他们退出时将其删除。抱歉,这有点多,但是我只是想解释一下我到目前为止所取得的进展。那么,你们如何看待我如何实现面部识别?任何想法/帮助将不胜感激。
最佳答案
如果您使用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<>
。我还建议您使用bool的
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;
}
希望这可以帮助!
关于image-processing - Kinect的面部识别,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11263501/