如何根据可用坐标绘制骨架



当我在问题中键入时,我想根据可用坐标绘制骨架线(或两点之间的线)。绘制完成后,完成的手动骨架将是这样的。它和Skeleton Basic绘制的一样,但坐标由我们提供。

http://social.msdn.microsoft.com/Forums/getfile/425774

我将关节的坐标保存在一个文本文件中,该应用程序将从该文件中获取数据进行绘制。有人能帮我吗?我真的很需要它。

我确实喜欢这样,但屏幕上的骨架被冻结了,它没有按照文本文件中的坐标移动。

FileStream fs;
private void Model_DrawBoneAndJoints(ref Skeleton skeleton, DrawingContext drawingContext)
{
fs = new FileStream
(@"C:UsersPhucTruongTienDesktopdatagram.txt", FileMode.Open, FileAccess.Read, FileShare.None);
StreamReader sr = new StreamReader(fs);
float[] x = new float[20];
float[] y = new float[20];
SkeletonPoint position;
Array Joint_Types = Enum.GetValues(typeof(JointType));
//Joint[] joint_array = new Joint[20];
foreach (JointType j_types in Joint_Types)
{
Joint joint = new Joint();
joint = skeleton.Joints[j_types];
joint.TrackingState = JointTrackingState.Tracked;
position = joint.Position;
position.X = (float)Convert.ToDouble(sr.ReadLine());
position.Y = (float)Convert.ToDouble(sr.ReadLine());
position.Z = (float)Convert.ToDouble(sr.ReadLine());
joint.Position = position;
skeleton.Joints[j_types] = joint;
}

}

private void DrawBonesAndJoints(Skeleton Skeleton,DrawingContext DrawingContext){Model_DrawBoneAndJoints(参照骨架,drawingContext);

//i++;
// 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);
}
}
}

抱歉我英语不好!

您可以使用StreamWriter,在选定的路径对其进行初始化,然后对于每个帧,增加帧计数器,将其写入文件,将时间戳写入文件,然后循环通过关节并将其写入到文件。我会这样做:

using System.IO;
StreamWriter writer = new StreamWriter(@path);
int frames = 0;
...
void AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
frames++;
using (SkeletonFrame sFrame = e.OpenSkeletonFrameData())
{
if (sFrame == null)
return;
skeletonFrame.CopySkeletonDataTo(skeletons);
Skeleton skeleton = (from s in skeletons
where s.TrackingState == SkeletonTrackingState.Tracked
select s);
if (skeleton == null)
return;
if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
{
foreach (Joint joint in skeleton.Joints)
{
writer.Write(joint.Position.X + "," + joint.Position.Y + "," joint.Position.Z + ",");
}
writer.Write(Environment.NewLine);
}
}
}

然后从文件中读取:

