C# 如何在WPF画布上精确绘制Kinect空间中的3D点?
我正在开发一个Kinect v1应用程序,希望能够检测用户相对于头部的地板位置 我想在画布上用WPF画一条线,从用户的头部开始,在地板上最靠近头部的点结束。这应该是一条完全垂直的线 不过,我对使用WPF、canvas和Kinect还不熟悉,而且我遇到了一个缩放问题,即行的结尾比Kinect提要的网格之外的地方要向下延伸得多。我之所以认为这是一个缩放问题,是因为它是完全垂直的,当我走近或远离相机时,它确实会正确地上下移动 这是此操作的代码主体:C# 如何在WPF画布上精确绘制Kinect空间中的3D点?,c#,wpf,xaml,canvas,kinect,C#,Wpf,Xaml,Canvas,Kinect,我正在开发一个Kinect v1应用程序,希望能够检测用户相对于头部的地板位置 我想在画布上用WPF画一条线,从用户的头部开始,在地板上最靠近头部的点结束。这应该是一条完全垂直的线 不过,我对使用WPF、canvas和Kinect还不熟悉,而且我遇到了一个缩放问题,即行的结尾比Kinect提要的网格之外的地方要向下延伸得多。我之所以认为这是一个缩放问题,是因为它是完全垂直的,当我走近或远离相机时,它确实会正确地上下移动 这是此操作的代码主体: SkeletonPoint headPos = cu
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的经验,所以我相当肯定这就是我出错的地方
感谢您的帮助,如果有任何细节我可以提供给您,使之更容易解决,我将很乐意提供。对不起,我犯了一个愚蠢的错误 在尝试查找楼层平面上的任意点时,我意外地翻转了分区中的两个值:
Point3D pointOnPlane = new Point3D(0, (double) -(floorPlane.Item2 / floorPlane.Item4), 0);
这是正确的代码:
Point3D pointOnPlane = new Point3D(0, (double) -(floorPlane.Item4 / floorPlane.Item2), 0);