当前位置 : 首页 » 文章分类 :  科研  »  OpenNI1.5获取华硕XtionProLive深度图和彩色图并用OpenCV显示

OpenNI1.5获取华硕XtionProLive深度图和彩色图并用OpenCV显示

华硕XtionPro类似Kinect,都是体感摄像机,可捕捉深度图和彩色图。
详细参数见:http://www.asus.com.cn/Multimedia/Xtion_PRO_LIVE/specifications/


实验环境

华硕XtionProLive,Win7 32位系统,VS2010,OpenCV2.4.4,OpenNI1.5.2.23


OpenNI的4中数据流异步机制

OpenNI中提供4中数据流异步机制:

  • WaitNoneUpdateAll():不等待流的更新,这样有可能读出来的和上次是同一帧
  • WaitAndUpdateAll():等待深度和彩色流都更新
  • WaitAnyUpdateAll():任意流有更新则返回
  • WaitOneUpdateAll(ProductionNode &node):等待参数指定的流更新

源码

#include <stdlib.h>
#include <iostream>
#include <string>

//OpenCV c函数头文件
#include "opencv/cv.h"
#include "opencv/highgui.h"

//OpenCV c++函数头文件
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <XnCppWrapper.h>  //OpenNI的头文件

using namespace std;
using namespace cv;
using namespace xn; // OpenNI的命名空间


int main()
{
    XnStatus result = XN_STATUS_OK;  //OpenNI函数的返回结果
    DepthMetaData depthMD; //OpenNI深度数据
    ImageMetaData imageMD; //OpenNI彩色数据

    //c版本OpenCV
    //IplImage*  imgDepth16u=cvCreateImage(cvSize(640,480),IPL_DEPTH_16U,1);
    //IplImage* imgRGB8u=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
    //IplImage*  depthShow=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
    //IplImage* imageShow=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
    //cvNamedWindow("depth",1);
    //cvNamedWindow("image",1);

    //c++版本OpenCV
    Mat cvDepthImg, cvBGRImg, cvFusionImg;
    namedWindow("depth");
    namedWindow("RGB");
    namedWindow("fusion");

    // 创建并初始化设备上下文
    Context context; 
    result = context.Init(); 
    if (XN_STATUS_OK != result)
        cerr<<"设备上下文初始化错误"<<endl;


    // 创建深度生成器和彩色生成器
    DepthGenerator depthGenerator;  
    result = depthGenerator.Create( context ); 
    if (XN_STATUS_OK != result)
        cerr<<"创建深度生成器错误"<<endl;
    ImageGenerator imageGenerator;
    result = imageGenerator.Create( context ); 
    if (XN_STATUS_OK != result)
        cerr<<"创建彩色生成器错误"<<endl;

    //通过映射模式来设置生成器参数,如分辨率、帧率
    XnMapOutputMode mapMode; 
    mapMode.nXRes = 640;  
    mapMode.nYRes = 480; 
    mapMode.nFPS = 30; 
    result = depthGenerator.SetMapOutputMode( mapMode );  
    result = imageGenerator.SetMapOutputMode( mapMode );  

    // 将深度生成器的视角对齐到彩色生成器,将深度数据配准到彩色数据
    depthGenerator.GetAlternativeViewPointCap().SetViewPoint( imageGenerator ); 
    //imageGenerator.GetAlternativeViewPointCap().SetViewPoint(depthGenerator); //彩色图配准到深度图

    // 启动所有生成器,即启动数据流
    result = context.StartGeneratingAll();  
    while( true)
    {
        // 更新数据
        result = context.WaitNoneUpdateAll(); 
        if (XN_STATUS_OK == result)
        {
            //获取一帧深度图并转换为OpenCV中的图像格式
            depthGenerator.GetMetaData(depthMD); 
            Mat cvRawImg16U(depthMD.FullYRes(), depthMD.FullXRes(), CV_16UC1, (char *)depthMD.Data() );
            cvRawImg16U.convertTo(cvDepthImg, CV_8U, 255.0/(depthMD.ZRes()));
            imshow("depth", cvDepthImg);

            //获取一帧彩色图并转换为OpenCV中的图像格式
            imageGenerator.GetMetaData(imageMD);
            Mat cvRGBImg(imageMD.FullYRes(), imageMD.FullXRes(), CV_8UC3, (char *)imageMD.Data());
            cvtColor(cvRGBImg, cvBGRImg, CV_RGB2BGR);
            imshow("RGB", cvBGRImg);

            //融合图
            cvtColor(cvDepthImg,cvFusionImg,CV_GRAY2BGR);
            addWeighted(cvBGRImg, 0.5, cvFusionImg, 0.5, 0, cvFusionImg);
            imshow("fusion", cvFusionImg);
            waitKey(30); //没有waitKey不显示图像

            // c函数形式
            //memcpy(imgDepth16u->imageData,depthMD.Data(),640*480*2);
            //cvConvertScale(imgDepth16u,depthShow,255/4096.0,0);
            //memcpy(imgRGB8u->imageData,imageMD.Data(),640*480*3);
            //cvCvtColor(imgRGB8u,imageShow,CV_RGB2BGR);
            //cvShowImage("depth", depthShow);
            //cvShowImage("image",imageShow);
        }
    }

    context.StopGeneratingAll(); //停止数据流
    context.Shutdown(); //关闭设备上下文
    destroyWindow("depth");
    destroyWindow("RGB");
    destroyWindow("fusion");

    //cvDestroyWindow("depth");
    //cvDestroyWindow("image");
    //cvReleaseImage(&imgDepth16u);
    //cvReleaseImage(&imgRGB8u);
    //cvReleaseImage(&depthShow);
    //cvReleaseImage(&imageShow);

    return 0;
}

实验结果

实验设定的深度图和彩色图大小都是640×480,规格上说彩色图支持更大分辨率,实测如果将彩色图设定为更大分辨率则会自动改为320×240


彩色图


未配准时的深度图


配准到彩色图后的深度图


深度图配准到彩色图后的1:1融合图


彩色图配准到深度图后的1:1融合图

相关资源

源码下载:
http://download.csdn.net/detail/masikkk/7581283

OpenNI1.5 + NITE + Sensor下载:
http://download.csdn.net/detail/masikkk/7581339


参考


上一篇 OpenNI2获取华硕XtionProLive深度图和彩色图并用OpenCV显示

下一篇 关于DPM(Deformable Part Model)算法中模型可视化的解释

域名迁移公告
2017年12月20日起,本博客迁移到新域名madaimeng.com,旧域名masikkk.com不再更新内容,但将永久保持可访问!
阅读
899
阅读预计4分钟
创建日期 2014-07-01
修改日期 2017-06-21
类别
百度推荐