windows10环境下使用Kinect2.0获取RGB-D图片
Author:yooongchun
, Email:yooongchun@foxmail.com
摘要:这篇文章介绍如何在Windows10环境下使用C++程序驱动Kinect2.0获取RGB-D图片
STEP 1 :安装Kinect2.0 SDK
Kinect2.0设备需要使用usb3.0接口,所以,首先要保证你接入的接口一定是USB3.0!
接下来,在官网上下载Kinect2.0的SDK :
https://www.microsoft.com/en-hk/download/confirmation.aspx?id=44561
下载之后安装,安装完成后会有一个
Kinect2.0 SDK
和一个Kinect2.0 Studio
将Kinect2.0设备连接到电脑上,然后打开Kinect2.0 Studio,这时可看到Kinect2.0摄像头的实时镜头照片,表示Kinect2.0安装完成。
STEP 2 :获取RGB-D图像
Kinect2.0 Studio能看到实时的图像,但是没法保存下来,要保存Kinect2.0的照片需要我们调用其SDK来编程获得。
我们这里使用VS2013+Kinect2.0 SDK 环境来编写代码。
- 配置Kinect2.0 SDK的开发环境
安装好Kinect2.0 SDK之后要在VS2013工程环境中使用还需要配置。
- 新建一个x86的VS2013的工程,注意,楼主这里使用x64 工程时Kinect2.0 SDK出错,因而建议使用x86工程
配置工程:
- 在
包含目录
下添加:***Microsoft SDKsKinectv2.0_1409inc
,这里*代表你的实际安装地址 - 在
库目录
下添加***Microsoft SDKsKinectv2.0_1409Libx86
- 在
附加依赖项
里添加kinect20.lib
- 在
编写代码获取Kinect2.0设备的图像
#include <kinect.h> #include <iostream> #include <opencv2opencv.hpp> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> using namespace cv; using namespace std; // 安全释放指针 template<class Interface> inline void SafeRelease(Interface *& pInterfaceToRelease) { if (pInterfaceToRelease != NULL) { pInterfaceToRelease->Release(); pInterfaceToRelease = NULL; } } int GetPicture() { // 获取Kinect设备 IKinectSensor* m_pKinectSensor; HRESULT hr; hr = GetDefaultKinectSensor(&m_pKinectSensor); if (FAILED(hr)) { return hr; } IMultiSourceFrameReader* m_pMultiFrameReader; if (m_pKinectSensor) { hr = m_pKinectSensor->Open(); if (SUCCEEDED(hr)) { // 获取多数据源到读取器 hr = m_pKinectSensor->OpenMultiSourceFrameReader( FrameSourceTypes::FrameSourceTypes_Color | FrameSourceTypes::FrameSourceTypes_Infrared | FrameSourceTypes::FrameSourceTypes_Depth, &m_pMultiFrameReader); } } if (!m_pKinectSensor || FAILED(hr)) { return E_FAIL; } // 三个数据帧及引用 IDepthFrameReference* m_pDepthFrameReference; IColorFrameReference* m_pColorFrameReference; IInfraredFrameReference* m_pInfraredFrameReference; IInfraredFrame* m_pInfraredFrame; IDepthFrame* m_pDepthFrame; IColorFrame* m_pColorFrame; // 三个图片格式 Mat i_rgb(1080, 1920, CV_8UC4); //注意:这里必须为4通道的图,Kinect的数据只能以Bgra格式传出 Mat i_depth(424, 512, CV_8UC1); Mat i_ir(424, 512, CV_16UC1); UINT16 *depthData = new UINT16[424 * 512]; IMultiSourceFrame* m_pMultiFrame = nullptr; int sample_id = 1; while (true) { // 获取新的一个多源数据帧 hr = m_pMultiFrameReader->AcquireLatestFrame(&m_pMultiFrame); if (FAILED(hr) || !m_pMultiFrame) { cout << "!!!" << endl; continue; } // 从多源数据帧中分离出彩色数据,深度数据和红外数据 if (SUCCEEDED(hr)) hr = m_pMultiFrame->get_ColorFrameReference(&m_pColorFrameReference); if (SUCCEEDED(hr)) hr = m_pColorFrameReference->AcquireFrame(&m_pColorFrame); if (SUCCEEDED(hr)) hr = m_pMultiFrame->get_DepthFrameReference(&m_pDepthFrameReference); if (SUCCEEDED(hr)) hr = m_pDepthFrameReference->AcquireFrame(&m_pDepthFrame); if (SUCCEEDED(hr)) hr = m_pMultiFrame->get_InfraredFrameReference(&m_pInfraredFrameReference); if (SUCCEEDED(hr)) hr = m_pInfraredFrameReference->AcquireFrame(&m_pInfraredFrame); // color拷贝到图片中 UINT nColorBufferSize = 1920 * 1080 * 4; if (SUCCEEDED(hr)) hr = m_pColorFrame->CopyConvertedFrameDataToArray(nColorBufferSize, reinterpret_cast<BYTE*>(i_rgb.data), ColorImageFormat::ColorImageFormat_Bgra); // depth拷贝到图片中 if (SUCCEEDED(hr)) { hr = m_pDepthFrame->CopyFrameDataToArray(424 * 512, depthData); for (int i = 0; i < 512 * 424; i++) { // 0-255深度图,为了显示明显,只取深度数据的低8位 BYTE intensity = static_cast<BYTE>(depthData[i] % 256); reinterpret_cast<BYTE*>(i_depth.data)[i] = intensity; } // 实际是16位unsigned int数据 //hr = m_pDepthFrame->CopyFrameDataToArray(424 * 512, reinterpret_cast<UINT16*>(i_depth.data)); } // infrared拷贝到图片中 if (SUCCEEDED(hr)) { hr = m_pInfraredFrame->CopyFrameDataToArray(424 * 512, reinterpret_cast<UINT16*>(i_ir.data)); } // 显示 imshow("rgb", i_rgb); if (waitKey(1) == VK_ESCAPE) break; imshow("depth", i_depth); if (waitKey(1) == VK_ESCAPE) break; imshow("ir", i_ir); if (waitKey(1) == VK_ESCAPE) break; //waitKey(0); /*string s1 = "C:\Users\mataiyuan\Desktop\yooongchun\dataset\sample-"; string s2 = "-rgb.png"; string s3 = "-depth.png"; string s4 = "-infrared.png"; cvSaveImage((s1 + to_string(sample_id) + s2).c_str(), &IplImage(i_rgb)); cvSaveImage((s1 + to_string(sample_id) + s3).c_str(), &IplImage(i_depth)); cvSaveImage((s1 + to_string(sample_id) + s4).c_str(), &IplImage(i_ir)); sample_id += 1;*/ // 释放资源 SafeRelease(m_pColorFrame); SafeRelease(m_pDepthFrame); SafeRelease(m_pInfraredFrame); SafeRelease(m_pColorFrameReference); SafeRelease(m_pDepthFrameReference); SafeRelease(m_pInfraredFrameReference); SafeRelease(m_pMultiFrame); } // 关闭窗口,设备 cv::destroyAllWindows(); m_pKinectSensor->Close(); } int main() { GetPicture(); std::system("pause"); return 0; }
完成!