2 kinect for windows(k4w) sdk之提取深度图像并利用opencv显示

配置好环境后,其中打开传感器等函数及类都写在 Kinect.h里面,这个可以在c://program//microsoft sdk//kinect里面找到,接下来我们就可以利用它来编程开发了。
其中的配置可以参考这个:
opencv配置
kinect开发环境配置

一 提取深度图像流程

1 打开传感器
2 获取图像的帧源
3 从帧源打开帧读取器
4 循环从帧读取器中读取深度图像的buffer,这个buffer包含每个点的深度信息,并且是一维的,范围微软建议是500到4500,但实际可能更大。
5 将buffer中的内容写入opencv的Mat格式的图片文件中,就可以用imshow来显示这个深度图像了,但是要把深度图像从500~4500转到0~255来显示。

二 代码:

// Standard Library
#include <iostream>
// OpenCV Header
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
// Kinect for Windows SDK Header
#include <Kinect.h>
using namespace std;
int main(int argc, char** argv)
{
    // 1a. Get default Sensor
    IKinectSensor* pSensor = nullptr;
    GetDefaultKinectSensor(&pSensor);
    // 1b. Open sensor
    pSensor->Open();
    // 2a. Get frame source
    IDepthFrameSource* pFrameSource = nullptr;
    pSensor->get_DepthFrameSource(&pFrameSource);
    // 2b. Get frame description
    int        iWidth = 0;
    int        iHeight = 0;
    IFrameDescription* pFrameDescription = nullptr;
    pFrameSource->get_FrameDescription(&pFrameDescription);
    pFrameDescription->get_Width(&iWidth);
    pFrameDescription->get_Height(&iHeight);
    pFrameDescription->Release();
    pFrameDescription = nullptr;
    // 2c. get some dpeth only meta
    UINT16 uDepthMin = 0, uDepthMax = 0;
    pFrameSource->get_DepthMinReliableDistance(&uDepthMin);
    pFrameSource->get_DepthMaxReliableDistance(&uDepthMax);
    cout << "Reliable Distance: " 
         << uDepthMin << " – " << uDepthMax << endl;
    // perpare OpenCV
    //cv::Mat mDepthImg(iHeight, iWidth, CV_16UC1);
    cv::Mat mImg8bit(iHeight, iWidth, CV_8UC1);
    cv::namedWindow( "Depth Map" );
    // 3a. get frame reader
    IDepthFrameReader* pFrameReader = nullptr;
    pFrameSource->OpenReader(&pFrameReader);
    // Enter main loop
    while (true)
    {
        // 4a. Get last frame
        IDepthFrame* pFrame = nullptr;
        if (pFrameReader->AcquireLatestFrame(&pFrame) == S_OK)
        {
            // 4c. read buffer and store it in mDepthImg
            UINT    uBufferSize = 0;
            UINT16*    pBuffer = nullptr;
            pFrame->AccessUnderlyingBuffer(&uBufferSize, &pBuffer);
            cv::Mat mDepthImg(iHeight, iWidth, CV_16UC1, pBuffer);//这个是不是要改下,回去再试试
            // 4d. convert from 16bit to 8bit
            mDepthImg.convertTo(mImg8bit, CV_8U, 255.0f / uDepthMax);
            cv::imshow("Depth Map", mImg8bit);
            // 4e. release frame
            pFrame->Release();
        }
        // 4f. check keyboard input
        if (cv::waitKey(30) == VK_ESCAPE){
            break;
        }
    }
    // 3b. release frame reader
    pFrameReader->Release();
    pFrameReader = nullptr;
    // 2d. release Frame source
    pFrameSource->Release();
    pFrameSource = nullptr;
    // 1c. Close Sensor
    pSensor->Close();
    // 1d. Release Sensor
    pSensor->Release();
    pSensor = nullptr;
    return 0;
}

其中opencv Mat数据类型及位数可以参考这个:
OpenCV Mat数据类型及位数总结

三 函数接口介绍

1 传感器
IKinectSensor

通过GetDefaultKinectSensor()来获取
接着要打开它

下面是IKinectSensor这个类的一些接口interface:

IKinectSensor (對應到感應器)
  get_DepthFrameSource() -> IDepthFrameSource (深度影像來源)
  get_ColorFrameSource() -> IColorFrameSource (彩色影像來源)
  get_InfraredFrameSource() -> IInfraredFrameSource (紅外線影像來源)
  get_LongExposureInfraredFrameSource() -> ILongExposureInfraredFrameSource (長時間曝光紅外線影像來源)
  get_AudioSource() -> IAudioSource (聲音的來源)
  get_BodyFrameSource() -> IBodyFrameSource (人體骨架資訊的來源)
  get_BodyIndexFrameSource() -> IBodyIndexFrameSource (人體在深度影像所佔位置的資料來源)
  OpenMultiSourceFrameReader() -> IMultiSourceFrameReader (多來源讀取器)
  get_CoordinateMapper() -> ICoordinateMapper (座標系統轉換)
2 深度图像来源
IDepthFrameSource

可以通过上述IKinectSensor这个类来取得

3 深度图像读取器
IDepthFrameReader

通过IDepthFrameSource得到

4 取得深度图像
IDepthFrame

通过IDepthFrameReader的AcquireLatestFrame得到,但是AcquireLatestFrame不一定会成功,所以一定要做状态检查。

5 得到深度图像的buffer
UINT    uBufferSize = 0;
UINT16*    pBuffer = nullptr;
pFrame->AccessUnderlyingBuffer(&uBufferSize, &pBuffer);
cv::Mat mDepthImg(iHeight, iWidth, CV_16UC1, pBuffer);

这个buffer是一维的,假如要读取坐标为(x,y)的深度图像的值,那么应该为pBuffer[x+y*iWidth]。
这样就可以用opencv的imshow来显示深度图像啦~
参考:K4W v2 C++ Part 2:使用 OpenCV 顯示深度影像

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值