關於Kinect手勢識別的一點體會

2021-06-11 17:55:29 字數 3255 閱讀 7535

kinect可以做的事情很多,諸如三維重構、場景替換、手勢識別等,但對於kinect應用的開發,目前很多時候傾向於做手勢識別方面。因為這是kinect最與眾不同的地方:將手勢對映到計算機互動中去從而傳遞人的想法。在人機互動領域,這是一種非常前衛的理念。

但是正是由於它的前衛,kinect目前各方面還不是非常成熟。感覺當前開發的難度主要集中在手勢識別引擎的開發上。雖然現在已經有一些第三方開發者建立的手勢引擎,但是微軟還沒有將它們作為標準的引擎。可預見在不遠的將來微軟會將手勢識別引擎新增到sdk中,又或者指明可替代方案,但在它出來之前,手勢識別很多時候得自己動手做。

在我看來,手勢識別實際上是要根據一系列點在一段時間內所形成的軌跡判斷出這裡面的含義。比方說,如果要識別畫圓的手勢,現在選擇跟蹤人的右手掌位置進行判斷。在人畫圓的過程中,計算機會採集一系列右手掌的點,一般以三維座標的形式標記出來,把這些點連起來會形成一段軌跡,接著要做的是判斷這段軌跡是否符合乙個圓,若符合就判斷人做出了畫圓的手勢。

目前我所知的做手勢識別主要有三種方法,基於演算法、基於神經網路和基於樣本庫。後兩種方法由於能力太低了,未能嘗試,希望以後能有機會。

基於演算法是最簡單也是最直接的方法,可以很快地做起來。演算法得到的結果是乙個二值化物件,某一手勢要麼符合預定手勢,要麼不符合,**寫起來簡單且容易除錯維護。可是,這裡存在著太多的問題。首先是識別精度低,誤判率高,特別是對於複雜的手勢。因為複雜的手勢軌跡很多時候並不能用某些數學公式準確地描述出來,比如人畫圓時,實際上並不是乙個標準的圓,多數情況下只是一段不規則的弧,若要找出最符合人畫圓軌跡的數學描述是挺困難的,這得通過大量的樣本分析這些弧的特徵。另外還有內在拓展性的問題,雖然對於不同的手勢有一些**可以重用,但是針對每乙個手勢都需要定製乙個演算法,隨著手勢數量的增加類庫會迅速增大,而且效能也會下降,因為每次判斷都要執行全部手勢識別演算法。最後還有乙個比較痛苦的問題就是引數的調整,每個演算法裡面或多或少都會有閾值,而這些閾值一般需要多次除錯才能調好,這過程是費時枯燥的。

基於神經網路的方法完全不懂。下面是看到的一些資料:神經網路的組織和判斷是基於統計和概率的,這使得識別手勢過程變得容易控制,能夠識別更複雜精細的手勢。除此之外,神經網路還能解決拓展性問題,因為神經網路包含很多神經元,每乙個神經元都是乙個好的演算法,能夠用來判斷手勢細微部分的運動,許多手勢可以共用乙個神經元,每一種手勢都有其獨特的神經元組合。雖然神經網路以及在電腦科學中對其的應用已經有了好幾十年,但建立乙個好的神經網路對於大多數程式設計師來說還是有一些困難的,大多數開發者可能對資料結構中的圖和樹比較熟悉,而對神經網路中尺度和模糊邏輯的實現可能一點都不了解,這種缺乏建立神經網路的經驗是乙個巨大的困難,即使能夠成功地構建乙個神經網路,程式的除錯也相當困難。神經網路依賴大量的引數來得到精確的結果,引數的個數隨著神經元的個數增長,每乙個神經元可以用來識別多個手勢,每乙個神經元的引數的變化都會影響其他節點的識別結果。配置和調整這些引數是一項藝術,需要經驗,並沒有特定的規則可循。然而,當神經網路配對機器學習過程中手動調整引數,隨著時間的推移,系統的識別精度會隨之提高。

基於樣本的手勢識別,是通過計算手勢與模板庫中已經規範了的手勢之間的匹配精度來進行識別的,簡單地說就是找最佳匹配,這也是計算機視覺中經常用到的方法。這種方法高度依賴於機器學習,識別引擎會記錄、處理和重用當前幀資料,所以隨著時間的推移,識別精度會逐步提高,系統能更好地識別出你想要表達的手勢意思,且能比較容易地識別出新的手勢,據說這種方法比基於神經網路能更好地處理複雜的手勢。但是,建立這樣乙個系統也是相當不容易的,首先,系統依賴大量樣本資料,樣本資料的收集是個問題,你需要不同高度、不同胖瘦、不同穿著的人做同乙個手勢時的資料,而且對於此方法,資料越多,識別精度越高。不過前一陣子已看到微軟發布了手勢資料,**如下另外,使用這方法系統也需要大量的儲存資源和cpu時間進行查詢與匹配。

