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

原创 2013年02月27日 23:34:22

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

      OpenNI2在接口上与OpenNI有了较大变化,具体更新可以查看《OpenNI Migration Guide》。从获取深度,彩色传感器的数据而言,小斤觉得调用更为直观,但对于Kinect,一大缺憾是不支持OpenNI2提供的深度与彩色图像配准的方法(体现在下文中的device.isImageRegistrationModeSupported()方法)。

      但使用Kinect的童鞋也不必沮丧,在OpenNI2.1 beta中,小斤看到了新增的convertDepthToColorCoordinates()方法可以做一些深度与彩色坐标数据的转化,它的效果应该是与device.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR )类似的,有兴趣的童鞋可以尝试一下。

      在显示方面,小斤还是使用OpenCV,这次是使用OpenCV的C++接口进行操作。

/*************************
OpenNI2 Deep, Color and Fusion Image
Author: Xin Chen, 2013.2
Blog: http://blog.csdn.net/chenxin_130
*************************/

#include <stdlib.h>
#include <iostream>
#include <string>
#include "OpenNI.h"
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
using namespace std;
using namespace cv;
using namespace openni;

void CheckOpenNIError( Status result, string status )
{ 
	if( result != STATUS_OK ) 
		cerr << status << " Error: " << OpenNI::getExtendedError() << endl;
}

int main( int argc, char** argv )
{
	Status result = STATUS_OK;  
    
	//OpenNI2 image
	VideoFrameRef oniDepthImg;
    VideoFrameRef oniColorImg;

	//OpenCV image
	cv::Mat cvDepthImg;
	cv::Mat cvBGRImg;
	cv::Mat cvFusionImg;
	
	cv::namedWindow("depth");
	cv::namedWindow("image");
	cv::namedWindow("fusion");
	char key=0;

	//【1】
	// initialize OpenNI2
    result = OpenNI::initialize();
	CheckOpenNIError( result, "initialize context" );  

	// open device  
	Device device;
    result = device.open( openni::ANY_DEVICE );

	//【2】
	// create depth stream 
    VideoStream oniDepthStream;
    result = oniDepthStream.create( device, openni::SENSOR_DEPTH );

	//【3】
	// set depth video mode
    VideoMode modeDepth;
    modeDepth.setResolution( 640, 480 );
    modeDepth.setFps( 30 );
    modeDepth.setPixelFormat( PIXEL_FORMAT_DEPTH_1_MM );
    oniDepthStream.setVideoMode(modeDepth);
	// start depth stream
    result = oniDepthStream.start();
 
	// create color stream
    VideoStream oniColorStream;
    result = oniColorStream.create( device, openni::SENSOR_COLOR );
	// set color video mode
	VideoMode modeColor;
    modeColor.setResolution( 640, 480 );
    modeColor.setFps( 30 );
    modeColor.setPixelFormat( PIXEL_FORMAT_RGB888 );
    oniColorStream.setVideoMode( modeColor);
	
//【4】
	// set depth and color imge registration mode
	if( device.isImageRegistrationModeSupported(IMAGE_REGISTRATION_DEPTH_TO_COLOR ) )
	{
		device.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR );
	}
	// start color stream
    result = oniColorStream.start();  

	while( key!=27 ) 
	{  
		// read frame
		if( oniColorStream.readFrame( &oniColorImg ) == STATUS_OK )
		{
			// convert data into OpenCV type
			cv::Mat cvRGBImg( oniColorImg.getHeight(), oniColorImg.getWidth(), CV_8UC3, (void*)oniColorImg.getData() );
			cv::cvtColor( cvRGBImg, cvBGRImg, CV_RGB2BGR );
			cv::imshow( "image", cvBGRImg );
		}
  
		if( oniDepthStream.readFrame( &oniDepthImg ) == STATUS_OK )
		{
			cv::Mat cvRawImg16U( oniDepthImg.getHeight(), oniDepthImg.getWidth(), CV_16UC1, (void*)oniDepthImg.getData() );
			cvRawImg16U.convertTo( cvDepthImg, CV_8U, 255.0/(oniDepthStream.getMaxPixelValue()));
			//【5】
			// convert depth image GRAY to BGR
			cv::cvtColor(cvDepthImg,cvFusionImg,CV_GRAY2BGR);
			cv::imshow( "depth", cvDepthImg );
		}
		//【6】
		cv::addWeighted(cvBGRImg,0.5,cvFusionImg,0.5,0,cvFusionImg);
		cv::imshow( "fusion", cvFusionImg );
		key = cv::waitKey(20);
	}

	//cv destroy
	cv::destroyWindow("depth");
	cv::destroyWindow("image");
	cv::destroyWindow("fusion");

    //OpenNI2 destroy
    oniDepthStream.destroy();
    oniColorStream.destroy();
    device.close();
    OpenNI::shutdown();

	return 0;
}

      小斤由上到下解释一把:

      【1】使用OpenNI::initialize()方法进行初始化,对于错误处理,可以使用OpenNI::getExtendedError()方法。在这里,Device对象打开任意一个可用设备。

      【2】在OpenNI2中,可以通过创建VideoStream视频流对象来读取设备的深度图像和色彩图像数据。

      【3】对于VideoStream视频流对象,我们可以设备它的Mode,包括分辨率,FPS,像素格式等等。对于像素格式的类型,可以使用VideoStream的getSensorInfo()方法获得,目前Kinect只有PIXEL_FORMAT_DEPTH_1_MM可供选择。

      【4】如果设备支持深度与彩色图像配准的话,小斤在这里使用OpenNI2自带的接口进行配准。在while循环中,各个VideoStream对象通过readFrame()来读取对应的图像数据。

      【5】将OpenNI的图像数据转换为OpenCV可显示的图像格式。对于彩色图像,可以先将数据塞入OpenCV三通道(8位)RGB对象,再转换到BGR来显示。对于深度图像,先放入单通道(16位)对象(这是因为深度数据的值域较大),最近将深度值等比例缩小到[0,255]的值域中,作为灰度图显示。

      【6】最后的图像融合,由于addWeighted()方法需要两个输入图像是同一类型,所以小斤首先将深度灰度图(单通道),转化为BGR图像,这样就与彩色图像一致了。再通过该方法进行融合,小斤使用的比例是0.5,0.5,也就是融合图像的每个像素点的值,都是(深度图像该点的像素值*0.5)+ (彩色图像该点的像素值*0.5)。


