Kinect橋接OpenCV代碼簡介Kinect Bridge With OpenCV

Kinect橋接OpenCV代碼簡介KinectBridge With OpenCV

 Kinect Bridge With MATLAB & OpenCV簡介文檔和項目下載

驅動版本:Kinect forWindows SDK v1.7

項目名稱:KinectBridgeWithOpenCVBasics-D2D

編程語言:C++

程序配置和運行

安裝程序後,在文件夾KinectBridgeWithOpenCVBasics-D2D中看到KinectBridgeWithOpenCVBasics-D2D.docx這個文檔。文檔中只說瞭如何配置OpenCV環境變量等等之類的,使用OpenCV的孩紙一眼就明白了。這裏我還是使用自己常用的方法配置。(如果沒有配置過OpenCV的,請去opencv.org.cn去學習如何配置,初學者往往需要1個小時到1天才能學會,熟練後5分鐘)【你也可以按照微軟說的方法進行配置,微軟的方法雖然麻煩,但是一勞永逸!】

 

我是把OpenCV2.4.4安裝在F盤的Softs文件夾下。使用VS2010進行配置。

在屬性頁中--->VC++目錄:

包含目錄:

         F:\Softs\OpenCV244\opencv\build\include

         $(KINECTSDK10_DIR)\inc

庫目錄:

         F:\Softs\OpenCV244\opencv\build\x86\vc10\lib

         $(KINECTSDK10_DIR)\lib\x86

源目錄:

         F:\Softs\OpenCV244\opencv\modules\core\src

F:\Softs\OpenCV244\opencv\modules\imgproc\src

F:\Softs\OpenCV244\opencv\modules\highgui\src

在屬性頁中--->鏈接器:

附加依賴項:

         opencv_core244d.lib

opencv_imgproc244d.lib

opencv_highgui244d.lib

Kinect10.lib

comctl32.lib

 

         全部配置完畢後,編譯F7,再執行Ctrl+F5。一點沒有問題(如果有問題是你的配置問題,不要留言,請去OpenCV論壇求救),得到以下運行圖像(頭像被我用畫筆刷掉了):


程序簡要解讀

FrameRateTracker類

         用於計算視頻幀率,使用clock()函數,每秒鐘會調整一次幀率顯示結果。

KinectHelper類

         這個類的定義和實現都放在頭文件中了。主要作用就是調用Kinect SDK中的函數,對Kinect進行初始化(打開Kinect和各種數據流,更新彩色、深度圖像數據幀和骨骼數據幀),使用事件對象進行同步。數據被存放在m_pColorBuffer,m_pDepthBuffer,m_skeletonFrame數組中。

OpenCVHelper類

         用於對圖像進行濾波(高斯模糊GaussianBlur,腐蝕erode,膨脹dilate,canndy邊緣檢測),把骨骼數據滑到彩色圖像和深度圖像中(line和circle方法)。

OpenCVFrameHelper類

         KinectHelper的子類,把數據存放到OpenCV的Mat矩陣結構中(方法pImage->ptr<Vec4b>(y))。

=================================================================

MainWindow類

       主程序。使用互斥鎖(CreateMutex)進行同步(他們以前的程序不進行同步),CreateMutex()函數可用來創建一個有名或無名的互斥量對象。

