computer_vision_kinect
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
computer_vision_kinect [2016/08/06 23:14] – joaomatos | computer_vision_kinect [2016/10/23 20:12] (current) – dwallace | ||
---|---|---|---|
Line 1: | Line 1: | ||
===== Computer Vision using Kinect Sensor ===== | ===== Computer Vision using Kinect Sensor ===== | ||
- | This tutorial will present all the instructions to install and run the Microsoft Kinect sensor using OpenNI library and how to use it together with OpenCV Libraries , using a C++ IDE for Windows. | + | |
+ | **Author:** Joao Matos Email: < | ||
+ | \\ | ||
+ | **Date:** Last modified on 6/8/2016 | ||
+ | \\ | ||
+ | **Keywords: | ||
+ | \\ | ||
+ | |||
+ | |||
+ | This tutorial will present all the instructions to install and run the Microsoft Kinect sensor using OpenNI library and how to use it together with OpenCV Libraries , using a Cpp IDE for Windows. | ||
Line 8: | Line 17: | ||
===== Installation Instructions ===== | ===== Installation Instructions ===== | ||
+ | | ||
+ | ** Downloading Required Softwares :** | ||
+ | |||
+ | .[[https:// | ||
+ | |||
+ | .[[http:// | ||
+ | |||
+ | .[[http:// | ||
+ | |||
+ | |||
+ | **Installing the Libraries using CMAKE:** | ||
+ | |||
+ | 1) Install the Kinect SDK , OpenNI2.0 and Nite2.0 , accepting all default installation configurations. | ||
+ | |||
+ | 2) Go to your control panel and open the device manager. Check if when you connect the Kinect to your PC you can see the Kinect for Windows icon. | ||
+ | |||
+ | 2) Go to your computer > right click on the icon of your PC > properties > advanced system settings > environment | ||
+ | |||
+ | 3) Open your Visual Studio solution configured with the OpenCV (see the OpenCV installation tutorial ) . Right click in your project name on the solution explorer (right side ) and go to properties. | ||
+ | |||
+ | 4) Under C/Cpp > GENERAL | ||
+ | |||
+ | 5) Under LINKER> GENERAL, add a new path to additional libraries directories . The path should be OpenNI2> | ||
+ | |||
+ | 6) Under LINKER > INPUT , add a library to additional dependencies . Add the OpenNI2.lib | ||
+ | |||
+ | 7) Include on your Visual Studio | ||
+ | |||
+ | 8) If you did all right , the OpenNI library can be used now. | ||
+ | |||
+ | 9) Try to run the commands: | ||
+ | |||
+ | < | ||
+ | |||
+ | openni:: | ||
+ | openni:: | ||
+ | auto ret = device.open(openni:: | ||
+ | if (ret != openni:: | ||
+ | throw std:: | ||
+ | } | ||
+ | |||
+ | //Opening Depth stream | ||
+ | openni:: | ||
+ | depthStream.create(device, | ||
+ | depthStream.start(); | ||
+ | |||
+ | </ | ||
+ | |||
+ | If you can compile this commands is because your OpenNI library is successfully installed. | ||
---- | ---- | ||
Line 14: | Line 72: | ||
===== How to get Depth image and convert to World Coordinates ===== | ===== How to get Depth image and convert to World Coordinates ===== | ||
+ | This code presents how to get the Depth stream using the OpenNI Library , and how to work with this depth information to obtain the Cartesian Coordinate of an object. | ||
- | ---- | + | **Introduction : How the Kinect works:** |
+ | |||
+ | {{ :: | ||
+ | |||
+ | In simple words , the Infrared projector sends infrared lights to the room , if you cold see these lights you would see a lot of dots projected in all your Kinect field of view. The Infrared camera analyze the pattern of the dots project into all the surfaces that intercepts the Infrared ray and by the Kinect software processing the Kinect can tell how the surface is ( if it is a flat surface , if it has curves , etc..) and also it can say how far is the projected dot from the camera (That' | ||
+ | |||
+ | The Depth stream obtained by the OpenNI library from the Kinect has stored the depth value of each pixel. So if you know in what pixel the object that you want to know the distance is (By analyzing the Colored Stream for example , or By running your object detection algorithm first ) , you only have to see the value of this same pixel on the Depth image and you get the distance (after doing some calculations). | ||
+ | |||
+ | The problem is that the RGB camera and IR camera are not on the same place , so the object located in the (x,y) pixel on the Depth Stream is not necessarily the same object located in the same (x,y) pixel of the Colored Stream. Fortunately we can use the OpenNI library to convert pixels from the Depth stream to the Colored Streams ( The values will be pretty close , so if your object is more than approximately 10x10 pixels , you can measure the distance of this object to the kinect using the pixel that is in the center of the object on the colored stream , and see the depth value of this pixel on the Depth Stream ( because the deviation is small and you will continue to be over the object surface on the Colored Stream ). For small object , you might need to use the Coordinate conversor. | ||
+ | |||
+ | For the OpenNI2 for example , you don't need to do any conversion , because you can start the device (kinect) with the command " | ||
+ | |||
+ | One thing that you have to pay attention is how to get the data from the Depth Stream. | ||
+ | |||
+ | You can get the depth data using this: (it will create the depth array, single row , with all the depth values) | ||
+ | |||
+ | < | ||
+ | short* depth = (short*)depthFrame.getData(); | ||
+ | </ | ||
+ | |||
+ | The depth data is stored into an one row array (so trying to access the depth of the (x,y) pixel will not work) . The pixel that you want to measure (you have the x,y location in the depth/ | ||
+ | < | ||
+ | index = ( PixelCoordinateY*DepthStreamResolutionX ) + PixelCoordinateX | ||
+ | </ | ||
+ | |||
+ | Finally you get the depth value of your object using: | ||
+ | |||
+ | < | ||
+ | short* depth = (short*)depthFrame.getData(); | ||
+ | depthObject = depth[index]; | ||
+ | </ | ||
+ | |||
+ | |||
+ | **Using OpenNI to get the depth image:** | ||
+ | |||
+ | **Initializing :** Lets try to open any Kinect connected to the PC , if you did't follow the installation instructions right you will not be able to start the Code and you will get an error message. | ||
+ | |||
+ | < | ||
+ | openni:: | ||
+ | openni:: | ||
+ | auto ret = device.open(openni:: | ||
+ | if (ret != openni:: | ||
+ | throw std:: | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | **Starting the Streams that you want:** (on this case Colored and Depth). We will initialize the " | ||
+ | |||
+ | < | ||
+ | openni:: | ||
+ | depthStream.create(device, | ||
+ | depthStream.start(); | ||
+ | |||
+ | openni:: | ||
+ | colorStream.create(device, | ||
+ | colorStream.start(); | ||
+ | |||
+ | device.setDepthColorSyncEnabled(true); | ||
+ | device.setImageRegistrationMode(openni:: | ||
+ | </ | ||
+ | |||
+ | **Useful Variables: | ||
+ | < | ||
+ | cv::Mat depthImage; | ||
+ | cv::Mat colorImage; | ||
+ | </ | ||
+ | |||
+ | Getting the frames: Now we introduce the infinite loop to keep getting frames from both streams . We need to create variables to store this frames , you do it with openni:: | ||
+ | |||
+ | < | ||
+ | while (1) { | ||
+ | |||
+ | |||
+ | // Create frames from depth and colored streams. | ||
+ | openni:: | ||
+ | depthStream.readFrame(& | ||
+ | |||
+ | openni:: | ||
+ | colorStream.readFrame(& | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | **Storing the frames in the Mat variable:** Now we want to store these frames into " | ||
+ | |||
+ | < | ||
+ | |||
+ | //CREATING THE COLORED IMAGE | ||
+ | const openni:: | ||
+ | ColorFrameBGR.create(initialcolorFrame.getHeight(), | ||
+ | memcpy(ColorFrameBGR.data, | ||
+ | |||
+ | cv:: | ||
+ | |||
+ | //CREATING THE DEPTH IMAGE | ||
+ | |||
+ | depthImage = cv:: | ||
+ | CV_16U, | ||
+ | |||
+ | </ | ||
+ | |||
+ | Now we have two images , " | ||
+ | |||
+ | | ||
+ | |||
+ | |||
+ | **Convert Depth coordinate to World coordinate: | ||
+ | |||
+ | There are two ways to get the World Coordinate from the depth image. First we can use an OpenNI function and get it straight , or we can use some algebra , and knowing the Kinect camera parameters we can find where the object is in relation with the camera referential . | ||
+ | | ||
+ | |||
+ | **The OpenNI function is:** | ||
+ | |||
+ | < | ||
+ | |||
+ | |||
+ | float x = 0; | ||
+ | float y = 0; | ||
+ | float z = 0; | ||
+ | |||
+ | openni:: | ||
+ | 200, | ||
+ | |||
+ | </ | ||
+ | |||
+ | you need to first initialize three variables to store the World coordinates given by the function (x,y,z). The Coordinate Converter will use the depthStream . The third and forth arguments are the pixel location of your object (on this case i want to know the world coordinate of the object located on the pixel (200,200). The fifth argument is the same object pixel but given in Depth Image Pixel (just use depthImage.at< | ||
+ | |||
+ | **Algebra Approach:** You can follow the math presented [[http:// | ||
- | * [[computer_vision_kinect_t1|Installation Instructions]] | ||
- | * [[computer_vision_kinect_t2|How to get Depth image and convert to World Coordinates]] | ||
computer_vision_kinect.1470550443.txt.gz · Last modified: 2016/08/06 23:14 by joaomatos