StreamReader reader = new StreamReader(@path);
int frame = -1;
JointCollection joints;
...
string[] lines = reader.ReadAllLines();
...
void AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
canvas.Children.Clear();
string[] coords = lines[frame];
int jointIndex = 0;
for (int i = 0; i < coords.Length; i += 3)
{
joints[jointIndex].Position.X = int.Parse(coords[i]);
joints[jointIndex].Position.Y = int.Parse(coords[i + 1]);
joints[jointIndex].Position.X = int.Parse(coords[i + 2]);
jointIndex++;
}
DepthImageFrame depthFrame = e.OpenDepthImageFrame();
canvas.Children.Add(GetBodySegment(joints, brush, new JointType[] { JointType.HipCenter, JointType.Spine, JointType.ShoulderCenter, JointType.Head }, depthFrame, canvas));
canvas.Children.Add(GetBodySegment(joints, brush, new JointType[] { JointType.ShoulderCenter, JointType.ShoulderLeft, JointType.ElbowLeft, JointType.WristLeft, JointType.HandLeft }, depthFrame, canvas));
canvas.Children.Add(GetBodySegment(joints, brush, new JointType[] { JointType.ShoulderCenter, JointType.ShoulderRight, JointType.ElbowRight, JointType.WristRight, JointType.HandRight }, depthFrame, canvas));
canvas.Children.Add(GetBodySegment(joints, brush, new JointType[] { JointType.HipCenter, JointType.HipLeft, JointType.KneeLeft, JointType.AnkleLeft, JointType.FootLeft }, depthFrame, canvas));
canvas.Children.Add(GetBodySegment(joints, brush, new JointType[] { JointType.HipCenter, JointType.HipRight, JointType.KneeRight, JointType.AnkleRight, JointType.FootRight }, depthFrame, canvas));
depthFrame.Dispose();
frame++;
}
Point GetDisplayPosition(Joint joint, DepthImageFrame depthFrame, Canvas skeleton)
{
float depthX, depthY;
KinectSensor sensor = KinectSensor.KinectSensors[0];
DepthImageFormat depthImageFormat = sensor.DepthStream.Format;
DepthImagePoint depthPoint = sensor.CoordinateMapper.MapSkeletonPointToDepthPoint(joint.Position, depthImageFormat);
depthX = depthPoint.X;
depthY = depthPoint.Y;
depthX = Math.Max(0, Math.Min(depthX * 320, 320));
depthY = Math.Max(0, Math.Min(depthY * 240, 240));
int colorX, colorY;
ColorImagePoint colorPoint = sensor.CoordinateMapper.MapDepthPointToColorPoint(depthImageFormat, depthPoint, ColorImageFormat.RgbResolution640x480Fps30);
colorX = colorPoint.X;
colorY = colorPoint.Y;
return new System.Windows.Point((int)(skeleton.Width * colorX / 640.0), (int)(skeleton.Height * colorY / 480));
}
Polyline GetBodySegment(Joint[] joints, Brush brush, JointType[] ids, DepthImageFrame depthFrame, Canvas canvas)
{
PointCollection points = new PointCollection(ids.Length);
for (int i = 0; i < ids.Length; ++i)
{
points.Add(GetDisplayPosition(joints[i], depthFrame, canvas));
}
Polyline polyline = new Polyline();
polyline.Points = points;
polyline.Stroke = brush;
polyline.StrokeThickness = 5;
return polyline;
}

虽然你所做的会奏效,但当我过去做过这件事时,我使用了这种描述的方法。另一种方法是使用与顶部帧数类似的设置,将每个关节写入一行,然后有一个多维数组(例如jointCoords = new string[amountOfFrames, 21, 3]),然后每帧增加帧计数器,并遍历所有关节,然后遍历它们的x、y和z。从文件中读取的示例看起来像

char[] delimiters = new char[] { '|', ' ' };
//Make sure this file exists.
string file_name_2 = "C:\path\doctor.txt";
string[] lines = System.IO.File.ReadAllLines(@file_name_2);
foreach (string line in lines)
{
// for the skeleton frame
string[] seperated = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
seperated.CopyTo(delim, 0);
skeleton_frames_doctor[total_frames, count, 0] = int.Parse(delim[0]);
skeleton_frames_doctor[total_frames, count, 1] = int.Parse(delim[1]);
skeleton_frames_doctor[total_frames, count, 2] = int.Parse(delim[2]);
count++;
if (count == 21)
{
count = 0;
total_frames++;
}
}

阅读起来会像:

