您的位置:首页 > 运维架构

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

2017-01-18 14:17 791 查看
配置好环境后,其中打开传感器等函数及类都写在 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 顯示深度影像
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  kinect sdk