對於基於演算法的手勢識別,需要儲存一定數量的點以還原手勢軌跡。這個點的數量選擇比較糾結,我的原則是:所有點連起來可以很好地重現手勢的軌跡,在此前提下,儘量減少需要維護的點。很明顯,每乙個手勢需要維護的點的數量都不一樣。一方面和手勢的平均持續時間相關,一般來說手勢持續時間越長需要維護越多的點,因為要保證有足夠長度去重現軌跡。但是,這並不一定的,比方說,如果手勢很簡單,只是單純地走直線,即使每隔多個點才儲存一次(跳幀),最後所有維護的點還是可以很好地重現軌跡的。因此另一方面點的數量還與手勢複雜度有關。另外,每個人做同乙個手勢速度是不一樣的,為了相容這種速度上的差異,一般會留些冗餘,比方說,假設現在維護了100個骨骼點,但某人做的手勢很快,它的手勢軌跡實際上只用前50個骨骼點就可以重現出來,後50個骨骼點就是冗餘的,但如果某人做的比較慢,可能就需要100個骨骼點才能重現軌跡。為了消除冗餘對響應速度的影響,我在識別手勢的時候是從最近的點開始往最遠的點進行判斷的,繼續上面的例子,那我的判斷就是如果前50個點符合軌跡,就直接判斷手勢做出來了並跳出,後50個點就不再判斷了。冗餘度的選擇比較麻煩,一方面點越多重現的軌跡就越逼近手勢實際軌跡,另一方面,維護越多點cpu的開銷就越大,而且響應速度也會減慢。若想估計一下需要的點數,可以這樣算,在效能理想的機器上,骨骼幀一般是30fps,就是說1秒可以獲取30次骨骼資料,然後估計一下手勢持續時間需要多少秒,相乘一下就可以知道大概需要多少個點了。但是,幀數有時是不穩定的,特別是在效能不好的機器上,變化可以非常大,因此最好還是實測除錯。由於維護骨骼點時需要大量的插入刪除操作,而且在識別的時候基本上需要順序遍歷大部分點,因此個人偏向於在儲存骨骼點的時候用鍊錶結構。

這裡舉個例子說明一下我做手勢識別的思路。思路整體是這樣的,首先想辦法識別出那個最基本的動作,然後再去考慮誤差,其中誤差需要多次測試才能考慮得比較全面。如識別手掌在胸前往前推,首先要識別出手掌往前推的動作,這裡可以直接用手掌在z座標上的距離變化作為前推距離進行判斷,若要相容側身(不是正對著kinect),就要利用x座標和z座標上的距離變化通過勾股定理算出向前推的距離,若前推距離大於某個閾值,則判斷做出了手勢。接著再減少誤判,相對來說這個就比較麻煩。假設只考慮z座標(人正對著kinect),(1)在前推的過程中,手掌要越來越靠近kinect,即對於每乙個點z座標上的值要不斷減少,不能來回晃動;(2)由於手掌要放在胸前,因此在xy平面上手掌點不能距離肩膀中點太遠;(3)由於要求平推,因此在前推過程中手掌在y軸方向上不能移動太多距離。

感覺做手勢的識別,最重要的是先選好基本的識別演算法,這個演算法要盡可能對於所有人做出的手勢都能識別,同時要盡量地排除其他手勢干擾,然後再減少誤判。當減少誤判的條件越來越多時,手勢的識別會越來越精確,但是程式的計算量會隨之增大,需要調整的閾值也會隨之增多,當有很多手勢需要識別時,程式的效能會受到很大的影響。

若要做乙個效果很好的、能夠復用的手勢識別引擎,估計要有深厚的演算法和程式設計功底才能勝任了。

另外,前幾個月看到有個叫leap 3d的運動控制系統,可以追蹤多個物體並識別手勢,雖然現在僅僅侷限於4立方英呎的空間,但據稱識別精度為0.01公釐,是kinect的100多倍……而售價也才70美元。雖然應用領域不太一樣,但從中看到的技術上的競爭還是非常激烈啊。

kinect 手勢識別的原理?

最近需要給小朋友們講解一下手勢識別的原理 但是我自己都不清楚,kinect 是怎麼識別到人的手勢,識別人手勢的左右揮動的動作,還有手勢往前推的動作的。下面只是我自己的一點理解。看了code 裡面好像自己就會識別 這幾個基本動作,沒有告訴我們到底是怎麼識別的.手勢識別raise的原理 識別到手勢的原理...

基於Kinect的手勢識別的相關資訊

1.硬體及其特點 kinect有三個鏡頭,中間的鏡頭是 rgb 彩色攝影機,左右兩邊鏡頭則分別為紅外線發射器和紅外線 cmos 攝影機所構成的 3d結構光深度感應器,還搭配了追焦技術,底座馬達會隨著對焦物體移動跟著轉動。kinect 也內建陣列式麥克風,並通過其採集聲音進行語音識別和聲源定位。支援多...

關於人臉識別技術一點談

隨著計算機通訊技術 視音訊壓縮技術和大規模儲存技術的發展,人臉影象識別己大量應用在教育 科研 廣播電視 安防 商業及消費領域。人臉影象識別在傳統上的應用包括人臉影象的辨認和確認,如 訪問控制 執法及安防等。隨著計算機計算和儲存能力的提高 網路技術的發展及人臉影象識別演算法的成熟,人臉影象識別技術將會...