Kinect For Windows V2开发日志四:使用OpenCV显示深度图像

代码示例:

#include <Kinect.h>
#include <iostream>
#include <opencv2\highgui.hpp>

using   namespace   std;
using   namespace   cv;
int main(void)
{
    IKinectSensor   * mySensor = nullptr;
    GetDefaultKinectSensor(&mySensor);  //获取感应器
    mySensor->Open();           //打开感应器

    IDepthFrameSource   * mySource = nullptr;   //取得深度数据
    mySensor->get_DepthFrameSource(&mySource);

    int height = 0, width = 0;
    IFrameDescription   * myDescription = nullptr;  //取得深度数据的分辨率
    mySource->get_FrameDescription(&myDescription);
    myDescription->get_Height(&height);
    myDescription->get_Width(&width);
    myDescription->Release();

    IDepthFrameReader   * myReader = nullptr;       
    mySource->OpenReader(&myReader);    //打开深度数据的Reader

    IDepthFrame * myFrame = nullptr;
    Mat temp(height,width,CV_16UC1);    //建立图像矩阵
    Mat img(height,width,CV_8UC1);
    while (1)
    {
        if (myReader->AcquireLatestFrame(&myFrame) == S_OK) //通过Reader尝试获取最新的一帧深度数据,放入深度帧中,并判断是否成功获取
        {
            myFrame->CopyFrameDataToArray(height * width, (UINT16 *)temp.data); //先把数据存入16位的图像矩阵中
            temp.convertTo(img,CV_8UC1,255.0 / 4500);   //再把16位转换为8位
            imshow("TEST", img);
            myFrame->Release();
        }
        if (waitKey(30) == VK_ESCAPE)
            break;
    }
    myReader->Release();        //释放不用的变量并且关闭感应器
    mySource->Release();
    mySensor->Close();
    mySensor->Release();

    return  0;
}

详细解释

为了简便起见,此段代码同样略掉了大部分错误检测。不难看出此段代码于上一篇非常相似,主要区别在循环里。

首先,声明了两个矩阵,一个为16位单通道,一个为8位单通道,之所以开16位的,是因为在Kinect的基本参数这篇里可以看到,深度数据是16位的。开8位的原因等下说。然后同样的,利用AcquireLatestFrame()来获取最新的一帧,不同的是下面一句,不再用AccessUnderlyingBuffer(),而是用CopyFrameDataToArray来把数据复制到openCV的图像矩阵Mat里,注意第三个参数的类型是UINT16*,所以需要强制转换一下。接下来要把16位的Mat转换成8位来输出显示,为什么不直接用16位?其实也可以用,但是直接用16位的话显示的图像很接接近于全黑,不方便观察,于是转换为8位。convertTo()这个函数的第一个参数是输出矩阵,第二个是转换的类型,第三个是缩放因子,其中4500是深度数据的最大距离。

最后,输出的图像应该像这样:
Kinect For Windows V2开发日志四:使用OpenCV显示深度图像_第1张图片


你可能感兴趣的:(Kinect For Windows V2开发日志四:使用OpenCV显示深度图像)