foreach (Joint joint in data.Joints)
{
Point jointPos = getDisplayPosition(joint);
//storing the patients x y coordinates
skeleton_frames[totalFrames1, joint_count, 0] = (double)jointPos.X;
skeleton_frames[totalFrames1, joint_count, 1] = (double)jointPos.Y;
//getting the doctors x y coordinates
XPos = (skeleton_frames[totalFrames1, 0, 0]) - (skeleton_frames_doctor[totalFrames1, 0, 0]);
YPos = (skeleton_frames[totalFrames1, 0, 1]) - (skeleton_frames_doctor[totalFrames1, 0, 1]);
//Scaling and transformation of doctors frame to patients frame
skeleton_frames_doctor_new[totalFrames1, joint_count, 0] = skeleton_frames_doctor[totalFrames1, joint_count, 0] + XPos;
skeleton_frames_doctor_new[totalFrames1, joint_count, 1] =  skeleton_frames_doctor[totalFrames1, joint_count, 1] + YPos;
for (int j = 0; j < 19; j++)
{
double DistP = Math.Sqrt(Math.Pow((skeleton_frames[totalFrames1, JointNo[j, 0] - 1, 0]) - skeleton_frames[totalFrames1, JointNo[j, 1] - 1, 0], 2) + Math.Pow((skeleton_frames[totalFrames1, JointNo[j, 0] - 1, 1]) - skeleton_frames[totalFrames1, JointNo[j, 1] - 1, 1], 2));
double DistD = Math.Sqrt(Math.Pow((skeleton_frames_doctor_new[totalFrames1, JointNo[j, 0] - 1, 0]) - skeleton_frames_doctor_new[totalFrames1, JointNo[j, 1] - 1, 0], 2) + Math.Pow((skeleton_frames_doctor_new[totalFrames1, JointNo[j, 0] - 1, 1]) - skeleton_frames_doctor_new[totalFrames1, JointNo[j, 1] - 1, 1], 2));
double alpha = DistP / DistD;
skeleton_frames_doctor_new[totalFrames1, JointNo[j, 1]-1, 0] = skeleton_frames_doctor_new[totalFrames1, JointNo[j, 0]-1, 0] + (skeleton_frames_doctor_new[totalFrames1, JointNo[j, 1]-1, 0] - skeleton_frames_doctor_new[totalFrames1, JointNo[j, 0]-1, 0]) * (alpha);
skeleton_frames_doctor_new[totalFrames1, JointNo[j, 1]-1, 1] = skeleton_frames_doctor_new[totalFrames1, JointNo[j, 0]-1, 1] + (skeleton_frames_doctor_new[totalFrames1, JointNo[j, 1]-1, 1] - skeleton_frames_doctor_new[totalFrames1, JointNo[j, 0]-1, 1]) * (alpha);
}

Line jointLine = new Line();
jointLine.X1 = jointPos.X - 3;
jointLine.X2 = jointLine.X1 + 6;
jointLine.Y1 = jointLine.Y2 = jointPos.Y;
jointLine.Stroke = jointColors[joint.ID];
jointLine.StrokeThickness = 6;
skeleton.Children.Add(jointLine);
joint_count++;
}

请注意,JointNo只是一个用于查找某些关节类型的索引的数组。这是

int[,] JointNo = new int[19, 2];
JointNo[0, 0] = 1;
JointNo[0, 1] = 2;
JointNo[1, 0] = 2;
JointNo[1, 1] = 3;
JointNo[2, 0] = 3;
JointNo[2, 1] = 4;
JointNo[3, 0] = 3;
JointNo[3, 1] = 9;
JointNo[4, 0] = 9;
JointNo[4, 1] = 10;
JointNo[5, 0] = 10;
JointNo[5, 1] = 11;
JointNo[6, 0] = 11;
JointNo[6, 1] = 12;
JointNo[7, 0] = 3;
JointNo[7, 1] = 5;
JointNo[8, 0] = 5;
JointNo[8, 1] = 6;
JointNo[9, 0] = 6;
JointNo[9, 1] = 7;
JointNo[10, 0] = 7;
JointNo[10, 1] = 8;
JointNo[11, 0] = 1;
JointNo[11,1] = 13;
JointNo[12, 0] = 13;
JointNo[12, 1] = 14;
JointNo[13,0] = 14;
JointNo[13, 1] = 15;
JointNo[14, 0] = 15;
JointNo[14, 1] = 16;
JointNo[15, 0] = 1;
JointNo[15, 1] = 17;
JointNo[16, 0] = 17;
JointNo[16, 1] = 18;
JointNo[17, 0] = 18;
JointNo[17, 1] = 19;
JointNo[18, 0] = 19;
JointNo[18, 1] = 20;

你可以从这段在beta 2中编写的代码中看到这一切,所以它目前不会编译,但它主要是你应该关注的方法。

相关内容

  • 没有找到相关文章

最新更新