java openni rgb显示_Kinect+OpenNI学习笔记之4(OpenNI获取的图像结合OpenCV显示)

前言

本文来结合下opencv的highgui功能显示kinect采集得来的颜色图和深度图。本来在opencv中自带了VideoCapture类的,使用该类可以直接驱动kinect设备,具体的可以参考下面的文章:http://blog.csdn.net/moc062066/article/details/6949910,也可以参考opencv提供的官方文档:http://docs.opencv.org/doc/user_guide/ug_highgui.html。这种方法用起来非常简单,不需要考虑OpenNI的驱动过程,有点像傻瓜式的操作。不过本人在使用该种方法时kinect一直驱动不成功,即使用opencv的VideoCapture类来捕捉Kinect设备的数据,一直是打不开的,即驱动不成功。但是kinect设备已经连接上了,且能运行openni中的sample,说明kinect的硬件驱动是没问题的,应该是opencv这个类的bug,网上很多人都碰到了该情况。

所以还是使用前面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边缘检测图。结果截图部分图如下:

44b5f916e8487616538ee923dcbc9b20.png

实验主要部分代码及注释(附录有实验工程code下载链接地址):

copenni.cpp:

#include #include#include

using namespacexn;using namespacestd;classCOpenNI

{public:~COpenNI() {

context.Release();//释放空间

}boolInitial() {//初始化

status =context.Init();if(CheckError("Context initial failed!")) {return false;

}

context.SetGlobalMirror(true);//设置镜像//产生图片node

status =image_generator.Create(context);if(CheckError("Create image generator error!")) {return false;

}//产生深度node

status =depth_generator.Create(context);if(CheckError("Create depth generator error!")) {return false;

}//视角校正

status =depth_generator.GetAlternativeViewPointCap().SetViewPoint(image_generator);if(CheckError("Can't set the alternative view point on depth generator")) {return false;

}return true;

}boolStart() {

status=context.StartGeneratingAll();if(CheckError("Start generating error!")) {return false;

}return true;

}boolUpdateData() {

status=context.WaitNoneUpdateAll();if(CheckError("Update date error!")) {return false;

}//获取数据

image_generator.GetMetaData(image_metadata);

depth_generator.GetMetaData(depth_metadata);return true;

}public:

DepthMetaData depth_metadata;

ImageMetaData image_metadata;private://该函数返回真代表出现了错误,返回假代表正确

bool CheckError(const char*error) {if(status !=XN_STATUS_OK ) {

QMessageBox::critical(NULL, error, xnGetStatusString(status));

cerr<< error << ":" << xnGetStatusString( status ) <

}return false;

}private:

XnStatus status;

Context context;

DepthGenerator depth_generator;

ImageGenerator image_generator;

};

main.cpp:

#include #include"opencv2/highgui/highgui.hpp"#include"opencv2/imgproc/imgproc.hpp"#include#include"copenni.cpp"#include

using namespacecv;using namespacexn;int main (int argc, char **argv)

{

COpenNI openni;if(!openni.Initial())return 1;

namedWindow("color image", CV_WINDOW_AUTOSIZE);

namedWindow("color edge detect", CV_WINDOW_AUTOSIZE);

namedWindow("depth image", CV_WINDOW_AUTOSIZE);

namedWindow("depth edge detect", CV_WINDOW_AUTOSIZE);if(!openni.Start())return 1;while(1) {if(!openni.UpdateData()) {return 1;

}/*获取并显示色彩图像*/Mat color_image_src(openni.image_metadata.YRes(), openni.image_metadata.XRes(),

CV_8UC3, (char *)openni.image_metadata.Data());

Mat color_image;

cvtColor(color_image_src, color_image, CV_RGB2BGR);

imshow("color image", color_image);/*对色彩图像进行canny边缘检测并显示*/Mat color_image_gray, color_image_edge;

cvtColor(color_image_src, color_image_gray, CV_RGB2GRAY);//因为在进行边缘检测的时候只能使用灰度图像

Canny(color_image_gray, color_image_edge, 5, 100);

imshow("color edge detect", color_image_edge);/*获取并显示深度图像*/Mat depth_image_src(openni.depth_metadata.YRes(), openni.depth_metadata.XRes(),

CV_16UC1, (char *)openni.depth_metadata.Data());//因为kinect获取到的深度图像实际上是无符号的16位数据

Mat depth_image, depth_image_edge;

depth_image_src.convertTo(depth_image, CV_8U,255.0/8000);

imshow("depth image", depth_image);/*计算深度图像的canny边缘并显示*/Canny(depth_image, depth_image_edge,5, 100);

imshow("depth edge detect", depth_image_edge);

waitKey(30);

}

}

总结:本实验将OpenNI驱动的Kinect数据转换成OpenCV中方便处理的格式,达到了将OpenNI和OpenCV两者相结合的目的。

参考资料:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值