在《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

#include

#include

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

  1. ODOO13 开发教程八 自定义导出数据到Excel

    前面几篇文章,我们已经说明怎么去创建并安装自己的模块.如果你跟着前几篇去做了,那太好了,我们可以一起进行本篇文章的学习了. 本篇实际上为新的odoo开发者说明,如何在odoo中,使用第三方包将数据导出 ...

  2. 如何开发一个黑白照片还原成彩色,AI黑白图像图片上色系统毕业设计毕设作品

    开发准备 第1步:准备好百度智能云的账号 第2步:在百度智能云领取对应AI开发的免费资源包 第3步:创建对应的应用,然后获取对应的开发信息,主要是下面几个 AppID:应用列表中 API Key:应用 ...

  3. iOS 11开发教程(十八)iOS11应用视图之使用代码添加按钮

    iOS 11开发教程(十八)iOS11应用视图之使用代码添加按钮 由于使用编辑界面添加视图的方式比较简单,所以不在介绍.这里,直接讲解代码中如何添加.使用代码为主视图添加一个按钮的方式和在1.3.3节 ...

  4. iOS 11开发教程(八)定制iOS11应用程序图标

    iOS 11开发教程(八)定制iOS11应用程序图标 在图1.9中可以看到应用程序的图标是网状白色图像,它是iOS模拟器上的应用程序默认的图标.这个图标是可以进行改变的.以下就来实现在iOS模拟器上将 ...

  5. Senparc.Weixin.MP SDK 微信公众平台开发教程(十八):Web代理功能

    在Senparc.Weixin.dll v4.5.7版本开始,我们提供了Web代理功能,以方便在受限制的局域网内的应用可以顺利调用接口. 有关的修改都在Senparc.Weixin/Utilities ...

  6. SAP UI5 应用开发教程之五十八 - 使用工厂方法在运行时动态创建不同类型的列表行项目控件试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...

  7. SAP UI5 应用开发教程之四十八 - 如何在 SAP UI5 应用里开发条形码扫描功能试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...

  8. SAP UI5 应用开发教程之三十八 - 使用 Chrome 开发者工具查看程序执行出错时的上下文信息

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...

  9. ArcGIS Maritime Server 开发教程(八)ArcGIS Bathymetry 扩展模块

    ArcGIS Maritime Server 开发教程(八)ArcGIS Bathymetry 扩展模块 本章导读:ArcGIS Bathymetry 扩展是 ArcGIS Maritime 解决方案 ...

最新文章

  1. 阿里手机小号,测试用
  2. python xpath语法-XPath 语法
  3. 什么是MySQL,以及它的特性
  4. Windows下用cmd命令安装及卸载服务[转]
  5. 关于双WiFi板卡做路由功能的记录
  6. 学习C++ - 类(Classes)的定义与实现
  7. CodeForces - 548D Mike and Feet(单调栈)
  8. 6 年成为 AIoT 独角兽,这位 17 年连续创业者是如何做到的?
  9. 马云卸任阿里巴巴董事局主席;苹果承认违法中国劳动法;IntelliJ IDEA 2019.2.2 发布​ | 极客头条...
  10. linux驱动基础开发3——linux 内核配置机制(make menuconfig、Kconfig、makefile)讲解-转
  11. STM32CUBEF4 实现USB 虚拟串口
  12. python文件中执行py文件
  13. JAVA SE 7虚拟机规范
  14. 车载导航软件怎么测试,导航功能测试2:语音提示
  15. 三角波电流与梯形波电流的分析
  16. Leetcode刷题之旅--剑指 Offer 17. 打印从1到最大的n位数
  17. Golang学习——error错误处理浅谈
  18. Cordova 拨打电话_Cordova 项目开启拨打电话
  19. RK987三模机械键盘win和alt键互换
  20. 移动医疗应用遍地开花,却抓不住用户的核心需求

热门文章

  1. 集合与泛型集合与键值对集合
  2. 2018java最新面试题
  3. Linux起不来,如何修复
  4. bzoj 4016: [FJOI2014]最短路径树问题
  5. 【转载】linux进程及进程控制
  6. 【网络流24题】No.7 试题库问题 (最大流,二分图多重匹配)
  7. 不同page页面选择不同页面模板的方法
  8. python学习---语法
  9. html网页距离顶部50像素,HTML5 教程之CSS Padding(填充)
  10. java 异步socket_java Socket读写异步分离