Kinect中使用OpenNI2实现深度图和彩色图对齐

来源:互联网 发布:java 方法调用实例 编辑:程序博客网 时间:2024/04/20 03:02

          博主从一位台湾大牛heresy那里学到很多东西,其中就有关于Kinect中使用OpenNI2实现深度图和彩色图对齐的相关知识。他的Blog是http://viml.nchc.org.tw/home/,大家可以去他的Blog学到很多知识。

          关于这篇文章,其中heresy自己写了一个Kinect.dll文件,可以实现 mDevice.setImageRegistrationMode(IMAGE_REGISTRATION_DEPTH_TO_COLOR );这个函数。有了它,对齐自然就水到渠成了。OpenNI1中不支持这个函数,需要修改相关源代码,实验室一个师兄做过这个。微软SDK也出过一个函数,叫做MapColorFrameToDepthFrame()这个函数,博主搞了好几天,没用好这个函数,故选择了OPENNI2。如果有同学对微软SDK熟悉,并搞定了这个问题的化,欢迎分享交流。

         下面博主贴出自己的代码,很简单。希望可以帮助大家。

         

#include <iostream>  // OpenCV Header#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>  // OpenNI Header#include <OpenNI.h>  // namespaceusing namespace std;using namespace openni;  int main( int argc, char **argv ){  // 1. Initial OpenNI  if( OpenNI::initialize() != STATUS_OK )  {    cerr << "OpenNI Initial Error: "          << OpenNI::getExtendedError() << endl;    return -1;  }    // 2. Open Device  Device mDevice;  if( mDevice.open( ANY_DEVICE ) != STATUS_OK )  {    cerr << "Can't Open Device: "          << OpenNI::getExtendedError() << endl;    return -1;  }  openni::Status status;  // 3. Create depth stream  VideoStream mDepthStream;  if( mDevice.hasSensor( SENSOR_DEPTH ) )  {    if( mDepthStream.create( mDevice, SENSOR_DEPTH ) == STATUS_OK )    {      // 3a. set video mode      VideoMode mMode;      mMode.setResolution( 640, 480 );      mMode.setFps( 30 );      mMode.setPixelFormat( PIXEL_FORMAT_DEPTH_1_MM );        if( mDepthStream.setVideoMode( mMode) != STATUS_OK )      {        cout << "Can't apply VideoMode: "             << OpenNI::getExtendedError() << endl;      }    }    else    {      cerr << "Can't create depth stream on device: "           << OpenNI::getExtendedError() << endl;      return -1;    }  }  else  {    cerr << "ERROR: This device does not have depth sensor" << endl;    return -1;  }    // 4. Create color stream  VideoStream mColorStream;  if( mDevice.hasSensor( SENSOR_COLOR ) )  {    if( mColorStream.create( mDevice, SENSOR_COLOR ) == STATUS_OK )    {      // 4a. set video mode      VideoMode mMode;      mMode.setResolution( 640, 480 );      mMode.setFps( 30 );      mMode.setPixelFormat( PIXEL_FORMAT_RGB888 );        if( mColorStream.setVideoMode( mMode) != STATUS_OK )      {        cout << "Can't apply VideoMode: "              << OpenNI::getExtendedError() << endl;      }        // 4b. image registration      if( mDevice.isImageRegistrationModeSupported(              IMAGE_REGISTRATION_DEPTH_TO_COLOR ) )      {        mDevice.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR );      }    }    else    {      cerr << "Can't create color stream on device: "           << OpenNI::getExtendedError() << endl;      return -1;    }  }     if( mDevice.isImageRegistrationModeSupported( IMAGE_REGISTRATION_DEPTH_TO_COLOR ) ){ status=mDevice.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR );}  // 5. create OpenCV Window  cv::namedWindow( "Depth Image",  CV_WINDOW_AUTOSIZE );  cv::namedWindow( "Color Image",  CV_WINDOW_AUTOSIZE );    // 6. start  VideoFrameRef  mColorFrame;  VideoFrameRef  mDepthFrame;  mDepthStream.start();  mColorStream.start();  int iMaxDepth = mDepthStream.getMaxPixelValue();  int ImgNum=0;  char ImagesName[50];  cv::Mat cImageBGR;  cv::Mat mScaledDepth;  while( true )  {    // 7. check is color stream is available    if( mColorStream.isValid() )    {      // 7a. get color frame      if( mColorStream.readFrame( &mColorFrame ) == STATUS_OK )      {        // 7b. convert data to OpenCV format        const cv::Mat mImageRGB(                mColorFrame.getHeight(), mColorFrame.getWidth(),                CV_8UC3, (void*)mColorFrame.getData() );        // 7c. convert form RGB to BGR        cv::cvtColor( mImageRGB, cImageBGR, CV_RGB2BGR );        // 7d. show image        cv::imshow( "Color Image", cImageBGR );      }    }      // 8a. get depth frame    if( mDepthStream.readFrame( &mDepthFrame ) == STATUS_OK )    {      // 8b. convert data to OpenCV format      const cv::Mat mImageDepth(                mDepthFrame.getHeight(), mDepthFrame.getWidth(),                CV_16UC1, (void*)mDepthFrame.getData() );      // 8c. re-map depth data [0,Max] to [0,255]           mImageDepth.convertTo( mScaledDepth, CV_8U, 255.0 / iMaxDepth );      // 8d. show image      cv::imshow( "Depth Image", mScaledDepth );    }      // 6a. check keyboard    if( cv::waitKey( 1 ) == 'q' )      break;if(cv::waitKey( 1 )=='s')//char filename[100];{sprintf(ImagesName, "cImage%.3d.bmp", ImgNum);                imwrite(ImagesName,cImageBGR );sprintf(ImagesName, "dImage%.3d.bmp", ImgNum);imwrite(ImagesName,mScaledDepth);ImgNum++;     }  }    // 9. stop  mDepthStream.destroy();  mColorStream.destroy();  mDevice.close();  OpenNI::shutdown();  system("pause");  return 0;}

这个代码实现了同时显示深度图和彩色图。并进行了对齐。大家可以获取彩色图和深度图进行叠加,观察效果。

该代码成功的运行条件是替换OpenNI2安装路径下的Kinect.dll和项目文件下的Kinect.dll

具体路径为C:\Program Files (x86)\OpenNI2\Redist\OpenNI2\Drivers


由于Heresy发布的Kinect.dll文件的地址被GFW呵呵了,所以我上传了一份到CSDN论坛里面,大家可以下载,博主最近没啥积分,故设了2个积分下载权限,大家没有积分的也可以留下邮箱,我看到了后会发给你们。

下载地址是 http://download.csdn.net/detail/janestar/7817293




         

0 0
原创粉丝点击