如何在WPF画布上的Kinect空间中准确绘制3D点?

时间:2015-01-09 11:58:32

标签: c# wpf xaml canvas kinect

我正在开发一个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没有任何经验,所以我很确定这是我出错的地方。

感谢您提供任何帮助,如果有任何细节可以让我们更容易解决,我很乐意为您提供帮助。

1 个答案:

答案 0 :(得分:0)

对不起,我只是一个愚蠢的错误。

当试图在地板平面上找到任意点时,我意外地在一个分区中翻转了两个值:

Point3D pointOnPlane = new Point3D(0, (double) -(floorPlane.Item2 / floorPlane.Item4), 0);

这是正确的代码:

Point3D pointOnPlane = new Point3D(0, (double) -(floorPlane.Item4 / floorPlane.Item2), 0);