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

原创 2014年08月25日 18:41:39

          博主从一位台湾大牛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>
  
// namespace
using 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




         

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Kinect深度图与彩色图的坐标校准

kinect的深度数据和彩色数据的分辨率以及视场大小都不一样,不能直接对应起来,想要把深度和彩色融合起来就要费一番周折了。 看了MSDN中kinectSDK的介绍,发现了一个ICoordinateM...
  • shihz_fy
  • shihz_fy
  • 2015年02月07日 12:21
  • 11571

Kinect开发教程八:OpenNI2显示深度、彩色及融合图像

在《Kinect开发教程二:OpenNI读取深度图像与彩色图像并显示》中,小斤介绍了OpenNI读取深度与彩色图像数据的方法,并且借助OpenCV进行显示。       OpenNI2在接口上与Op...

OpenNI2获取华硕XtionProLive深度图和彩色图并用OpenCV显示

使用OpenNI2打开XtionProLive时有个问题,彩色图分辨率无论如何设置始终是320*240,深度图倒是可以设成640*480,而OpenNI1.x是可以获取640*480的彩色图的。 ...
  • masikkk
  • masikkk
  • 2014年07月02日 15:41
  • 5571

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

OpenNI:深度图显示方法

OpenNI的深度图显示有主要有两种方法: 1.深度值直接赋值方法(同上一篇): 缺点:深度图层次不明显,主要由于位移操作导致 #include #include #include #inc...

关于OpenNI2和OpenCV2的那些事——获取彩色图和深度图(XtionProLive)

上一节讲述了搭环境时遇到的挫折,这一节我们来讲讲如何使用XtionProLive(XtionPro没有彩色摄像头,Live版才有)获取彩色图和数度图,以及彩色图的放大与水平镜像。(PS: 对比两代Op...

Kinect v2.0如何获取彩色图像和深度图像

首先,下载最新的Kinect 2 SDK  http://www.microsoft.com/en-us/kinectforwindows/develop/downloads-docs.aspx下载之...

OpenNI2显示深度、彩色及融合图像

在《Kinect开发教程二:OpenNI读取深度图像与彩色图像并显示》中,小斤介绍了OpenNI读取深度与彩色图像数据的方法,并且借助OpenCV进行显示。       OpenNI2在接口上与...

OpenNI2显示深度、彩色及融合图像

环境:OpenNI2(http://structure.io/openni); OpenCV2.4.6; VS2010

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Kinect中使用OpenNI2实现深度图和彩色图对齐
举报原因:
原因补充:

(最多只允许输入30个字)