我正在开发一个Kinect(v1)应用程序,我希望能够检测用户相对于用户头部的楼层位置。
我想在画布上绘制一条从用户头部开始的画线,并在最接近头部的地板平面上的一点(这应该是一条完全垂直的线)结束。 / p>
然而,我是使用WPF,canvas和Kinect的新手,而且我遇到了一个缩放问题,其中线的结束比它应该的更远(在Kinect feed的网格之外)。我认为它是一个缩放问题的原因是因为它是完全垂直的,当我走近或远离相机时,它会正确地上下移动。
这是此操作的主要代码:
SkeletonPoint headPos = currentSkeleton.Joints[JointType.Head].Position;
SkeletonPoint floorPoint = getSkeletonFloorPoint(headPos, floorPlane);
CoordinateMapper mapper = new CoordinateMapper(KinectSensor);
ColorImagePoint colorHeadPoint = mapper.MapSkeletonPointToColorPoint(headPos, ColorImageFormat.RgbResolution640x480Fps30);
Point mappedHeadPoint = new Point(colorHeadPoint.X, colorHeadPoint.Y);
ColorImagePoint colorFloorPoint = mapper.MapSkeletonPointToColorPoint(floorPoint, ColorImageFormat.RgbResolution640x480Fps30);
Point mappedFloorPoint = new Point(colorFloorPoint.X, colorFloorPoint.Y);
drawUserPosition(userPos, mappedHeadPoint, mappedFloorPoint);
这是根据头部位置计算落地点的方法:
private SkeletonPoint getSkeletonFloorPoint(SkeletonPoint skeletonHeadPos, Tuple<float, float, float, float> floorPlane)
{
Point3D headPos = new Point3D(skeletonHeadPos.X, skeletonHeadPos.Y, skeletonHeadPos.Z);
Point3D pointOnPlane = new Point3D(0, (double) -(floorPlane.Item2 / floorPlane.Item4), 0);
Vector3D planeNorm = new Vector3D(floorPlane.Item1, floorPlane.Item2, floorPlane.Item3);
Vector3D planeToHead = Point3D.Subtract(headPos, pointOnPlane);
double dist = Vector3D.DotProduct(planeNorm, planeToHead);
Point3D floorPoint = Vector3D.Add(Vector3D.Multiply(-dist, planeNorm), headPos);
SkeletonPoint skeletonFloorPoint = new SkeletonPoint();
skeletonFloorPoint.X = (float) floorPoint.X;
skeletonFloorPoint.Y = (float) floorPoint.Y;
skeletonFloorPoint.Z = (float) floorPoint.Z;
return skeletonFloorPoint;
}
设置行位置:
private void drawUserPosition(Line userPos, Point headPoint, Point floorPoint)
{
userPos.X1 = headPoint.X;
userPos.Y1 = headPoint.Y;
userPos.X2 = floorPoint.X;
userPos.Y2 = floorPoint.Y;
}
这是画布的XAML:
<Canvas>
<kt:KinectSkeletonViewer
KinectSensorManager="{Binding KinectSensorManager}"
Visibility="{Binding KinectSensorManager.ColorStreamEnabled, Converter={StaticResource BoolToVisibilityConverter}}"
Width="{Binding ElementName=ColorViewer,Path=ActualWidth}"
Height="{Binding ElementName=ColorViewer,Path=ActualHeight}"
ImageType="Color" />
<Line X1="0" Y1="0" X2="0" Y2="0" Name="userPos" Stroke="Red" StrokeThickness="2" />
</Canvas>
正如我所说,我认为几何是正确的,我对WPF没有任何经验,所以我很确定这是我出错的地方。
感谢您提供任何帮助,如果有任何细节可以让我们更容易解决,我很乐意为您提供帮助。
答案 0 :(得分:0)
对不起,我只是一个愚蠢的错误。
当试图在地板平面上找到任意点时,我意外地在一个分区中翻转了两个值:
Point3D pointOnPlane = new Point3D(0, (double) -(floorPlane.Item2 / floorPlane.Item4), 0);
这是正确的代码:
Point3D pointOnPlane = new Point3D(0, (double) -(floorPlane.Item4 / floorPlane.Item2), 0);