HANDLE CreateMutex(   

LPSECURITY_ATTRIBUTES lpMutexAttributes, // 指向安全屬性的指針   

BOOL bInitialOwner,// 初始化互斥對象的所有者   

LPCTSTR lpName // 指向互斥對象名的指針);

 

返回值

Long,如執行成功,就返回互斥體對象的句柄;零表示出錯。會設置GetLastError。即使返回的是一個有效句柄,但倘若指定的名字已經存在,GetLastError也會設爲ERROR_ALREADY_EXISTS

 

參數表   參數          類型及說明   

lpMutexAttributes SECURITY_ATTRIBUTES,指定一個SECURITY_ATTRIBUTES結構,或傳遞零值(將參數聲明爲ByVal As Long,並傳遞零值),

表示使用不允許繼承的默認描述符。

 

bInitialOwner BOOL,如創建進程希望立即擁有互斥體,則設爲TRUE。一個互斥體同時只能由一個線程擁有。是FALSE,表示剛剛創建的這個Mutex不屬於任何線程

也就是沒有任何線程擁有他,一個Mutex在沒有任何線程擁有他的時候,他是處於激發態的, 所以處於有信號狀態。

 

lpName String,指定互斥體對象的名字。用vbNullString創建一個未命名的互斥體對象。如已經存在擁有這個名字的一個事件,則打開現有的已命名互斥體。這個名字可能不與現有的事件、信號機、可等待計時器或文件映射相符該名稱可以有一個"Global\" 或"Local\" 前綴,明確地建立在全局或會話命名空間的對象。剩餘的名稱可以包含任何字符,除反斜槓字符(\)。

 

生成方法:

m_hColorResolutionMutex =CreateMutex(NULL, FALSE, NULL);

微軟創建的所有的互斥鎖參數都一樣。表明,1使用不允許繼承的默認描述符,2剛剛創建的這個Mutex不屬於任何線程,3互斥體對象沒有名字。

調用方法:

WaitForSingleObject(m_hColorResolutionMutex,INFINITE);

m_colorResolution = NUI_IMAGE_RESOLUTION_640x480;

ReleaseMutex(m_hColorResolutionMutex);

         從使用方法看,和臨界區的方法一模一樣。之所以使用這些同步方法(互斥鎖,臨界區)是因爲有些變量(或稱爲資源)會同時在多個線程中使用,爲了避免資源使用衝突,使得多個線程排隊使用這個變量。凡是在多個線程中同時使用的變量,都需要爲它們設定一個同步方法(如果變量太多,最好把它組合成一個變量結構)。

 

 

線程開始(Run函數中):

m_hProcessThread= CreateThread(NULL, 0, ProcessThread, this, 0,NULL);

線程結束事件:

m_hProcessStopEvent= CreateEvent(NULL, FALSE, FALSE, NULL);

 

主線程ProcessThread中使用while無限循環

四個事件對象(426行)

HANDLE hEvents[4]= {m_hProcessStopEvent(退出), 彩色, 深度, 骨骼};

等待某個內核對象被觸發(一共四個)

int eventId = WaitForMultipleObjects(numEvents,hEvents, FALSE, 100);

     之後就針對不同情況進行處理。除了對退出(eventId==0)進行判斷,其它的都直接對所有數據進行更新,而不針對eventId的大小(1,2,3)而分別處理。這算是改進吧,其它的C++程序都改成這樣子的了,應該算變得簡單了。但這樣會導致每次只有1個函數是實際運行的,另外二個是不運行的。可以把我之前Kinect人臉跟蹤Kinect Face Tracking SDK文章中的if (WAIT_OBJECT_0 == WaitForSingleObject(m_hNextDepthFrameEvent, 0))都去掉,程序一樣可以運行,但是會提示數據沒有捕獲到(三個數據不是同時都能獲取的,得排隊)。

 

         在MainWindow中還可以看到OpenCV的Mat如何被使用的:

1.原始數據BYTE-->存放到m_pColorBuffer中(m_frameHelper.UpdateColorFrame())

2.m_pColorBuffer構建成m_colorMat結構(m_frameHelper.GetColorImage(&m_colorMat)),3.對m_colorMat進行各種濾波方法(m_openCVHelper.ApplyColorFilter(&m_colorMat))

4.最後把濾波後的畫出來(UpdateBitmap(&m_colorMat,&m_hColorBitmap, &m_bmiColor);底層又調用了SetDIBits(m_hdc, *phBitmap, 0, height,pImg->ptr(), pBmi, DIB_RGB_COLORS);)

5.最最後還需要刷新屏幕區域(InvalidateRect(m_hWndMain, NULL, false);)

 

         由於使用windows api創建窗體,這個程序顯得很臃腫,一共3000行代碼(包含註釋和空行)。但依舊有很多可以學習的地方,特別是他們寫代碼都很精美。這個程序僅僅是把數據傳到OpenCV的結構中,並使用OpenCV的基本函數進行一些圖像處理,最後再顯示出來,一年多前寫的文章代碼實現的就是這個原理。

         如果你一直使用windows api顯示窗口,那麼很容入門。如果不是,那麼需要很多時間學習它(我一直用簡單的MFC作窗口)。微軟給的例子很強健,很穩定,考慮了許多情況。但如果想要自己實現更好的軟件,還是建議使用MFC吧。

可以直接在我前些天的文章Kinect人臉跟蹤Kinect Face Tracking SDK中做一些修改,即可得到OpenCV顯示的圖像。也不知道有多少人使用MFC,如果人多的話,可以花時間寫一個簡單範例出來,更不知道Qt(VS2010中開發)是否可以進行顯示。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章