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开发教程八:OpenNI2显示深度、彩色及融合图像

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

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

环境:OpenNI2(http://structure.io/openni); OpenCV2.4.6; VS2010
  • scliu12345
  • scliu12345
  • 2014年05月28日 16:28
  • 1344

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

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

kinect 2.0 SDK学习笔记(四)--深度图与彩色图对齐

深度图与彩色图对齐如果用kinect SDK的话只需要一个函数就好了:MapDepthFrameToColorSpace(512 * 424, depthData, 512 * 424, m_pCol...
  • jiaojialulu
  • jiaojialulu
  • 2016年11月14日 00:28
  • 8665

realsense彩色图与深度图对齐

其实realsense的彩色图与深度图对齐非常简单,因为当你开始采集彩色图与深度图流时,会自动产生一个对齐后的图像流,一个是彩色对齐深度:color_aligned_to_depth,一个是深度对齐彩...
  • wi162yyxq
  • wi162yyxq
  • 2017年04月06日 15:28
  • 2553

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

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

KINECT人物抠取 图像对齐(KINECTSDK + OPENCV)

#include #include //windows的头文件,必须要,不然NuiApi.h用不了 #include //Kinect for windows 的头文件 #include "N...
  • nation_zhang
  • nation_zhang
  • 2014年11月26日 09:48
  • 1712

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

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

kinect 深度彩色图像对齐的问题

最近在用kinect和opencv做东西,遇到了深度和彩色图像不能对齐的问题,查看了好多文档,其中一篇博客KINECT人物抠取 图像对齐(KINECTSDK + OPENCV)http://blo...
  • qiqijiayou793518
  • qiqijiayou793518
  • 2016年04月07日 14:45
  • 521

Kinect on Ubuntu with OpenNI2.2

接上文KinectV2+Ubuntu 14.04+Ros 安装教程,本文考虑的是KinectV1的情况。   安装 首先安装依赖项 sudo apt-get install g++ sudo...
  • BBZZ2
  • BBZZ2
  • 2016年06月07日 15:58
  • 1542
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Kinect中使用OpenNI2实现深度图和彩色图对齐
举报原因:
原因补充:

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