圖1.Kinect 硬體設備(圖片來源:Games Blog)
1.中間的鏡頭是攝影機
2.左右兩顆鏡頭則是3D深度感應器
3.底座馬達可上下轉各27度
4.陣列式麥克風
圖2.功能圖(圖片來源:PrimeSense)
Kinect可同時獲取彩色影像、3D深度影像、以及聲音訊號(引
用PrimeSensor解說圖)
微軟與另一家以色列公司PrimeSense合作
(來源:gossipgamers),讓Kinect使用的3D偵測技術有了著
落。他們也是提供動作感測系統的公司,擁有體感偵測裝置PrimeSensor,以及感測晶片PS1080。PrimeSense用的並
不是採用3DV Systems的TOF技術、而是Light Coding技術。
Light Coding技術理論是利用連續光(近紅外線)對測量空間
進行編碼,經感應器讀取編碼的光線,交由晶片運算進行解碼
後,產生成一張具有深度的圖像。Light Coding技術的關鍵是
Laser Speckle雷射光散斑,當雷射光照射到粗糙物體、或是穿
透毛玻璃後,會形成隨機的反射斑點,稱之為散斑。散斑具有
高度隨機性,也會隨著距離而變換圖案,空間中任何兩處的散
斑都會是不同的圖案,等於是將整個空間加上了標記,所以任
何物體進入該空間、以及移動時,都可確切紀錄物體的位置。
Light Coding發出雷射光對測量空間進行編碼,就是指產生散
斑。
Kinect就是以紅外線發出人眼看不見的class 1雷射光,透
過鏡頭前的diffuser(光柵、擴散片)將雷射光均勻分佈投射
在測量空間中,再透過紅外線攝影機記錄下空間中的每個散
斑,擷取原始資料後,再透過晶片計算成具有3D深度的圖像。
微軟會將偵測到的3D深度圖像,轉換到骨架追蹤系統。該系統最多可同時偵測到6個人,包含同時辨識2個人的動作;每個人共可記錄20組細節,包含軀幹、四肢以及手指等都是追蹤的範圍,達成全身體感操作。為了看懂使用者的動作,微軟也用上機器學習技術(machine learning),建立出龐大的圖像資料庫,形成智慧辨識能力,盡可能理解使用者的肢體動作所代表的涵義。
Kinect偵測的最佳距離為1.2公尺到3.5公尺間,水平視野則是57度,偵測範圍似乎比原本想像的還要小,看來還是不能站的太隨意;Kinec也配備了追焦系統,如果玩家超出影像範圍,底座馬達可驅動Kinect上下旋轉27度。
由於Kinect攝影機的影像更新頻率為30FPS,代表動作傳遞將會有33ms(1/30秒)的延遲,CrunchGear也在文中質疑這會不會造成動作偵測上的延遲,為何不使用60FPS以上的錄影規格拍攝?這其實是PrimeSense公司提供的處理晶片能耐,它就只能處理VGA畫質、30FPS的影像。
30FPS影像更新頻率造成的延遲應該有限,因為人類對事物的反應速度幾乎都超過100ms,已經大於30FPS所帶來的33ms延遲。比起偵測延遲,更該擔心的是辨識需要的時間、以及辨識的精準度。由於Kinect是透過辨識圖像再轉化為指令的方式,大量的影像處理、以及事後的辨識動作,恐怕才是讓Kinect使用者感受到延遲的原因。
進行編碼,經感應器讀取編碼的光線,交由晶片運算進行解碼
後,產生成一張具有深度的圖像。Light Coding技術的關鍵是
Laser Speckle雷射光散斑,當雷射光照射到粗糙物體、或是穿
透毛玻璃後,會形成隨機的反射斑點,稱之為散斑。散斑具有
高度隨機性,也會隨著距離而變換圖案,空間中任何兩處的散
斑都會是不同的圖案,等於是將整個空間加上了標記,所以任
何物體進入該空間、以及移動時,都可確切紀錄物體的位置。
Light Coding發出雷射光對測量空間進行編碼,就是指產生散
斑。
Kinect就是以紅外線發出人眼看不見的class 1雷射光,透
過鏡頭前的diffuser(光柵、擴散片)將雷射光均勻分佈投射
在測量空間中,再透過紅外線攝影機記錄下空間中的每個散
斑,擷取原始資料後,再透過晶片計算成具有3D深度的圖像。
微軟會將偵測到的3D深度圖像,轉換到骨架追蹤系統。該系統最多可同時偵測到6個人,包含同時辨識2個人的動作;每個人共可記錄20組細節,包含軀幹、四肢以及手指等都是追蹤的範圍,達成全身體感操作。為了看懂使用者的動作,微軟也用上機器學習技術(machine learning),建立出龐大的圖像資料庫,形成智慧辨識能力,盡可能理解使用者的肢體動作所代表的涵義。
Kinect偵測的最佳距離為1.2公尺到3.5公尺間,水平視野則是57度,偵測範圍似乎比原本想像的還要小,看來還是不能站的太隨意;Kinec也配備了追焦系統,如果玩家超出影像範圍,底座馬達可驅動Kinect上下旋轉27度。
圖4.介面
程式碼部分,我參考了微軟的SDK範例,不過上面寫的只有部分程式碼,若要使範例能正常編譯且執行,還需要從cm-bloggers上面抓起一些程式碼。研究了微軟範例3天左右,因為上面寫的不是很清楚,比方說:沒有寫使用哪些物件、函式沒給...等等,所以我將函式名稱Google一下,意外發現cm-bloggers這個部落格,上面的程式碼較為完善,也因為這樣,我才能將Kinect的影像訊息顯示出來。
以下三張照片,是在非常巧合的情況下拍攝的,因為要kinect顯示骨架的話,人必須在鏡頭前1.2公尺左右才會顯示,正當我在煩惱要如何拍骨架圖和拍照時,一位帥氣的學長走了過來看我寫的程式時,程式偵測到骨架的那一瞬間,我就按下拍照了。
圖5.視訊圖
圖6.深層圖
圖7.骨架圖
以上三張照片,都是同一個人,只是輸入和輸出的各有不同的技術,才會造成不同圖案顯示。
圖8.更新頻率
30FPS影像更新頻率造成的延遲應該有限,因為人類對事物的反應速度幾乎都超過100ms,已經大於30FPS所帶來的33ms延遲。比起偵測延遲,更該擔心的是辨識需要的時間、以及辨識的精準度。由於Kinect是透過辨識圖像再轉化為指令的方式,大量的影像處理、以及事後的辨識動作,恐怕才是讓Kinect使用者感受到延遲的原因。
圖9.深層加骨架
這是我想玩玩看,如果鏡頭不一樣,那我將兩張圖重疊,位置會不會一樣呢?實驗顯示,會一樣的。
圖10.馬達控制
在前文中有提到馬達可上下轉動各27度,我是使用Button控制,本來想讓馬達一直轉動,但是...看到下面這段原文:
To adjust the camera tilt, set the ElevationAngle property of the Camera object to a value between –27 (Camera.ElevationMinimum) and +27 (Camera.ElevationMaximum). However, the tilt mechanism in the sensor array is not designed for frequent use. Code should not make calls to the tilt device more than 15 times in any two-minute window. Changing the tilt too often will result in an error message.
似乎說著馬達不適合頻繁轉動,所以我就做罷,必要時再動馬達就好。
這一個星期剛接觸Kinect,本來以為可以很快的就將其功能寫出來,未料範例程式有缺函式和剛接觸C# WPF專案,導致需花一段時間研究環境,不過還好有開竅,才得以照範例寫出來。
參考資料: