我已经研究了几天但没有成功,看看其他问题是堆栈溢出是我的一个来源。 我正在使用Kinect for Windows创建一个程序,它将跟踪用户的关节并在单独的“屏幕”上绘制骨架,我已经映射了关节本身,我正在使用图像(红点)来演示位置映射关节的
我的下一步是通过从一个关节到另一个关节绘制一条线来构建骨架本身,我遇到的问题是如何绘制线条...我倾向于使事情过于复杂,所以我想知道我是否我只是为自己制造困难,而不仅仅是发现 最简单的解决方案。
我觉得我有99%的路在那里,但仍然有一个我遇到的错误,我无法理解,请在下面找到错误消息和相关的C#代码。
"cannot convert from 'Microsoft.Kinect.SkeletonPoint' to 'System.Windows.Point"
代码:
private void DrawBone (Joint jointFrom, Joint jointTo)
{
Brush centerPointBrush;
Pen trackedBonePen = new Pen(Brushes.White, TrackedBoneThickness);
inferredBonePen = new Pen(Brushes.Gray, InferredBoneThickness);
DrawingVisual visual = new DrawingVisual();
DrawingContext context = visual.RenderOpen();
centerPointBrush = Brushes.Red;
if (jointFrom.TrackingState == JointTrackingState.NotTracked
|| jointTo.TrackingState == JointTrackingState.NotTracked)
{
return;
}
if (jointFrom.TrackingState == JointTrackingState.Inferred
|| jointTo.TrackingState == JointTrackingState.Inferred)
{
context.DrawLine(inferredBonePen,jointFrom.Position, jointTo.Position);
}
if (jointFrom.TrackingState == JointTrackingState.Tracked
|| jointTo.TrackingState == JointTrackingState.Tracked)
{
context.DrawLine(trackedBonePen, jointFrom.Position, jointTo.Position);
}
}
与开始context.DrawLine
的行相关的错误,因为这些是DrawLine
函数的不正确参数,我收到了错误:
Error 4 The best overloaded method match for
'System.Windows.Media.DrawingContext.DrawLine(System.Windows.Media.Pen,
System.Windows.Point, System.Windows.Point)' has some invalid arguments
答案 0 :(得分:1)
不要重新发明轮子。来自微软的人在那里做得很好。也许这段代码可以帮助你:
private void DrawBonesAndJoints(Skeleton skeleton, DrawingContext drawingContext)
{
// Render Torso
this.DrawBone(skeleton, drawingContext, JointType.Head, JointType.ShoulderCenter);
this.DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.ShoulderLeft);
this.DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.ShoulderRight);
this.DrawBone(skeleton, drawingContext, JointType.ShoulderCenter, JointType.Spine);
this.DrawBone(skeleton, drawingContext, JointType.Spine, JointType.HipCenter);
this.DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipLeft);
this.DrawBone(skeleton, drawingContext, JointType.HipCenter, JointType.HipRight);
// Left Arm
this.DrawBone(skeleton, drawingContext, JointType.ShoulderLeft, JointType.ElbowLeft);
this.DrawBone(skeleton, drawingContext, JointType.ElbowLeft, JointType.WristLeft);
this.DrawBone(skeleton, drawingContext, JointType.WristLeft, JointType.HandLeft);
// Right Arm
this.DrawBone(skeleton, drawingContext, JointType.ShoulderRight, JointType.ElbowRight);
this.DrawBone(skeleton, drawingContext, JointType.ElbowRight, JointType.WristRight);
this.DrawBone(skeleton, drawingContext, JointType.WristRight, JointType.HandRight);
// Left Leg
this.DrawBone(skeleton, drawingContext, JointType.HipLeft, JointType.KneeLeft);
this.DrawBone(skeleton, drawingContext, JointType.KneeLeft, JointType.AnkleLeft);
this.DrawBone(skeleton, drawingContext, JointType.AnkleLeft, JointType.FootLeft);
// Right Leg
this.DrawBone(skeleton, drawingContext, JointType.HipRight, JointType.KneeRight);
this.DrawBone(skeleton, drawingContext, JointType.KneeRight, JointType.AnkleRight);
this.DrawBone(skeleton, drawingContext, JointType.AnkleRight, JointType.FootRight);
// Render Joints
foreach (Joint joint in skeleton.Joints)
{
Brush drawBrush = null;
if (joint.TrackingState == JointTrackingState.Tracked)
{
drawBrush = this.trackedJointBrush;
}
else if (joint.TrackingState == JointTrackingState.Inferred)
{
drawBrush = this.inferredJointBrush;
}
if (drawBrush != null)
{
drawingContext.DrawEllipse(drawBrush, null, this.SkeletonPointToScreen(joint.Position), JointThickness, JointThickness);
}
}
}
答案 1 :(得分:0)
错误消息说明了一切。您无需直接使用jointFrom.Position
,而是需要创建System.Windows.Point
来表示jointFrom
的坐标,并将其传递给DrawLine
。
同样适用于jointTo
...
复杂的是骨架位置,因此fromJoint.Position
表示3D坐标,而用于绘制线的点是2D坐标。因此无法直接转换。相反,您需要在2D中投影关节位置并使用投影点绘制线。
您的另一个选择是使用3D drawing in WPF,而不仅仅是绘制视觉效果。
答案 2 :(得分:0)
正如Miky Dinescu指出的那样,您的直接问题是需要将Microsoft.Kinect.Joint.Position
翻译为System.Windows.Point
。
您可能不关心Z
值(深度),因此需要将X
和Y
标准化为您窗口的大小。根据您希望绘制的骨架的行为方式,这可能就像始终将JointType.Spine
放在窗口的中心一样简单;或者您可能需要进行额外的数学运算才能根据玩家在Kinect的FOV中的位置来转换窗口中需要显示的位置。
基于Kinect的输入绘制骨架,可以在Kinect for Windows Toolkit中找到多个示例。 “Skeleton Basics”和“Shape Game”示例是立即浮现在脑海中的两个例子。您也可以只在Kinect for Windows Samples CodePlex页面找到代码(这些示例是针对SDK 1.6编写的,这些代码在SDK 1.7中都可以正常工作)。
以下是“Skeleton Basics”示例的MainWindow.xaml.cs。记下DrawBonesAndJoints' and
DrawBone'函数,以演示您想要做什么。
答案 3 :(得分:0)
也许我没有正确理解,但你为什么要做一些已经完成的事情?以下是Kinect Developer Toolkit 1.8的示例代码。
private void DrawBone(Skeleton skeleton, DrawingContext drawingContext, JointType jointType0, JointType jointType1)
{
Joint joint0 = skeleton.Joints[jointType0];
Joint joint1 = skeleton.Joints[jointType1];
// If we can't find either of these joints, exit
if (joint0.TrackingState == JointTrackingState.NotTracked || joint1.TrackingState == JointTrackingState.NotTracked)
{
return;
}
// Don't draw if both points are inferred
if (joint0.TrackingState == JointTrackingState.Inferred && joint1.TrackingState == JointTrackingState.Inferred)
{
return;
}
// We assume all drawn bones are inferred unless BOTH joints are tracked
Pen drawPen = this.inferredBonePen;
if (joint0.TrackingState == JointTrackingState.Tracked && joint1.TrackingState == JointTrackingState.Tracked)
{
drawPen = this.trackedBonePen;
}
drawingContext.DrawLine(drawPen, this.SkeletonPointToScreen(joint0.Position), this.SkeletonPointToScreen(joint1.Position));
}