----------------------------------

作者:小斤(陈忻)

新浪围脖:@小斤陈

本文属于原创文章,如需转载引用请注明原文作者和链接,谢谢。


OpenNI2 开发者指南

OpenNI 2.0 开发指南 主要介绍了OpenNI 2.0 的编程思维和具体使用到的API
  • LinkageWorld
  • LinkageWorld
  • 2016年09月22日 11:34
  • 3522

Kinect开发教程六:OpenNI2简介、安装与VS开发环境配置

简介       最近OpenNI2的推出,小斤也要多给博客除除草了,并在闲暇之余做一些范例程序。从试用几天的经历看,OpenNI2带来了较大的变化:     【1】程序接口作了较大的更新。具体更...
  • chenxin_130
  • chenxin_130
  • 2013年02月14日 15:06
  • 33057

使用OpenNI2读取oni格式的文件,并将其中的彩色视频,深度视频显示并保存

前几天做人体行为识别的师姐在网上下载了一个以
  • zdhfjb
  • zdhfjb
  • 2014年11月05日 10:38
  • 2229

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

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

Ubuntu14.04下openni2以及nite2的配置-kinectv1篇

本文实现了ubuntu14.04下的openni2和nite2的配置,使用freenect来驱动kinect v1,测试可用!...
  • wsr123wsrwsr
  • wsr123wsrwsr
  • 2015年09月11日 19:35
  • 4248

win10安装openni2以及获取kinect v1图像

初始环境:win10(64位)+vs2015+opencv2.4.13 硬件:kinect v1 最终环境:win10(64位)+vs2015+opencv2.4.13+kinect SDK 1.8+...
  • u011988573
  • u011988573
  • 2017年02月20日 14:10
  • 1565

OPENNI2.2(64位的)

  • 2014年07月28日 11:00
  • 8.14MB
  • 下载

基于OpenNI2(win64) 的Structure Sensor应用开发完整教程

工具准备1.从http://www.structure.io/openni 下载OpenNI-Windows-x64-2.2.0.33.zip 2.打开zip,运行其中的msi文件。安装完毕注销wi...
  • blackeagleX
  • blackeagleX
  • 2015年09月11日 16:45
  • 2161

Kinect开发教程一:OpenNI的安装与开发环境配置

小斤注:关于OpenNI2.X版本的安装与开发环境配置,请参考《Kinect开发教程六:OpenNI2简介、安装与VS开发环境配置》 ------------------------------...
  • chenxin_130
  • chenxin_130
  • 2011年08月17日 00:04
  • 91773

OpenNI 2.x与Kinect For Windows的安装

Microsoft推出Kinect For Windows后,原来的安装方法不再继续有效,OpenNI 1.5.x也不能再继续使用。这里介绍OpenNI和Kinect For Windows的安装与使...
  • zhuxiaoyang2000
  • zhuxiaoyang2000
  • 2013年06月13日 17:19
  • 7779
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Kinect开发教程八:OpenNI2显示深度、彩色及融合图像
举报原因:
原因补充:

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