Click here to Skip to main content
15,878,959 members
Articles / Game Development / Kinect

Floor Detection using Kinect

Rate me:
Please Sign up or sign in to vote.
5.00/5 (2 votes)
27 Jan 2019CPOL4 min read 7.1K   2   1
Floor Detection using Kinect

Image 1

Kinect is primarily used in Body and Face tracking applications. Few people know, though, that Kinect is an amazing sensor for detecting the floor, too!

The native Kinect SDK provides us with all the information we need to accurately recognize whether a particular plane in the 3D space is, actually, a floor. We can also acquire information such as the height the Kinect sensor is placed at. We can even measure the distance between a point in the 3D space and the floor. All this can have a ton of impact in modern Augmented Reality applications.

In today’s tutorial, I am going to show you the following:

  • How to detect the floor clip plane
  • How to estimate the position (height) of the Kinect sensor
  • How to measure the distance between a point and the floor

This is a snapshot of what we are going to develop:

Image 2

Prerequisites

To run the code and samples provided in this article, you’ll need the following:

Source Code

The source code of the demo is hosted on GitHub. Moreover, all of this functionality is part of Vitruvius. Vitruvius is the most popular Kinect framework and will help you create Kinect apps very easily. So, if you are in a hurry, just download Vitruvius and integrate it into your apps.

Detecting the Floor Clip Plane

Some floor-detection functionality is already built into the Kinect SDK. Please, meet the FloorClipPlane property. The FloorClipPlane is a member of the BodyFrame class. Very few people are aware of its existence, however, it’s one of the most useful components when developing motion apps.

This is how to access the FloorClipPlane property:

C#
using (BodyFrame frame = e.FrameReference.AcquireFrame())
{
    if (frame != null)
    {
        Vector4 floorClipPlane = frame.FloorClipPlane;
    }
}

As you can see, the FloorClipPlane is a set of 4 floating-point values (Vector4): X, Y, Z, and W.

  • The X, Y, and Z values indicate the orientation of the plane in the 3D space.
  • The W value indicates the distance between the plane and the origin of the coordinate system.

Actually, the Vector4 structure represents the mathematical equation of a plane. You can read more about it on Wolfram MathWorld.

For our examples, we are going to encapsulate the FloorClipPlane vector into a handy Floor C# class:

C#
public class Floor
{
    public float X { get; internal set; }
    public float Y { get; internal set; }
    public float Z { get; internal set; }
    public float W { get; internal set; }

    public Floor(Vector4 floorClipPlane)
    {
        X = floorClipPlane.X;
        Y = floorClipPlane.Y;
        Z = floorClipPlane.Z;
        W = floorClipPlane.W;
    }
}

Kinect Sensor Height – The Magic W

As we saw, the W value indicates the distance between the floor and the origin of the coordinate system. The origin of the Kinect coordinate system is the device itself! Consequently, the W parameter of the FloorClipPlane describes the height where the Kinect sensor is positioned!

Using the W value, you can provide feedback to your users:

C#
Vector4 floorClipPlane = frame.FloorClipPlane;
float height = floorClipPlane.W;

if (height < 1f) // 1 meter
{
    Debug.WriteLine("The sensor is positioned too low!");
}

Field of View

When the W value is 0, it means that the field of view is limited. This is a very easy way to understand whether there are any objects, such as tables, chairs, etc. that are blocking the field of view.

C#
if (height == 0f)
{
    Debug.WriteLine("The field of view is limited.");
}

Kinect Sensor Tilt Angle

Other than finding the height of the sensor, we can also detect the tilting angle of the device. All we need to do is use the orientation of the floor plane:

C#
public double Tilt
{
    get
    {
        return Math.Atan(Z / Y) * (180.0 / Math.PI);
    }
}

Measuring Distances

In one of my previous articles, I explained how to measure the distance between 2 points in the 3D space using simple Mathematical equations.

Now, we need to measure the distance between a point and a plane in the 3D space. This is trickier, but we can easily figure it out with the help of Geometry.

The detected floor is a plane with a known distance (W) and orientation (X, Y, Z). A point in the 3D space is a set of X, Y, and Z coordinates.

C#
// Plane (X, Y, Z, W)
Floor floor = new Floor(frame.FloorClipPlane);

// Point (X, Y, Z)
CameraSpacePoint point = body.Joints[JointType.WristLeft].Position;

To measure the distance between a plane and a point, we need to use the Point-Plane Distance Formula:

Image 3

How shall we convert this formula into programming code? Let me do the Math for you:

C#
public double DistanceFrom(CameraSpacePoint point)
{
   double numerator = X * point.X + Y * point.Y + Z * point.Z + W;
   double denominator = Math.Sqrt(X * X + Y * Y + Z * Z);

   return numerator / denominator;
}

Add this method in your Floor.cs class. This is it! You can now get the 3D position of any point, pass it as a parameter to the above method, and find its distance from the floor.

C#
double distance = floor.DistanceFrom(point);

For your reference, this is the complete Floor.cs class:

C#
public class Floor
{
    public float X { get; internal set; }
    public float Y { get; internal set; }
    public float Z { get; internal set; }
    public float W { get; internal set; }

    public Floor(Vector4 floorClipPlane)
    {
        X = floorClipPlane.X;
        Y = floorClipPlane.Y;
        Z = floorClipPlane.Z;
        W = floorClipPlane.W;
    }

    public float Height
    {
        get { return W; }
    }

    public double Tilt
    {
        get { return Math.Atan(Z / Y) * (180.0 / Math.PI); }
    }

    public double DistanceFrom(CameraSpacePoint point)
    {
        double numerator = X * point.X + Y * point.Y + Z * point.Z + W;
        double denominator = Math.Sqrt(X * X + Y * Y + Z * Z);

        return numerator / denominator;
    }
}

This is it, folks! You can now use the Floor.cs class to implement cool functionality! In my C# sample code, I have also added numerous Extension methods that will let you draw the points of the floor and even find the projection of any other point.

History

  • 28th January, 2019: Initial version
This article was originally posted at https://pterneas.com/2017/09/10/floor-kinect

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
PraiseMy vote of 5 Pin
Stylianos Polychroniadis29-Jan-19 3:06
Stylianos Polychroniadis29-Jan-19 3:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.