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

來源:互聯網
上載者:User

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中開發)是否可以進行顯示。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.