Kinect OpenNI学习笔记之4OpenNI获取的图像结合OpenCV显示.docx
《Kinect OpenNI学习笔记之4OpenNI获取的图像结合OpenCV显示.docx》由会员分享,可在线阅读,更多相关《Kinect OpenNI学习笔记之4OpenNI获取的图像结合OpenCV显示.docx(7页珍藏版)》请在冰豆网上搜索。
KinectOpenNI学习笔记之4OpenNI获取的图像结合OpenCV显示
KinectOpenNI学习笔记之4(OpenNI获取的图像结合OpenCV显示)
前言
本文来结合下opencv的highgui功能显示kinect采集得来的颜色图和深度图。
本来在opencv中自带了VideoCapture类的,使用该类可以直接驱动kinect设备,具体的可以参考下面的文章:
所以还是使用前面2篇博文介绍的,自己用OpenNI写驱动,这样可以更深刻的对OpenNI这个库灵活运用。
开发环境:
QtCreator2.5.1+OpenNI1.5.4.0+Qt4.8.2+OpenCV2.4.2
实验说明
在用OpenCV显示OpenNI的数据时,先来了解下Kinect获取到的深度信息的一些特点,Heresy的文章:
Kinect+OpenNI的深度值介绍得比较通俗易懂。
下面是个人觉得kinect深度信息比较重要的地方:
Kinect官方推荐的使用距离为1.2m到3.6m之间。
其中1.2m时的精度为3mm,3.2米的时候精度越为3cm。
随着距离越来越远,其检测到的精度也越来越小。
精度最小为1mm,大概是距离50cm时,不过此时的点数量比较少,也不稳定,因此官方没有推荐使用这个时候的距离。
另外还需要注意OpenNI中表示深度像素的格式为XnDepthPixel,实际上是单一channel的16位正整数,因此如果使用OpenCV来存储时,需要设定格式为CV_16UC1。
因此其范围是0~65536,不过期最大的深度只能感应到10000,所以我们需要将其归一化到一个比较好的范围内。
本文使用的是上一篇博文:
Kinect+OpenNI学习笔记之3(获取kinect的数据并在Qt中显示的类的设计)中用到的类COpenNI,该类可以方便的驱动kinect,并将获得的色彩信息和深度信息保存在共有变量中,提供其对象来调用。
主函数中使用OpenCV库来创建窗口,且将Kinect获到的数据转换成OpenCV的格式,然后在创建的窗口中显示。
同时也对深度图像和颜色图像进行了canny边缘检测并显示出来比较。
实验结果
本实验显示4幅图像,分别为颜色原图及其canny边缘检测图,深度原图及其canny边缘检测图。
结果截图部分图如下:
实验主要部分代码及注释(附录有实验工程code下载链接地址):
copenni.cpp:
#include<XnCppWrapper.h>
#include<QtGui/QtGui>
#include<iostream>usingnamespacexn;
usingnamespacestd;classCOpenNI
{
public:
~COpenNI(){
context.Release();//释放空间
}
boolInitial(){
//初始化
status=context.Init();
if(CheckError("Contextinitialfailed!
")){
returnfalse;
}
context.SetGlobalMirror(true);//设置镜像
//产生图片node
status=image_generator.Create(context);
if(CheckError("Createimagegeneratorerror!
")){
returnfalse;
}
//产生深度node
status=depth_generator.Create(context);
if(CheckError("Createdepthgeneratorerror!
")){
returnfalse;
}
//视角校正
status=depth_generator.GetAlternativeViewPointCap().SetViewPoint(image_generator);
if(CheckError("Can'tsetthealternativeviewpointondepthgenerator")){
returnfalse;
}returntrue;}boolStart(){
status=context.StartGeneratingAll();
if(CheckError("Startgeneratingerror!
")){
returnfalse;
}
returntrue;
}boolUpdateData(){
status=context.WaitNoneUpdateAll();
if(CheckError("Updatedateerror!
")){
returnfalse;
}
//获取数据
image_generator.GetMetaData(image_metadata);
depth_generator.GetMetaData(depth_metadata);returntrue;
}public:
DepthMetaDatadepth_metadata;
ImageMetaDataimage_metadata;private:
//该函数返回真代表出现了错误,返回假代表正确
boolCheckError(constchar*error){
if(status!
=XN_STATUS_OK){
QMessageBox:
:
critical(NULL,error,xnGetStatusString(status));
cerr<<error<<":
"<<xnGetStatusString(status)<<endl;
returntrue;
}
returnfalse;
}private:
XnStatusstatus;
Contextcontext;
DepthGeneratordepth_generator;
ImageGeneratorimage_generator;
};
main.cpp:
#include<QCoreApplication>#include"opencv2/highgui/highgui.hpp"
#include"opencv2/imgproc/imgproc.hpp"
#include<opencv2/core/core.hpp>
#include"copenni.cpp"#include<iostream>usingnamespacecv;
usingnamespacexn;intmain(intargc,char**argv)
{
COpenNIopenni;
if(!
openni.Initial())
return1;namedWindow("colorimage",CV_WINDOW_AUTOSIZE);
namedWindow("coloredgedetect",CV_WINDOW_AUTOSIZE);
namedWindow("depthimage",CV_WINDOW_AUTOSIZE);
namedWindow("depthedgedetect",CV_WINDOW_AUTOSIZE);if(!
openni.Start())
return1;
while
(1){
if(!
openni.UpdateData()){
return1;
}
/*获取并显示色彩图像*/
Matcolor_image_src(openni.image_metadata.YRes(),openni.image_metadata.XRes(),
CV_8UC3,(char*)openni.image_metadata.Data());
Matcolor_image;
cvtColor(color_image_src,color_image,CV_RGB2BGR);
imshow("colorimage",color_image);/*对色彩图像进行canny边缘检测并显示*/
Matcolor_image_gray,color_image_edge;
cvtColor(color_image_src,color_image_gray,CV_RGB2GRAY);//因为在进行边缘检测的时候只能使用灰度图像
Canny(color_image_gray,color_image_edge,5,100);
imshow("coloredgedetect",color_image_edge);/*获取并显示深度图像*/
Matdepth_image_src(openni.depth_metadata.YRes(),openni.depth_metadata.XRes(),
CV_16UC1,(char*)openni.depth_metadata.Data());//因为kinect获取到的深度图像实际上是无符号的16位数据
Matdepth_image,depth_image_edge;
depth_image_src.convertTo(depth_image,CV_8U,255.0/8000);
imshow("depthimage",depth_image);/*计算深度图像的canny边缘并显示*/
Canny(depth_image,depth_image_edge,5,100);
imshow("depthedgedetect",depth_image_edge);
waitKey(30);}}
总结:
本实验将OpenNI驱动的Kinect数据转换成OpenCV中方便处理的格式,达到了将OpenNI和OpenCV两者相结合的目的。
参考资料:
Kinect+OpenNI学习笔记之3(获取kinect的数据并在Qt中显示的类的设计)
opencv2.3读取kinect深度信息和彩色图像
Kinect+OpenNI的深度值
OpenNI+OpenCV
附录:
实验工程code下载。
作者:
tornadomeet
出处:
欢迎转载或分享,但请务必声明文章出处。