简体   繁体   English

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

[英]How to accurately draw a 3D point in Kinect space on a WPF canvas?

I am developing a Kinect (v1) application where I want to be able to detect the floor position of the user relative to the user's head. 我正在开发Kinect(v1)应用程序,在该应用程序中我希望能够检测用户相对于用户头部的地面位置。

I want to draw a line in WPF on the canvas which goes from the head of the user, and ends at the point on the floor plane which is closest to the head point (this should be a completely vertical line). 我想在WPF中在画布上从用户的头开始画一条线,并在地板平面上最接近该头点的点处结束(这应该是一条完全垂直的线)。

I am however new to using WPF, canvas and Kinect, and I am having a scaling issue where the line ends much further down than it should (outside of the Kinect feed's grid). 但是,我对使用WPF,canvas和Kinect并不陌生,并且遇到了缩放问题,该行的结尾比应有的远得多(在Kinect提要的网格之外)。 The reason I believe for it to be a scaling issue is because it is completely vertical and does move up and down correctly when I walk closer or further from the camera. 我之所以认为它是缩放问题,是因为它完全垂直,并且在我离相机更近或更远时确实可以正确地上下移动。

This is the main body of code for this operation: 这是此操作的代码主体:

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

This the method which computes the floor point based on the head position: 该方法根据头部位置计算下限点:

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

This sets the line position: 设置行的位置:

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;

}

This is the XAML for the canvas: 这是画布的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>

As I said, I think the geometry is correct, I just don't have any experience with WPF so I am fairly certain that is where I am going wrong. 就像我说的那样,我认为几何结构是正确的,只是我没有使用WPF的经验,因此我可以肯定那是我要去的地方。

Thank you for any help, and if there are any details I can provide to make this easier to solve I will be happy to provide them. 感谢您的帮助,如果有任何细节可以使我更容易解决,我将很乐意为您提供帮助。

Sorry, just a stupid mistake by me. 抱歉,我只是一个愚蠢的错误。

When trying to find an arbitrary point on the floor plane I accidentally flipped two values in a division: 当试图在地板平面上找到任意点时,我不小心翻转了除法中的两个值:

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

This is the correct code: 这是正确的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM