Measuring Distances using Kinect – The Right Way

By August 11, 2016C#, CodeProject, Kinect
Kinect Distance - Depth

Today I’m going to share a little trick that will save you a ton of time when working with Kinect: how to properly measure the distance between the sensor and a body or object. Surprisingly, I was asked the exact same question by three of my blog readers during the past 10 days!

First, some good-to-know background.

How Kinect measures distances

As you know, Kinect integrates an infrared sensor, along with a depth processor. The visible area is called “field of view”. The depth processor produces depth frames. Each depth frame is a grid of 512×424 points. The Kinect SDK is then feeding the depth frames to a powerful body-detection algorithm. The algorithm identifies 25 human body joints and calculates their coordinates in the 3D space.

Every single joint has 3 values: X, Y, and Z. It is projected in a Cartesian coordinate system. The (0, 0, 0) point is the position of the sensor. Every other point is measured in terms of the position of the sensor! Check the overhead graphic below. It’s viewing the sensor and the scene from above.

  • X is the position in the horizontal axis.
  • Y is the position in the vertical axis.
  • Z is the position in the depth axis.

Kinect Distance - Depth

Making sense of the Z value

X and Y are fairly easy to understand. That’s not true for Z. If you take a close look at the graphic above, you’ll notice that the Z value is not the linear distance between the point and the sensor. Instead, it’s the distance between the point and the plane of the sensor! It’s like having a virtual wall right in front of the Kinect. The Z value is the vertical distance from that wall (drawn in green).

To access the Z value, use the code below:

var distance = body.Joints[JointType.SpineBase].Position.Z;

Simple, huh? The “body” variable represents the tracked player. The “Position” property is a set of X, Y, and Z coordinates in the 3D space. The “Z” value is the distance between the player and the plane. I’ve used the SpineBase joint as a reference, since it’s the most reliably-tracked joint, and it’s also closer to the center of mass. You can read more about processing body data in my body-tracking tutorial.

Measuring the distance

How about the physical distance, though? The distance between the player and the device is represented by a mathematical vector (drawn in blue). Thankfully, we do not need to be gurus in Algebra to measure the length of a vector in the 3D space.

The length of a vector is given by the formula below:

Kinect Distance - Vector Length

The SDK provides us with all of the required values. All we have to do is convert the formula into working C# code:

public double Length(CameraSpacePoint point)
{
	return Math.Sqrt(
		point.X * point.X +
		point.Y * point.Y +
		point.Z * point.Z
	);
}

Bringing it all together:

var point = body.Joints[JointType.SpineBase].Position;
var distance = Length(point);

This is it! You now know exactly how far or how close someone is to the Kinect sensor! Of course, if someone is standing right in front of the sensor, the Z value and the distance would converge.

Hint: in case you need to measure distances of points that do not belong to the human body, you can use Coordinate Mapping.

Summary

Kinect provides us with the X, Y, and Z coordinates of the human body joints.

  • To measure the distance between the player and the plane of the sensor, we just use the Z value as-is.
  • To measure the distance between the player and the sensor, we calculate the length of the corresponding vector.

And… Vitruvius!

If you liked this post, then you’ll love Vitruvius. Vitruvius is the result of my Kinect research during the past 4 years. Vitruvius will help you minimize the development time and create tough applications with just a few lines of code! Includes advanced Mathematics, Avateering, Video Recording, Face Tracking, and more.

Download Vitruvius

‘Til the next time, keep Kinecting!

Author Vangos Pterneas

Vangos Pterneas is a Microsoft Most Valuable Professional in the Kinect technology. He helps companies from all over the world grow their revenue by creating profitable software products. Vangos is the owner of LightBuzz Software agency and author of The Dark Art Of Freelancing. Read more

More posts by Vangos Pterneas

Join the discussion 8 Comments

  • Unless Math.Pow gets inlined by the compiler (guess it doesn’t), better use x*x + y*y + z*z

    Also if one can work with distance2 (distance squared), say if they just want to compare distances, instead of distance itself, they can avoid the cost of the square root calculation.

  • Arunraj says:

    Dear Author, will you please provide me a tutorial for calculating the distance between two joints (out of 25) when a person is standing still?

    • Using Vitruvius, you can call the Length() extension method:

      At the head of your file:


      using LightBuzz.Vitruvius;

      Inside the FrameArrived event:


      var joint1 = body.Joints[JointType.KneeLeft];
      var joint2 = body.Joints[JointType.KneeRight];
      var distance = joint1.Length(joint2);

  • Eric says:

    Thank you so much for your tutorial.
    How about to find the distance between an object and Kinect? Here you used human body (player)

    • Hello Eric. If you’ve already detected an object in the 3D space using the depth frame array, you already know its distance from the sensor: it’s the ushort value of the depth array (measured in millimeters).

  • manideep says:

    Hi sir, i am using kinect xbox 360 sensor with projector side by side, i want to calculate the projected screen dimensions. Can you please help me to find out.

Leave a Reply