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

原创 2013年02月27日 23:34:22
  • 标签:
  • OpenNI /
  • Kinect /
  • 人机互动 /
  • 计算机视觉
  • 23427

在《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++接口进行操作。

[cpp] view plain copy
  1. /*************************
  2. OpenNI2 Deep, Color and Fusion Image
  3. Author: Xin Chen, 2013.2
  4. Blog: http://blog.csdn.net/chenxin_130
  5. *************************/
  6. #include <stdlib.h>
  7. #include <iostream>
  8. #include <string>
  9. #include "OpenNI.h"
  10. #include "opencv2/core/core.hpp"
  11. #include "opencv2/highgui/highgui.hpp"
  12. #include "opencv2/imgproc/imgproc.hpp"
  13. using namespace std;
  14. using namespace cv;
  15. using namespace openni;
  16. void CheckOpenNIError( Status result, string status )
  17. {
  18. if( result != STATUS_OK )
  19. cerr << status << " Error: " << OpenNI::getExtendedError() << endl;
  20. }
  21. int main( int argc, char** argv )
  22. {
  23. Status result = STATUS_OK;
  24. //OpenNI2 image
  25. VideoFrameRef oniDepthImg;
  26. VideoFrameRef oniColorImg;
  27. //OpenCV image
  28. cv::Mat cvDepthImg;
  29. cv::Mat cvBGRImg;
  30. cv::Mat cvFusionImg;
  31. cv::namedWindow("depth");
  32. cv::namedWindow("image");
  33. cv::namedWindow("fusion");
  34. char key=0;
  35. //【1】
  36. // initialize OpenNI2
  37. result = OpenNI::initialize();
  38. CheckOpenNIError( result, "initialize context" );
  39. // open device
  40. Device device;
  41. result = device.open( openni::ANY_DEVICE );
  42. //【2】
  43. // create depth stream
  44. VideoStream oniDepthStream;
  45. result = oniDepthStream.create( device, openni::SENSOR_DEPTH );
  46. //【3】
  47. // set depth video mode
  48. VideoMode modeDepth;
  49. modeDepth.setResolution( 640, 480 );
  50. modeDepth.setFps( 30 );
  51. modeDepth.setPixelFormat( PIXEL_FORMAT_DEPTH_1_MM );
  52. oniDepthStream.setVideoMode(modeDepth);
  53. // start depth stream
  54. result = oniDepthStream.start();
  55. // create color stream
  56. VideoStream oniColorStream;
  57. result = oniColorStream.create( device, openni::SENSOR_COLOR );
  58. // set color video mode
  59. VideoMode modeColor;
  60. modeColor.setResolution( 640, 480 );
  61. modeColor.setFps( 30 );
  62. modeColor.setPixelFormat( PIXEL_FORMAT_RGB888 );
  63. oniColorStream.setVideoMode( modeColor);
  64. //【4】
  65. // set depth and color imge registration mode
  66. if( device.isImageRegistrationModeSupported(IMAGE_REGISTRATION_DEPTH_TO_COLOR ) )
  67. {
  68. device.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR );
  69. }
  70. // start color stream
  71. result = oniColorStream.start();
  72. while( key!=27 )
  73. {
  74. // read frame
  75. if( oniColorStream.readFrame( &oniColorImg ) == STATUS_OK )
  76. {
  77. // convert data into OpenCV type
  78. cv::Mat cvRGBImg( oniColorImg.getHeight(), oniColorImg.getWidth(), CV_8UC3, (void*)oniColorImg.getData() );
  79. cv::cvtColor( cvRGBImg, cvBGRImg, CV_RGB2BGR );
  80. cv::imshow( "image", cvBGRImg );
  81. }
  82. if( oniDepthStream.readFrame( &oniDepthImg ) == STATUS_OK )
  83. {
  84. cv::Mat cvRawImg16U( oniDepthImg.getHeight(), oniDepthImg.getWidth(), CV_16UC1, (void*)oniDepthImg.getData() );
  85. cvRawImg16U.convertTo( cvDepthImg, CV_8U, 255.0/(oniDepthStream.getMaxPixelValue()));
  86. //【5】
  87. // convert depth image GRAY to BGR
  88. cv::cvtColor(cvDepthImg,cvFusionImg,CV_GRAY2BGR);
  89. cv::imshow( "depth", cvDepthImg );
  90. }
  91. //【6】
  92. cv::addWeighted(cvBGRImg,0.5,cvFusionImg,0.5,0,cvFusionImg);
  93. cv::imshow( "fusion", cvFusionImg );
  94. key = cv::waitKey(20);
  95. }
  96. //cv destroy
  97. cv::destroyWindow("depth");
  98. cv::destroyWindow("image");
  99. cv::destroyWindow("fusion");
  100. //OpenNI2 destroy
  101. oniDepthStream.destroy();
  102. oniColorStream.destroy();
  103. device.close();
  104. OpenNI::shutdown();
  105. return 0;
  106. }

