opencv读取kinect图像获取的RGB-D图像是什么图像?

HighGUI & OpenCV 2.3.2 documentation
Navigation
使用Kinect传感器
类 VideoCapture 支持Kinect传感器。使用 VideoCapture 里的接口,可以从Kinect获取深度图,RGB图像和其他格式的输出。
为了在OpenCV中使用Kinect,你需要遵循如下主要步骤。
安装OpenNI库 (从此处获取 ) 以及 PrimeSensor Module for OpenNI (从此处获取
)。使用它们的缺省安装目录安装则可。安装目录如下:
Linux & MacOSX:
Libs into: /usr/lib
Includes into: /usr/include/ni
Libs into: c:/Program Files/OpenNI/Lib
Includes into: c:/Program Files/OpenNI/Include
PrimeSensor Module:
Linux & MacOSX:
Bins into: /usr/bin
Bins into: c:/Program Files/Prime Sense/Sensor/Bin
如果其中一个或者多个被安装到其他目录,你应该修改与之对应的CMake变量 OPENNI_LIB_DIR , OPENNI_INCLUDE_DIR 或/和 OPENNI_PRIME_SENSOR_MODULE_BIN_DIR 。
通过CMake中的 WITH_OPENNI 标志配置OpenCV的OpenNI支持。无论发现PrimeSensor模块与否(检查CMake log中的 OpenNI PrimeSensor Modules 状态),如果在安装目录中发现了OpenNI(检查CMake log中的 OpenNI 状态),OpenCV都将会使用OpenNI编译。没有PrimeSensor模块,OpenCV也可成功地与OpenNI编译,但是 VideoCapture 对象无法从Kinect传感器中抓取数据。
编译OpenCV。
VideoCapture 可以获取如下Kinect数据:
来自深度传感器的数据:
OPENNI_DEPTH_MAP
- 以毫米为单位的深度值 (CV_16UC1)
OPENNI_POINT_CLOUD_MAP
- 以米为单位的XYZ点云 (CV_32FC3)
OPENNI_DISPARITY_MAP
- 以像素为单位的视差 (CV_8UC1)
OPENNI_DISPARITY_MAP_32F
- 以像素为单位的视差 (CV_32FC1)
OPENNI_VALID_DEPTH_MASK
- 有效像素标志 (非遮挡,非影子区等) (CV_8UC1)
来自RGB图像传感器的数据:
OPENNI_BGR_IMAGE
- 彩色图像 (CV_8UC3)
OPENNI_GRAY_IMAGE
- 灰度图像 (CV_8UC1)
为了从Kinect获取深度图,请使用 VideoCapture::operator &&, 例如
VideoCapture capture( CV_CAP_OPENNI );
Mat depthMap;
capture && depthMap;
if( waitKey( 30 ) &= 0 )
如果获取多个Kinect数据,请使用 VideoCapture::grab 和 VideoCapture::retrieve, 例如
VideoCapture capture(0); // or CV_CAP_OPENNI
Mat depthMap;
Mat rgbImage
capture.grab();
capture.retrieve( depthMap, OPENNI_DEPTH_MAP );
capture.retrieve( bgrImage, OPENNI_BGR_IMAGE );
if( waitKey( 30 ) &= 0 )
设置或者获取Kinect数据属性,请分别使用 VideoCapture::set 和 VideoCapture::get 。例如
VideoCapture capture( CV_CAP_OPENNI );
capture.set( CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, CV_CAP_OPENNI_VGA_30HZ );
cout && &FPS
& && capture.get( CV_CAP_OPENNI_IMAGE_GENERATOR+CV_CAP_PROP_FPS ) && endl;
既然Kinect有两个数据传感器(图像传感器和深度传感器),因此有两个标志用来设置/获取指定传感器的属性:
CV_CAP_OPENNI_IMAGE_GENERATOR – 读写图像传感器属性的标志。
CV_CAP_OPENNI_DEPTH_GENERATOR – 读写深度传感器属性的标志。此标志为默认值,如果这两个标志都没有设置,则为此标志。
当读写特定传感器属性时,必须用此标志指定传感器。如下属性可透过OpenNI接口支持:
图像传感器:
CV_CAP_PROP_OPENNI_OUTPUT_MODE – 支持两种模式:缺省的 CV_CAP_OPENNI_VGA_30HZ (图像传感器以30FPS速度返回VGA分辨率的图像) 或者 CV_CAP_OPENNI_SXGA_15HZ (图像传感器以15FPS速度返回SXGA分辨率的图像);深度传感器一直是VGA分辨率。
深度传感器:
CV_CAP_PROP_OPENNI_REGISTRATION – 此标志用来校准深度图,通过改变深度传感器的视点到图像传感器,这样两图中同一位置的像素表示同一物体(需将此标志设置为 &on&); 或者设置深度传感器的视点为其本来的视点(需将此标志设置为 &off&).
下面的属性仅可读取:
CV_CAP_PROP_OPENNI_FRAME_MAX_DEPTH – Kinect支持的最大距离,以毫米为单位。
CV_CAP_PROP_OPENNI_BASELINE – Baseline值,以毫米为单位。
CV_CAP_PROP_OPENNI_FOCAL_LENGTH – 焦距,以像素为单位。
CV_CAP_PROP_FRAME_WIDTH – 帧的宽度,以像素为单位。
CV_CAP_PROP_FRAME_HEIGHT – 帧的高度,以像素为单位。
CV_CAP_PROP_FPS – 帧率,以FPS为单位。
一些”generator type + property”被定以为一个标志:
CV_CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE = CV_CAP_OPENNI_IMAGE_GENERATOR + CV_CAP_PROP_OPENNI_OUTPUT_MODE
CV_CAP_OPENNI_DEPTH_GENERATOR_BASELINE = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_BASELINE
CV_CAP_OPENNI_DEPTH_GENERATOR_FOCAL_LENGTH = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_FOCAL_LENGTH
CV_CAP_OPENNI_DEPTH_GENERATOR_REGISTRATION_ON = CV_CAP_OPENNI_DEPTH_GENERATOR + CV_CAP_PROP_OPENNI_REGISTRATION_ON
更多信息,请参考 opencv/samples/cpp 目录中的Kinect例子 kinect_maps.cpp 。
Help and Feedback
You did not find what you were looking for?
Ask a question in the .
If you think something is missing or wrong in the documentation,
please file a .
NavigationKinect+OpenNI学习笔记之2(获取kinect的颜色图像和深度图像) - 推酷
Kinect+OpenNI学习笔记之2(获取kinect的颜色图像和深度图像)
网上有不少使用Qt做界面,OpenNI为库来开发kinect。或许大家的第一个问题就是询问该怎样使用Kinect来获取颜色信息图和深度信息图呢?这一节就是简单来回答这个问题的。
开发环境:QtCreator2.5.1+OpenNI1.5.4.0+Qt4.8.2
实验说明:
在使用OpenNI来驱动读取kinect数据时,我们需要了解context object这个名词。查看了下OpenNI UserGuide文档,简单翻译下这个名词的意思:
Context是openNI中一个主要的object,它掌握了OpenNI使用过程中应用程序的全部状态,以及这些状态的prodection chains,一个应用程序有多个context,但是这些context之间不能共享信息。例如一个中间件节点不能使用另一个context的驱动节点。Context在使用前必须被立即初始化,因此此时所有嵌入的模块被下载和分析。为了释放context的内存,应用程序需调用shutdown程序。&&&&&
虽然翻译得不准确,但是它的大概意思就是告诉我们在驱动kinect时,需要用到context这个类,且我们需要安装一定顺序去使用,这与一些常见的库驱动差不多,比如opengl,这些都需要什么初始化啊,设置属性啊等。因此我们只需要直接去看懂他人的一个工程实例就ok了。
好了,本文参考Heresy的教程中的源码写的。
在新建好工程文件后,需要包含XnCppWrapper头文件,且需在Qt工程中设置好头文件目录和库文件目录。
使用OpenNI读取颜色图和深度图的步骤如下(这个是程序的核心部分):
1. 定义一个Context对象,并 调用该对象的Init()方法来进行初始化。
2. 定义一个XnMapOutputMode格式对象,设置好分图像分辨率和帧率。
3. 定义颜色图和深度图的节点对象,并用其Create()方法来创建,参数为Context对象.
4. 设置颜色和深度图的输出模式,调用的方法是SetMapOutputMode();参数为步骤2中定义和设置好了的XnMapOutputMode对象。
6. 如果深度图和颜色图在一张图上显示,则必须对深度图像进行校正,校正的方法是调用深度图的如下方法:.GetAlternativeViewPointCap().SetViewPoint();
7. 调用context对象的StartGeneratingAll()来开启设备读取数据开关。
8. 调用context对象的更新数据方法,比如WaitAndupdateAll()方法。
9. 定义颜色图和色彩图的ImageMetaData对象,并利用对应的节点对象的方法GetMetaData(),将获取到的数据保存到对应的ImageMetaData对象中。
10. 如果需要将深度图转换成灰度图来显示,则需要自己将深度值转换成0~255的单通道或者多通道数据,然后直接用来显示。
注意如果没有设置视觉校正,则深度图的显示与颜色图的显示会出现对应不上的情况,后面的实验可以看出这2者的区别,另外对于是否需要设置镜像就要看自己的具体应用场合了。
实验结果:
下面分别分是否设置图像镜像,是否对深度图像进行校正来给出实验结果.
无镜像无校正:
无镜像有校正:
有镜像无校正:
有镜像有校正:
从有无镜像可以看出,设置镜像的效果与字面的理解是一样的,即有镜像时就相当于取镜子中的图像。有无校正可以看出,没有校正时,深度图片和颜色图片同一个物体都对应不起来,可以看下天花板上的吊灯就可以发现,没校正,2者不重合,且相差不少。有校正时效果就好多了,只是此时的深度图像显示的范围要稍小些。
实验主要部分代码及注释(附录有工程code下载链接):
首先来个最小工程,即去掉那些错误处理代码:
#include &QtGui&
#include &XnCppWrapper.h& //包含OpenNI的头文件
//使用OpenNI库中的命名空间
//全局的OpenNI object
Context g_
ImageGenerator g_image_
DepthGenerator g_depth_
//全局的Qt Object
QGraphicsPixmapItem *g_image_
QGraphicsPixmapItem *g_depth_
//CTimer类的定义
class CTimer : public QObject
void start() {
g_context.StartGeneratingAll();//开启设备读取数据的开关
startTimer(33);//使用startTimer()启动定时器,每当时间到时会自动调用timerEvent()函数
void timerEvent(QTimerEvent *) {
g_context.WaitAndUpdateAll();//更新数据
//颜色数据
ImageMetaData image_
g_image_generator.GetMetaData(image_map);
//为g_image_map设置图片,图片的数据来源于外部硬件设备
g_image_map-&setPixmap(QPixmap::fromImage(QImage(image_map.Data(), image_map.XRes(),
image_map.YRes(), QImage::Format_RGB888)));
//深度数据
DepthMetaData depth_
g_depth_generator.GetMetaData(depth_map);
XnDepthPixel max_depth_value = depth_map.ZRes();
QImage depth_img(depth_map.XRes(), depth_map.YRes(), QImage::Format_ARGB32);//格式为ARGB32型的
for(unsigned int i = 0; i & depth_map.XRes(); i++)
for(unsigned int j = 0; j & depth_map.YRes(); j++)
XnDepthPixel depth_value_ij = depth_map(i, j);//获取x,y处的坐标值
if(depth_value_ij == 0) {
depth_img.setPixel(i, j, qRgba(0, 0, 0, 0));
}//如果捕捉不到深度信息,则将其设置为0
float fscale = 1.0f*depth_value_ij/max_depth_//当前深度的比例因子
depth_img.setPixel(i, j, qRgba(255*(1-fscale), 0, 255*fscale, 255*(1-fscale)));
g_depth_map-&setPixmap(QPixmap::fromImage(depth_img));
main(int argc, char **argv)
QApplication app(argc, argv);
g_context.Init();//context初始化
g_context.SetGlobalMirror(true);//设置全局镜像,就像照镜子一样,与设置为false时的2张图片镜像
XnMapOutputM//定义图像的输出模式
xmode.nXRes = 640;//x方向分辨率
xmode.nYRes = 480;//y方向分辨率
xmode.nFPS = 30;//帧率
//设置颜色节点属性
g_image_generator.Create(g_context);
g_image_generator.SetMapOutputMode(xmode);
//设置深度节点属性
g_depth_generator.Create(g_context);
g_depth_generator.SetMapOutputMode(xmode);
//视觉校正,否则深度图和颜色图感应到的区域不能一一对应
g_depth_generator.GetAlternativeViewPointCap().SetViewPoint(g_image_generator);
//Qt场景设置
QGraphicsS
g_image_map = scene.addPixmap(QPixmap());
g_image_map-&setZValue(1);//设置为z方向上的第1层
g_depth_map = scene.addPixmap(QPixmap());
g_depth_map-&setZValue(2);//设置为z方向上的第2层
//Qt视图创建
QGraphicsView view(&scene);
view.resize(660, 500);
//设置定时器,每隔一段时间读取kinect的颜色信息和深度信息
timer.start();
view.show();
return app.exec();
加入错误处理部分后的完整main.cpp:
#include &QtGui&
#include &XnCppWrapper.h& //包含OpenNI的头文件
//使用OpenNI库中的命名空间
//全局的OpenNI object
XnStatus g_
Context g_
ImageGenerator g_image_
DepthGenerator g_depth_
bool g_has_image_generator =
//全局的Qt Object
QGraphicsPixmapItem *g_image_
QGraphicsPixmapItem *g_depth_
//CTimer类的定义
class CTimer : public QObject
void start() {
g_status = g_context.StartGeneratingAll();//开启设备读取数据的开关
if(g_status == XN_STATUS_OK) {
startTimer(33);//使用startTimer()启动定时器,每当时间到时会自动调用timerEvent()函数
QMessageBox::critical(NULL, &Create Data Error!&, xnGetStatusString(g_status));//显示创建数据失败,该消息框没有父窗口
void timerEvent(QTimerEvent *) {
g_context.WaitAndUpdateAll();//更新数据
//颜色数据
if(g_has_image_generator) {
ImageMetaData image_
g_image_generator.GetMetaData(image_map);
//为g_image_map设置图片,图片的数据来源于外部硬件设备
g_image_map-&setPixmap(QPixmap::fromImage(QImage(image_map.Data(), image_map.XRes(),
image_map.YRes(), QImage::Format_RGB888)));
//深度数据
DepthMetaData depth_
g_depth_generator.GetMetaData(depth_map);
XnDepthPixel max_depth_value = depth_map.ZRes();
QImage depth_img(depth_map.XRes(), depth_map.YRes(), QImage::Format_ARGB32);//格式为ARGB32型的
for(unsigned int i = 0; i & depth_map.XRes(); i++)
for(unsigned int j = 0; j & depth_map.YRes(); j++)
XnDepthPixel depth_value_ij = depth_map(i, j);//获取x,y处的坐标值
if(depth_value_ij == 0) {
depth_img.setPixel(i, j, qRgba(0, 0, 0, 0));
}//如果捕捉不到深度信息,则将其设置为0
float fscale = 1.0f*depth_value_ij/max_depth_//当前深度的比例因子
depth_img.setPixel(i, j, qRgba(255*(1-fscale), 0, 255*fscale, 255*(1-fscale)));
g_depth_map-&setPixmap(QPixmap::fromImage(depth_img));
main(int argc, char **argv)
QApplication app(argc, argv);
g_status = g_context.Init();//context初始化
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, &Context Initial Error!&, xnGetStatusString(g_status));
return -1;
// g_context.SetGlobalMirror(true);//设置全局镜像,就像照镜子一样,与设置为false时的2张图片镜像
XnMapOutputM//定义图像的输出模式
xmode.nXRes = 640;//x方向分辨率
xmode.nYRes = 480;//y方向分辨率
xmode.nFPS = 30;//帧率
//设置颜色节点属性
g_status = g_image_generator.Create(g_context);
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, &Image map create failed&, xnGetStatusString(g_status));
g_has_image_generator =
if( g_has_image_generator ) {
g_status = g_image_generator.SetMapOutputMode(xmode);
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, &Image map output mode error!&, xnGetStatusString(g_status));
return -1;
//设置深度节点属性
g_status = g_depth_generator.Create(g_context);
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, &Depth map create failed&, xnGetStatusString(g_status));
return -1;
g_status = g_depth_generator.SetMapOutputMode(xmode);
if(g_status != XN_STATUS_OK) {
QMessageBox::critical(NULL, &Depth map output mode error!&, xnGetStatusString(g_status));
return -1;
if(g_has_image_generator)//视觉校正,否则深度图和颜色图感应到的区域不能一一对应
//g_depth_generator.GetAlternativeViewPointCap().SetViewPoint(g_image_generator);
//Qt场景设置
QGraphicsS
g_image_map = scene.addPixmap(QPixmap());
g_image_map-&setZValue(1);//设置为z方向上的第1层
g_depth_map = scene.addPixmap(QPixmap());
g_depth_map-&setZValue(2);//设置为z方向上的第2层
//Qt视图创建
QGraphicsView view(&scene);
view.resize(660, 500);
//设置定时器,每隔一段时间读取kinect的颜色信息和深度信息
timer.start();
view.show();
return app.exec();
通过本次实验,了解了怎样使用OpenNI来显示kinect的颜色图像和深度图像了。
参考资料:
作者:tornadomeet 出处:/tornadomeet 欢迎转载或分享,但请务必声明文章出处。
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
没有分页内容
图片无法显示
视频无法显示
与原文不一致}

我要回帖

更多关于 rgb d 图像 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信