Subscribe:

Ads 468x60px

Thursday, August 2, 2012

How to get 3D Coordinates from Kinect

This is a simple tutorial helps you to get the 3D coordinates from Kinect using OpenNI library

Code snippet

 xn::DepthGenerator & Xn_depth;  
 const XnDepthPixel * pDepthMap = Xn_depth.GetDepthMap();  
 XnPoint3D Point2D, Point3D;  
 Point2D.X = ii;   //x-pixels  
 Point2D.Y = jj;  //y-pixels  
 Point2D.Z = pDepthMap[jj*640+ii];Xn_depth.ConvertProjectiveToRealWorld(1, &Point2D, &Point3D);  


Example Code showing the usage of this snippet. This code combine OpenCV and OpenNI. It gives X,Y,Z coordinate of the desired x,y pixel that we supply through command line argument.

Setting OpenCV in Windows

Installing OpenNI in Windows 7

Setting OpenNI in Visual studio 2010




 #include <iostream>  
 #include <stdexcept>  
 using namespace std;  
 #include <opencv2/core/core.hpp>  
 #include <opencv2/imgproc/imgproc.hpp>  
 #include <opencv2/highgui/highgui.hpp>  
 using namespace cv;  
 #include <XnCppWrapper.h>  
 using namespace xn;  
 #define SAMPLE_XML_PATH "./SamplesConfig.xml"  
 DepthGenerator Xn_depth;  
 int main(int argc,char* argv[])  
 {  
   Context g_context;  
   try {  
     XnStatus rc;  
     EnumerationErrors errors;  
     rc = g_context.InitFromXmlFile(SAMPLE_XML_PATH, &errors);  
     if ( rc == XN_STATUS_NO_NODE_PRESENT ) {  
       XnChar strError[1024];  
       errors.ToString( strError, 1024 );  
       throw runtime_error( strError );  
     }  
     else if( rc != XN_STATUS_OK ) {  
       cout << "Open failed: ";  
       throw runtime_error( xnGetStatusString( rc ) );  
     }  
     cout << "Open success." << endl;  
     //------------------------------  
     DepthGenerator g_depth;  
           rc = g_context.FindExistingNode( XN_NODE_TYPE_DEPTH, g_depth );  
     if( rc != XN_STATUS_OK ) {  
       cout << "Get depth error: ";  
       throw runtime_error( xnGetStatusString( rc ) );  
     }  
           rc = g_context.FindExistingNode( XN_NODE_TYPE_DEPTH, Xn_depth );  
     if( rc != XN_STATUS_OK ) {  
       cout << "Get depth error: ";  
       throw runtime_error( xnGetStatusString( rc ) );  
     }  
           const XnDepthPixel *pDepthMap=Xn_depth.GetDepthMap();  
           XnPoint3D Point2D,Point3D;  
           int ii=atoi(argv[1]);  
           int jj=atoi(argv[2]);  
           Point2D.X=ii;  
           Point2D.Y=jj;  
           Point2D.Z= pDepthMap[(jj*640)+ii];  
           Xn_depth.ConvertProjectiveToRealWorld(1,&Point2D,&Point3D);  
           std::cout<<Point3D.X<<std::endl;  
           std::cout<<Point3D.Y<<std::endl;  
           std::cout<<Point3D.Z<<std::endl;  
     //------------------------------  
     ImageGenerator g_image;  
     rc = g_context.FindExistingNode( XN_NODE_TYPE_IMAGE, g_image );  
     if( rc != XN_STATUS_OK ) {  
       cout << "Get image error: ";  
       throw runtime_error( xnGetStatusString( rc ) );  
     }  
     cout << "Generate success." << endl;  
     //------------------------------  
     DepthMetaData g_depthMD;  
     ImageMetaData g_imageMD;  
     g_depth.GetMetaData( g_depthMD );  
     g_image.GetMetaData( g_imageMD );  
     if( g_imageMD.FullXRes() != g_depthMD.FullXRes() || g_imageMD.FullYRes() != g_depthMD.FullYRes() ) {  
       throw std::runtime_error( "The device depth and image resolution must be equal!" );  
     }  
     if( g_imageMD.PixelFormat() != XN_PIXEL_FORMAT_RGB24 ) {  
       throw std::runtime_error( "The device image format must be RGB24" );  
     }  
     cout << "Get meta data success." << endl;  
     //------------------------------  
     XnMapOutputMode mapMode;  
     mapMode.nXRes = 640;  
     mapMode.nYRes = 480;  
     mapMode.nFPS = 30;  
     rc = g_depth.SetMapOutputMode( mapMode );  
     if( rc != XN_STATUS_OK ) {  
       cout << "Set depth output mode error: ";  
       throw runtime_error( xnGetStatusString( rc ) );  
     }  
     rc = g_image.SetMapOutputMode( mapMode );  
     if( rc != XN_STATUS_OK ) {  
       cout << "Set image output mode error: ";  
       throw runtime_error( xnGetStatusString( rc ) );  
     }  
     cout << "Set output mode success." << endl << "Starting Generate.." << endl;  
     //------------------------------  
     rc = g_context.StartGeneratingAll();  
     if( rc != XN_STATUS_OK ) {  
       cout << "Starting Kinect error: ";  
       throw runtime_error( xnGetStatusString( rc ) );  
     }  
     //------------------------------  
     Mat m_depth16u( 480, 640, CV_16UC1 );  
     Mat m_rgb8u( 480, 640, CV_8UC3 );  
     Mat m_DepthShow( 480, 640, CV_8UC1 );  
     Mat m_ImageShow( 480, 640, CV_8UC3 );  
     unsigned char key;  
     while( key != 27 && key != 'q' ) {  
       rc = g_context.WaitAnyUpdateAll();  
       if ( rc != XN_STATUS_OK ) {  
         cout << "Read failed: ";  
         throw runtime_error( xnGetStatusString( rc ) );  
       }  
       g_depth.GetMetaData( g_depthMD );  
       g_image.GetMetaData( g_imageMD );  
       memcpy( m_depth16u.data, g_depthMD.Data(), 640*480*2 );  
       memcpy( m_rgb8u.data, g_imageMD.Data(), 640*480*3 );  
       m_depth16u.convertTo( m_DepthShow, CV_8U, 255/2096.0 );  
       cvtColor( m_rgb8u, m_ImageShow, CV_RGB2BGR );  
       imshow( "depth", m_DepthShow );  
       imshow( "image", m_ImageShow );  
       key = waitKey( 10 );  
     }  
   }  
   catch( exception& ex ) {  
     cout << ex.what() << endl;  
   }  
   g_context.StopGeneratingAll();  
   g_context.Shutdown();  
   return 0;  
 }  

0 comments:

Post a Comment