小斤由上到下解释一把:

【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)。

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

  1. 由于找不到openni2_Kinect开发教程八:OpenNI2显示深度、彩色及融合图像

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

  2. Kinect开发教程二:OpenNI读取深度图像与彩色图像并显示

    细心的朋友肯定已经发现Kinect上长了三只眼睛,其中一个是彩色摄像头,另外两个深度摄像头,一个负责发射红外光,一个负责接收,这样,我们便能通过Kinect得到一幅彩色图像和一幅深度图像.如果大家对K ...

  3. Kinect开发教程四:用Kinect控制鼠标玩水果忍者PC版

    最近Kinect连接Xbox玩水果忍者的视频非常红火,可惜小斤只有本本和Kinect,没法玩Xbox上的体感游戏.幸运的是,寻寻觅觅后,小斤发现水果忍者有PC版本,既然上一个教程我们已经可以让Kine ...

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

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

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

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

  6. Kinect开发学习笔记之(二)Kinect开发学习资源整理

    Kinect开发学习笔记之(二)Kinect开发学习资源整理 zouxy09@qq.com http://blog.csdn.net/zouxy09 刚刚接触Kinect,在网上狂搜资料,获得了很多有 ...

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

    小斤注:关于OpenNI2.X版本的安装与开发环境配置,请参考<Kinect开发教程六:OpenNI2简介.安装与VS开发环境配置> --------------------------- ...

  8. Kinect开发学习笔记之(八)彩色、深度、骨骼和用户抠图结合

    Kinect开发学习笔记之(八)彩色.深度.骨骼和用户抠图结合 zouxy09@qq.com http://blog.csdn.net/zouxy09 我的Kinect开发平台是: Win7 x86 ...

  9. SAP UI5 应用开发教程之六十八 - 如何实现 SAP UI5 路由失败时显示自定义的 NOT Found 页面

    我们平时访问的不少网站,在浏览器地址栏故意输入一个不存在的页面地址时, 都会自动跳转到一个自定义的 NOT Found 页面,比如: 我们在本系列第 31 个步骤学习了 SAP UI5 应用的路由功能 ...

  10. Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取

    Kinect开发学习笔记之(六)带游戏者ID的深度数据的提取 zouxy09@qq.com http://blog.csdn.net/zouxy09 我的Kinect开发平台是: Win7x86 + ...

最新文章

  1. poj1129Channel Allocation
  2. mysql命令程序_MySQL命令大全经典版
  3. 解决IOS微信中 HTML5 中audio的自动播放问题。
  4. 反击CobaltStrike
  5. 基于朴素贝叶斯的垃圾邮件分类-着重理解拉普拉斯变换
  6. 无人机图像处理工具更新——多线程优化版
  7. build.gradle里test标签的实现原理
  8. 计组之中央处理器:3、数据通路(单总线结构、专用通路结构)
  9. Java校招笔试题-Java基础部分(七)
  10. 微信占用空间太大,删除又担心工作相关聊天记录,有啥好办法没?
  11. 动态修改ViewPagerIndicator CustomTabPageIndicator Tab标签文字颜色
  12. 2021最新漫画小程序源码,流量主必备。
  13. 软件测试的模式(一、)
  14. [详细]分享验证码接收平台工作原理
  15. 源码:Spark SQL 分区特性第一弹
  16. 受保护的Word文档如何编辑?
  17. 波段划分相关资料总结
  18. python中shape是什么意思_对numpy中shape的深入理解
  19. 《彻底卸载chrome及注册表清理》
  20. oracle10g rac ocssd,求教:安装oracle10g rac 报crs-0223错误问题

热门文章

  1. python怎么批量下载图片_python批量下载图片的三种方法
  2. C# Bitmap 频繁创建报错 软件闪退 内存溢出
  3. c++ const 和 define
  4. C++11强类型枚举——枚举类
  5. 元器件封装形式对照表_二三极管封装形式图表
  6. 解除主键锁_mysql 锁
  7. CACHE的一些名词术语
  8. Bit,Byte,WORD,DWORD区别和联系
  9. Tip: Unicode Debug和Debug有什么区别?
  10. linux 下查看文件修改时间