市場上各種深度攝像頭測試之Kinect V1(第一代)
系統要求、系統配置、開發環境
Windows XP 及以後,X86(32/64bit)
2 GB RAM
USB 2.0 高速埠
sdk下載安裝及執行官方demo
Windows安裝步驟:
1、安裝 KinectSDK-v1.8-Setup.exe,預設安裝即可
2.安裝 KinectDeveloperToolkit-v1.8.0-Setup.exe,預設安裝即可,安裝後可執行官方案例
3.開始選單可看到安裝後的資料夾,點選Developer Toolkit Browser v1.8.0 (Kinect for Windows)可進入官方 demo
深度影象獲取
windows+vs2013+opencv 儲存16位深度影象,格式為png
1、opencv安裝+vs2013配置
直接官網下載:http://opencv.org/
安裝和配置:http://blog.csdn.net/wzw_ice/article/details/77159741
2、vs專案配置Kinect V1
(1)右鍵專案,進入專案屬性頁,選擇Debug配置
(2)VC++目錄:
包含目錄中 新增官方驅動的include資料夾,如:
C:\Program Files\Microsoft SDKs\Kinect\v1.8\inc
庫目錄中 新增依賴庫,如:
C:\Program Files\Microsoft SDKs\Kinect\v1.8\lib\x86
(3)連結器->輸入->附加依賴項,新增
kinect10.lib
3 個人專案程式碼(從官方demo提取出來並通過opencv獲取深度影象儲存為16bit的png)
opencvKinectDep.cpp
/*
原始深度影象獲取
kinect sdk 1.0
*/
#include "opencvKinectDepOrigin.h"
#define DEPTH_WIDTH 320
#define DEPTH_HIGHT 240
#define CHANNEL 3
BYTE buf[DEPTH_WIDTH*DEPTH_HIGHT*CHANNEL];
HANDLE hDepth1;
HANDLE hDepth2;
DWORD WINAPI DepthFunc(LPVOID pParam)
{
//cout << "depth start!" << endl;
while (TRUE)
{
if (WaitForSingleObject(hDepth1, INFINITE) == WAIT_OBJECT_0)
{
drawDepth(hDepth2);
}
// Sleep(10);
//cout << "depth" << endl;
}
}
//深度圖轉偽彩色圖
void depth2color(cv::Mat & color, const cv::Mat & depth, const double max, const double min)
{
cv::Mat grayImage;
double alpha = 255.0 / (max - min);
depth.convertTo(grayImage, CV_8UC1, alpha, -alpha * min);// expand your range to 0..255. Similar to histEq();
cv::applyColorMap(grayImage, color, cv::COLORMAP_JET);// this is great. It converts your grayscale image into a tone-mapped one, much more pleasing for the eye function is found in contrib module, so include contrib.hpp and link accordingly
}
int drawDepth(HANDLE h)
{
const NUI_IMAGE_FRAME * pImageFrame = NULL;
HRESULT hr = NuiImageStreamGetNextFrame(h, 0, &pImageFrame);
if (FAILED(hr))
{
cout << "Get Depth Image Frame Failed" << endl;
return -1;
}
INuiFrameTexture * pTexture = pImageFrame->pFrameTexture;
NUI_LOCKED_RECT LockedRect;
pTexture->LockRect(0, &LockedRect, NULL, 0);
if (LockedRect.Pitch != 0)
{
USHORT * pBuff = (USHORT*)LockedRect.pBits;
//cout << LockedRect.pBits << endl;
//cout << pBuff << endl;
Mat depthTmp(DEPTH_HIGHT, DEPTH_WIDTH, CV_16U, pBuff);
imshow("DepthOrigin", depthTmp);
imwrite("./image/16depth/1.png", depthTmp);
//深度->偽彩色
Mat sc_color;
double imax = 0, imin = 70000;
int imrow = depthTmp.rows;
int imcol = depthTmp.cols * depthTmp.channels();
for (int i = 0; i < imrow; i++)
{
for (int j = 0; j < imcol; j++)
{
ushort data = depthTmp.at<ushort>(i, j);
if (imin >= data && data != 0)
{
imin = data;
}
if (imax <= data)
{
imax = data;
}
}
}
depth2color(sc_color, depthTmp,imax,imin);
imshow("偽彩色圖",sc_color);
//imwrite("./1.png",sc_color);
for (int i = 0; i<DEPTH_WIDTH*DEPTH_HIGHT; i++)
{
BYTE index = pBuff[i] & 0x07;
USHORT realDepth = (pBuff[i] & 0xFFF8) >> 3;
BYTE scale = 255 - (BYTE)(256 * realDepth / 0x0fff);
buf[CHANNEL*i] = buf[CHANNEL*i + 1] = buf[CHANNEL*i + 2] = 0;
switch (index)
{
case 0:
buf[CHANNEL*i] = scale / 2;
buf[CHANNEL*i + 1] = scale / 2;
buf[CHANNEL*i + 2] = scale / 2;
break;
case 1:
buf[CHANNEL*i] = scale;
break;
case 2:
buf[CHANNEL*i + 1] = scale;
break;
case 3:
buf[CHANNEL*i + 2] = scale;
break;
case 4:
buf[CHANNEL*i] = scale;
buf[CHANNEL*i + 1] = scale;
break;
case 5:
buf[CHANNEL*i] = scale;
buf[CHANNEL*i + 2] = scale;
break;
case 6:
buf[CHANNEL*i + 1] = scale;
buf[CHANNEL*i + 2] = scale;
break;
case 7:
buf[CHANNEL*i] = 255 - scale / 2;
buf[CHANNEL*i + 1] = 255 - scale / 2;
buf[CHANNEL*i + 2] = 255 - scale / 2;
break;
}
}
Mat b(DEPTH_HIGHT, DEPTH_WIDTH, CV_8UC3, buf);
imshow("depth", b);
waitKey(1);
}
NuiImageStreamReleaseFrame(h, pImageFrame);
return 0;
}
int getOpencvKinectDepOrigin()
{
//初始化NUI
HRESULT hr = NuiInitialize(NUI_INITIALIZE_FLAG_USES_DEPTH);
if (hr != S_OK)
{
cout << "NuiInitialize failed" << endl;
return hr;
}
hDepth1 = CreateEvent(NULL, TRUE, FALSE, NULL);
hDepth2 = NULL;
hr = NuiImageStreamOpen(NUI_IMAGE_TYPE_DEPTH, NUI_IMAGE_RESOLUTION_320x240, 0, 2, hDepth1, &hDepth2);
if (FAILED(hr))
{
cout << "Could not open depth stream video" << endl;
return hr;
}
HANDLE hThread;
hThread = CreateThread(NULL, 0, DepthFunc, hDepth2, 0, NULL);
CloseHandle(hThread);
//Sleep(50000);
if (cvWaitKey(20) == 27)
{
NuiShutdown();
}
return 0;
}
深度圖轉換成偽彩色圖