第二篇 KinectV2結合opencv入門開發以及一些相關的學習資料
第二篇 KinectV2結合opencv入門開發以及一些相關的學習資料
首先宣告一下,本系統所使用的開發環境版本是計算機系統Windows 10、Visual Studio 2013、Opencv3.0和Kinect SDK v2.0。這些都可以在百度上找到,download下來安裝一下即可。
一、開發環境配置
1.Visual Studio 2013安裝
還有版本祕鑰,直接百度查詢就會有,這裡給出我當時用的:BWG7X-J98B3-W34RT-33B3R-JVYW9。
2.Opencv3.0安裝
Opencv的全稱是Open Source Computer Vision Library,是一個開源的跨平臺計算機視覺庫,
Opencv3.0的安裝十分簡單,只是環境配置相比其他軟體有一丟丟麻煩。這裡將分步演示每一步,包教包會。
你要記住你安裝的路徑。像本人的就是G:\Program Files\opencv3.0\opencv。第一步,配置環境變數。【計算機】-【(右鍵)屬性】-【高階系統設定】-【環境變數】。如圖
在path後面加一個英文分號,然後新增安裝路徑下的bin檔案,包括X86和X64資料夾下的,像本人的就是這樣的G:\Program Files\opencv3.0\opencv\build\x64\vc12\bin;G:\Program Files\opencv3.0\opencv\build\x86\vc12\bin;
溫馨提示:環境變數配置好後一般需要重啟電腦才會生效。
第二步,新建一個VS2013的控制檯工程,新增一個空cpp原始檔。在選單欄有個【檢視】-【其他視窗】-【屬性管理器】。如圖
開啟屬性視窗後,雙擊【Debug|Win32】下的第一個檔案【Microsoft.Cpp.Win32.user】會開啟一個屬性頁。(1)配置包含目錄。【通用屬性】-【VC++目錄】-【包含目錄】,再點選【編輯】按鈕,新增opencv安裝路徑下的include資料夾和其子檔案下,本人的是:
G:\Program Files\opencv3.0\opencv\build\include
G:\Program Files\opencv3.0\opencv\build\include\opencv
G:\Program Files\opencv3.0\opencv\build\include\opencv2
截圖如下:
(2)配置庫目錄,方法類似包含目錄的配置方法,【通用屬性】-【VC++目錄】-【庫目錄】,再點選【編輯】按鈕,新增安裝路徑下的X86資料夾裡面的lib資料夾,因為我們一般都是使用win32編譯器。本人的是
G:\Program Files\opencv3.0\opencv\build\x86\vc12\lib
截圖如下:
(3)配置連結庫,方法類似。【通用屬性】-【聯結器】-【輸入】-【附加依賴項】,再點選【編輯】按鈕。新增安裝路徑下lib資料夾裡面的,lib檔名,opencv3.0的lib檔案包含有
opencv_ts300d.lib
opencv_world300d.lib
opencv_ts300.lib
opencv_world300.lib
其中帶d的是debug版本lib檔案,不帶d的是release版本的lib檔案。
截圖如下:
經過以上兩大步五小步的配置之後,opencv3.0就配置好了。自己可以找個小程式測試一下,有其他問題歡迎留言,也可以自行百度或者谷歌解決。
3.Kinect SDK v2.0
去官網直接下載下來,雙擊安裝就行,然後在VS2013裡面新增一下相關的庫目錄和連結庫的附加依賴項。在【包含目錄】中加入【$(KINECTSDK20_DIR)\inc】
在【庫目錄】中加入【$(KINECTSDK20_DIR)\Lib\x86】
在【連結器】的【輸入】裡,【附加依賴項】中加入【kinect20.lib】。下載地址https://www.microsoft.com/en-us/download/details.aspx?id=44561
好了,以上這麼多就是配置開發環境的過程了,有問題歡迎留言交流。接下來就要進入正題了。
二、Kinect v2的API解讀
就目前來說,市面還沒有Kinect v2相關的學習書籍。本人覺得最好的學習資料就是SDK裡面的一些samples了,好好研究裡面的程式碼會讓你收穫不少,,當然也可以上網看一些別人的學習心得和學習筆記。
深入研讀Kinect SDK v2.0裡面示例的程式(samples),會發現Kinect v2的API是有規律可循的。拿上文提到的資料來源舉例,每種資料來源都有3個類與之對應,分別是Source,Reader,Frame,在程式裡面只需要例項化這三個類並呼叫相關類的成員函式就可以了。獲取彩色影象時,就需要使用IColorFrameSource, IColorFrameReader, IColorFrame這三個類。獲取紅外影象時,就會使用IInfraredFrameSource, IInfraredFrameReader, IInfraredFrame這三個類。剩下的也是類似的,如骨骼資料(Body),人物索引二值圖(BodyIndex),深度圖(Depth)。繼續深究:
(1)Source 在初始化好Kinect後,需要請求Kinect開啟一個目標源,後面從這個源獲得資料。以骨骼資料來源為例,下同,示例程式碼為:
m_pKinectSensor->get_BodyFrameSource(&pBodyFrameSource);
其中m_pKinectSensor是一個IKinectSensor類的例項化物件,是Kinect的源,所有資料都是從這個源獲取的,pBodyFrameSource是一個IBodyFrameSource類的例項化物件,它可以開啟讀口(reader)傳輸資料到電腦。
(2)Reader 由於Source是從Kinect獲得的資料來源,在電腦端需建立一個Reader和上面的Source繫結,然後可以通過這個Reader來獲取資料。示例程式碼:
pBodyFrameSource->OpenReader(&m_pBodyFrameReader);
其中m_pBodyFrameReader是一個IBodyFrameReader類的例項化物件,獲取最新的影象幀(AcquireLatestFrame)以及該類資料的其他屬性。
(3)Frame 真正儲存資料的類,一般是先從Reader讀取資料到Frame裡面,Frame裡面有各種各樣的資料,可以按自己的需求獲取。示例程式碼:
m_pBodyFrameReader->AcquireLatestFrame(&pBodyFrame);
其中pBodyFrame是一個IBodyFrame類的例項物件,呼叫其相關成員函式就可以把資料轉換到陣列或者其他格式,進而可以用Opencv顯示出來。
這裡的每個物件都需主動釋放,否則無法獲取其他變數。
三、Kinect v2獲取深度影象資料
在這裡以獲取深度圖為例,直接先貼上程式碼,稍後詳細解析。
#include <Kinect.h> //Kinect的標頭檔案
#include <iostream>
#include <opencv2\highgui.hpp> //opencv標頭檔案
using namespace std;
using namespace cv;
int main(void)
{
IKinectSensor * mySensor = nullptr;
GetDefaultKinectSensor(&mySensor); //獲取感應器
mySensor->Open(); //開啟感應器
IDepthFrameSource * mySource = nullptr; //取得深度資料
mySensor->get_DepthFrameSource(&mySource);
int height = 0, width = 0;
IFrameDescription * myDescription = nullptr; //取得深度資料的解析度
mySource->get_FrameDescription(&myDescription);
myDescription->get_Height(&height);
myDescription->get_Width(&width);
myDescription->Release();
IDepthFrameReader * myReader = nullptr;
mySource->OpenReader(&myReader); //開啟深度資料的Reader
IDepthFrame * myFrame = nullptr;
Mat temp(height,width,CV_16UC1); //建立影象矩陣
Mat img(height,width,CV_8UC1);
while (1)
{
if (myReader->AcquireLatestFrame(&myFrame) == S_OK) //通過Reader嘗試獲取最新的一幀深度資料,放入深度幀中,並判斷是否成功獲取
{
myFrame->CopyFrameDataToArray(height * width, (UINT16 *)temp.data); //先把資料存入16位的影象矩陣中
temp.convertTo(img,CV_8UC1,255.0 / 4500); //再把16位轉換為8位
imshow("TEST", img);
myFrame->Release();
}
if (waitKey(30) == VK_ESCAPE)
break;
}
myReader->Release(); //釋放不用的變數並且關閉感應器
mySource->Release();
mySensor->Close();
mySensor->Release();
return 0;
}
注意:為了簡便起見,此段程式碼略掉了大部分錯誤和異常檢測,只是為了做個示例獲取Kinect的深度影象。
首先,聲明瞭兩個矩陣,一個為16位單通道,一個為8位單通道,之所以開16位的,是因為在Kinect的基本引數這篇裡可以看到,深度資料是16位的。開8位的原因等下說。然後同樣的,利用AcquireLatestFrame()來獲取最新的一幀,不同的是下面一句,不再用AccessUnderlyingBuffer(),而是用CopyFrameDataToArray來把資料複製到openCV的影象矩陣Mat裡,注意第三個引數的型別是UINT16*,所以需要強制轉換一下。接下來要把16位的Mat轉換成8位來輸出顯示,為什麼不直接用16位?其實也可以用,但是直接用16位的話顯示的影象很接接近於全黑,不方便觀察,於是轉換為8位。convertTo()這個函式的第一個引數是輸出矩陣,第二個是轉換的型別,第三個是縮放因子,其中4500是深度資料的最大距離。如圖所示。
其他各種影象獲取方法都是類似的,除了骨骼資料獲取稍微複雜一點點,這些將在文章末尾打包下載,程式都會有詳細註釋。
四、Kinect學習的一些資料
Kinect for Windows C++ Reference(Kinect v2的API最全面和最權威的文件):
Kinect V2 SDK API說明文件 下載地址:http://download.csdn.net/detail/baolinq/9593563
還有很多人的部落格和論壇也有講解Kinect的入門開發:(1)http://blog.csdn.net/dustpg/article/category/2408183
(2)
(3)體感遊戲論壇
(4)k4w網
。。。。。。。
好了,本篇文章到這裡就要結束了。通過本篇文章,主要可以掌握Kinect v2的部分API的使用和學會如何獲取Kinect的資料來源。下面附上一些原始碼下載地址,0積分下載。
http://download.csdn.net/detail/baolinq/9616276
下一篇見。