Kinect SDK 1 - The Full Skeleton
Written by Harry Fairhead   
Article Index
Kinect SDK 1 - The Full Skeleton
Drawing the Body
The Full Skeleton

 

Drawing the Body

Now that we have the video frame as a bitmap we can start to draw the skeleton on it.

We need to retrieve the skeleton data. This is done in the usual way:

SkeletonFrame SFrame = e.OpenSkeletonFrame();
if (SFrame == null) return;
Skeleton[] Skeletons=
new Skeleton[SFrame.SkeletonArrayLength];
SFrame.CopySkeletonDataTo(Skeletons);

Now we have the skeleton data in the Skeletons array we can step through each skeleton in the set and check its tracked status before processing it:

foreach (Skeleton S in Skeletons)
{
if (S.TrackingState ==
SkeletonTrackingState.Tracked)
{

Now we have a skeleton in S we can use it to find the positions of any joint as we did in the previous chapter.

Our next problem is to find the positions of each of the joints that makeup the "body" of the skeleton i.e. the torso.  If you look at the diagram that gives the names of the joints you can see that we need the positions of the Head, Shoulder Center, Spine and Hip Center.

 

bodyparts

 

The positions of these four joints gives us the line of the torso and this is the line we need to draw connecting each of the joints in the correct order..

First we need the position of the head:

SkeletonPoint Sloc =  
S.Joints[JointType.Head].Position;

and we need to convert its position to pixel co-ordinates as described in the previous chapter:

ColorImagePoint Cloc= 
sensor.MapSkeletonPointToColor(Sloc,
ColorImageFormat.RgbResolution640x480Fps30);

So far so good but now we need the position of the ShoulderCenter joint and this means repeating everything we have just done and again for the spine and subsequent joints.

We clearly need to package this code into a helper method:

Point GetJoint(JointType j, Skeleton S)
{
SkeletonPoint Sloc =  S.Joints[j].Position;
ColorImagePoint Cloc=
sensor.MapSkeletonPointToColor(Sloc,
ColorImageFormat.RgbResolution640x480Fps30);
return new Point(Cloc.X,Cloc.Y);

The only difference is that we are now returning the co-ordinates as a Point object rather than a ColorImagePoint.  The reason for this is that the GDI drawing routines we are going to use accept Point object parameters.

Now we have the helper we can plot the line between the head and the ShoulderCenter joints:

Point p1=GetJoint(JointType.Head,S);
Point p2=GetJoint(JointTypeD.ShoulderCenter,S);
g.DrawLine(Pens.Red, p1, p2);

where g is the graphics object associated with the Bitmap i.e.:

Graphics g = Graphics.FromImage(bmap);

Now if you run the program you would see a single red line drawn from the head to the shoulder. This is the first part of our skeleton drawing.

 

Drawing a Bone

it should be obvious that what we have to do next is draw a line between ShoulderCenter and Spine. Clearly this is just a repeat of what we have already done so this suggests another helper function:

void DrawBone(
JointType j1,
JointType j2,
Skeleton S,
Graphics g)
{
Point p1 = GetJoint(j1, S);
Point p2 = GetJoint(j2, S);
g.DrawLine(Pens.Red, p1, p2);
}

This will draw a line between the two specified Joints. So to draw the body all we need is:

DrawBone( JointType.Head, 
JointType.ShoulderCenter,
S, g);
DrawBone( JointType.ShoulderCenter,
JointType.Spine,
S, g);
DrawBone( JointType.Spine,
JointType.HipCenter,
S, g);

This is all we need!

If you run the program now you will see lines following the body of the users that are detected.