其實就是彩圖映射到深度圖,我建議你以后修改下代碼,比如:不顯示紅外圖,加快運行。
#include<opencv2/opencv.hpp> #include <iostream> #include<iomanip> #include <Kinect.h> using namespace cv; using namespace std; //**************************************************** int i = 0;//拍照命名計數 bool flag;// 如果為真,i進行計數自增一 stringstream strColor;//保存彩圖名稱 stringstream strDepth;//保存深度圖名稱 stringstream strIR; //保存紅外圖名稱 //**************************************************** UINT16 *depthData = new UINT16[424 * 512]; Mat Temp; Mat Temp_; // 安全釋放指針 template<class Interface> inline void SafeRelease(Interface *& pInterfaceToRelease) { if (pInterfaceToRelease != NULL) { pInterfaceToRelease->Release(); pInterfaceToRelease = NULL; } } int main() { IKinectSensor *kinect; //創建一個感應器 HRESULT hr; //用於檢測操作是否成功 hr = GetDefaultKinectSensor(&kinect); if (FAILED(hr)) { return hr; } IMultiSourceFrameReader* m_pMultiFrameReader = nullptr;//下面的指針都初始化了,避免由於SDL檢測,不能通過編譯 if (kinect) { hr = kinect->Open(); //打開感應器 if (SUCCEEDED(hr)) { hr = kinect->OpenMultiSourceFrameReader( FrameSourceTypes::FrameSourceTypes_Color | FrameSourceTypes::FrameSourceTypes_Infrared | FrameSourceTypes::FrameSourceTypes_Depth, &m_pMultiFrameReader ); } } if (!kinect || FAILED(hr)) { return E_FAIL; } // 三個數據幀及引用 IDepthFrameReference* m_pDepthFrameReference = nullptr; IColorFrameReference* m_pColorFrameReference = nullptr; IInfraredFrameReference* m_pInfraredFrameReference = nullptr; IInfraredFrame* m_pInfraredFrame = nullptr; IDepthFrame* m_pDepthFrame = nullptr; IColorFrame* m_pColorFrame = nullptr; // 三個圖片格式 Mat i_rgb(1080, 1920, CV_8UC4); //注意:這里必須為4通道的圖,Kinect的數據只能以Bgra格式傳出 Mat i_depth(424, 512, CV_16UC1); Mat i_ir(424, 512, CV_16UC1); IMultiSourceFrame* m_pMultiFrame = nullptr; while (true) { // <4>獲取新的一個多源數據幀 如果沒有意外 以下 hr 都會 Returns S_OK 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); if (SUCCEEDED(hr)) { hr = m_pColorFrame->CopyConvertedFrameDataToArray(1080 * 1920 * 4, reinterpret_cast<BYTE*>(i_rgb.data), ColorImageFormat::ColorImageFormat_Bgra); //傳出數據 } if (SUCCEEDED(hr)) { hr = m_pDepthFrame->CopyFrameDataToArray(424 * 512, reinterpret_cast<UINT16*>(i_depth.data)); /* 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; } */ } if (SUCCEEDED(hr)) { hr = m_pInfraredFrame->CopyFrameDataToArray(424 * 512, reinterpret_cast<UINT16*>(i_ir.data)); } namedWindow("color", WINDOW_NORMAL); imshow("color", i_rgb); //i_depth.convertTo(Temp, CV_8UC1);//便於肉眼可見 //imshow("depth", Temp); //imshow("ir", i_ir); for (int i = 0; i < (424 * 512); i++) { depthData[i] = (i_depth.data)[i]; } /* // 數據傳遞測試 cv::Mat imageXX = cv::Mat::zeros(424,512,CV_16UC1); for (int i = 0; i < (424 * 512); i++) { (imageXX.data)[i] = depthData[i]; } */ //**************************************************** //彩色圖映射到深度【核心代碼】 int colorHeight = 1080; int colorWidth = 1920; //Mat coordinateMapperMat_(colorHeight, colorWidth, CV_16UC1);//映射后的深度圖 Mat coordinateMapperMat_ = Mat::ones(colorHeight, colorWidth, CV_16UC1); ICoordinateMapper* m_pCoordinateMapper_; hr = kinect->get_CoordinateMapper(&m_pCoordinateMapper_); std::vector<DepthSpacePoint> depthSpacePoints(colorHeight * colorWidth ); hr = m_pCoordinateMapper_->MapColorFrameToDepthSpace(424 * 512 , reinterpret_cast<UINT16*>(i_depth.data), colorHeight * colorWidth, &depthSpacePoints[0]); if (SUCCEEDED(hr)) { //coordinateMapperMat_ = cv::Scalar(0);//???? for (int y = 0; y < colorHeight; y++) { for (int x = 0; x < colorWidth; x++) { unsigned int index_ = y*colorWidth + x; DepthSpacePoint point_ = depthSpacePoints[index_]; int depthX_ = static_cast<int>(std::floor(point_.X + 0.5)); int depthY_ = static_cast<int>(std::floor(point_.Y + 0.5)); if ((depthX_ >= 0) && (depthX_ < 512) && (depthY_ >= 0) && (depthY_ < 424)) //&& (depth_ >= 800) && (depth_ <= 5000)) { coordinateMapperMat_.at<unsigned short>(y, x) = i_depth.at<unsigned short>(depthY_, depthX_); } } } } coordinateMapperMat_.convertTo(Temp_, CV_8UC1); namedWindow("coordinateMapperMat_", cv::WINDOW_NORMAL); imshow("coordinateMapperMat_", Temp_); if (waitKey(1) == VK_ESCAPE) break; //**************************************************** //拍照 flag = 0; int key = cv::waitKey(30);//獲取鍵盤 順便延時 if ((key & 255) == 32)//空格 { //【注】png是無損格式,同時 imread(depth.png, -1);后面的 “-1”是無損讀取原圖 strColor << "D:\\Temp\\color\\color_" << setw(2) << setfill('0') << i << ".png"; strDepth << "D:\\Temp\\depth\\depth_" << setw(2) << setfill('0') << i << ".png"; strIR << "D:\\Temp\\ir\\ir_" << setw(2) << setfill('0') << i << ".png"; cout << strColor.str() << "||" << strDepth.str() << "||" << strIR.str() << endl; imwrite(strColor.str(), i_rgb);//【注:】這里改為:紅外圖映射后的彩圖 imwrite(strDepth.str(), coordinateMapperMat_); imwrite(strIR.str(), i_ir); strColor.str(""); strDepth.str(""); strIR.str(""); flag = 1; } if (flag) i++; //**************************************************** // 釋放資源 SafeRelease(m_pColorFrame); SafeRelease(m_pDepthFrame); SafeRelease(m_pInfraredFrame); SafeRelease(m_pColorFrameReference); SafeRelease(m_pDepthFrameReference); SafeRelease(m_pInfraredFrameReference); SafeRelease(m_pMultiFrame); } // 關閉窗口,設備 cv::destroyAllWindows(); kinect->Close(); std::system("pause"); destroyAllWindows(); }