NUI圖像數據流概述編程
NUI的流數據是經過連續靜態圖像序列傳遞的。在上下文初始化階段,應用程序將識別須要讀取的流數據,並對其進行附加的流相關設置,包括數據解析度、圖像類型、用於存儲輸入幀的緩衝區數量等內容。在應用程序檢索並釋放相關幀以前,若是運行時數據佔滿了緩衝區,那麼系統將自動丟棄最舊的幀並重用緩衝區,也就是說,幀數據是可被丟棄的。同時系統最多容許請求四個緩衝區,而在大多數應用情形下一般只須要其中的兩個。應用程序可經過API獲取以下類型的圖像信息:彩色圖像數據、深度圖像數據、用戶分割數據等。下面將分別對上述三種類型的數據進行一些說明。框架
彩色圖像數據:系統提供兩種格式的彩色圖像數據,包括32位X8R8G8B8格式的sRGB位圖數據和16位的UYVY格式的YUV位圖數據。因爲二者實際來自同一圖像數據,所以兩種格式的最終圖像實際上沒有任何差異。不事後者要求圖像保持640×480的分辨率和15FPS的幀率,同時內存需求更小。應注意,因爲系統採用USB鏈接,傳感器層會首先將1280×1024分辨率的Bayer彩色濾波馬賽克圖像壓縮並轉換爲RGB格式傳輸,運行時系統再對該數據進行解壓縮操做。上述特性能夠保證數據幀率可達30FPS,但解碼操做會損失必定的圖像精度。函數
深度圖像數據:深度圖像幀中的每個像素點都表示從攝像頭所在平面到視野內最近物體的笛卡爾座標系距離,單位爲毫米。系統目前支持630×480、320×240、80×60三種規格的深度圖像幀。應用程序可根據深度圖像數據跟蹤人物動做、識別並忽略背景物體。深度圖像數據含有兩種格式,其一是惟一表示深度值:那麼像素的低12位表示一個深度值,高4位未使用;其二是既表示深度值又含有人物序號,則低三位保存人物序號,其他數據位表示深度值。應注意若是獲取的深度值爲0,則說明物體距離攝像頭過近或過遠以至超出了設備規格。ui
用戶分割數據:SDK beta目前支持讀取兩個用戶的分割映射數據,其數據幀的相關像素分別記錄了用戶的序號。儘管用戶分割數據是獨立生成的數據流,在實際應用中仍能夠將深度數據和用戶分割數據整合成一個幀,其中像素值的高13位保存了深度值,低三位保存用戶序號,其中序號爲0則表示無用戶,1和2分別表示兩個不一樣的用戶。在實際應用中,應用程序每每利用用戶分割數據在深度圖像和原始彩色圖像中獲取ROI感興趣信息。spa
基本編程模型線程
基於NUI API的編程模型本質上就是獲取傳感器圖像數據的過程。應用程序每每經過相關代碼首先將圖像的最後一幀讀入至緩衝區中,若是該幀已預備好,那麼其將進入緩衝區,若是幀數據還沒有就緒,代碼仍可選擇是否繼續掛起等待或暫時釋放並稍後重試。NUI攝像頭API絕對不會屢次傳遞相同的圖像數據。框架包含的基本編程模型以下:blog
一、POLLing模型,該模型較爲基礎易用。首先應開啓圖像數據流,而後請求並設置等待下一幀的時間,範圍容許從0到無窮大,單位爲毫秒;若是幀數據還沒有就緒,則系統將等待剛纔指定的時間而後返回。若是幀數據成功返回,則應用程序可請求下一幀數據並在同一線程執行其它操做。一般一個C++應用程序應調用NuiImageStreamOpen函數首先啓動一個彩色或深度數據流,並忽略可選事件。託管代碼則需調用ImageStream.Open方法。請求彩色或深度圖像幀的C++函數爲NuiImageStreamGetNextFrame,C#爲ImageStream.GetNextFrame方法。事件
二、事件模型,事件模型容許將獲取骨骼幀的功能精確、靈活地集成入應用程序引擎。在該模型中,C++程序首先調用NuiImageStreamOpen函數並傳入一個事件句柄。每當一個新的圖像幀數據可用時,事件信號將被觸發。任何相關的等待線程將被喚醒並經過調用NuiImageGetNextFrame函數獲取骨骼信息,與此同時事件將被系統重置。託管代碼應綁定Runtime.DepthFrameReady和Runtime.ImageFrameReady事件到相關的處理函數,當新數據可用時,處理函數可調用ImageStream.GetNextFrame獲取該數據。ip
NUI骨骼跟蹤應用內存
NUI還包括一個Skeleton骨骼跟蹤模塊,該部分提供最多兩名用戶的詳細位置和朝向信息。骨骼跟蹤的輸出是一個點集,稱做Skeleton Positions,該點集表示了一個完整的人體骨骼信息,以下圖所示。
骨骼位置信息表示了用戶當前的位置和姿態,若是要使用骨骼跟蹤功能,應用程序應在NUI初始化階段設置相關內容。NUI骨骼數據獲取的方式與NUI Image部分基本一致,其基本編程模型也包括Polling和Event兩種。前者的C++函數爲NuiSkeletonGetNextFrame,託管函數爲SkeletonEngine.GetNextFrame;後者的C++句柄綁定操做由NuiSkeletonTrackingEnable完成,並在處理線程內調用NuiSkeletonGetNextFrame;C#則使用Runtime.SkeletonFrameReady綁定事件,而後調用SkeletonEngine.GetNextFrame獲取相關信息。
骨骼跟蹤模塊經過深度數據計算地板裁切面,其基本方法將在後文進行介紹。若是應用程序在NUI初始化時開啓了骨骼跟蹤功能,則其每處理完一套深度數據則就放出相應的骨骼數據信號,而不管該深度數據中是否真的包含骨骼信息。應用程序使用地板裁切面數據獲取骨骼框架,返回的骨架信息將攜帶一個時間戳以和相關的深度信息進行匹配。
NUI骨骼跟蹤分主動和被動兩種模式,提供最多兩副完整的骨骼跟蹤數據。主動模式下須要調用相關幀讀取函數得到用戶骨骼數據,而被動模式下還支持額外最多四人的骨骼跟蹤,可是在該模式下僅包含了用戶的位置信息。對於全部獲取的骨骼數據,其至少包含如下信息:
一、相關骨骼的跟蹤狀態,被動模式時僅包括位置數據,主動模式包括完整的骨骼數據。
二、惟一的骨骼跟蹤ID,用於分配給視野中的每一個用戶。
三、用戶質心位置,該值僅在被動模式下可用。
四、對於主動模式下的骨骼跟蹤數據,還包括用戶完整的骨骼數據。
五、對於被動模式下的骨骼跟蹤數據,僅包括用戶位置信息,不包括詳細的骨骼數據。
NUI座標變換原理
深度圖像空間:這是一個僅包含物體到傳感器法平面的深度數據的投影空間,其z值是惟一有效的,而x、y值僅僅是進行了插值計算的結果,其數據實際並沒有任何物理意義;
骨骼空間:用戶骨骼位置使用x、y、z三維座標表示,與深度圖像空間座標系不一樣的是,該空間的單位爲米,且是一個傳感器朝向爲z軸正向的右手系。應注意,骨骼空間座標系與Kinect位置息息相關,若是傳感器被放置在一個非水平面上,那麼計算獲得的座標系可能並不是是標準形式,最終的用戶數據也有多是傾斜的。
地板裁剪面的肯定:骨骼數據均須要包含一個地板裁剪面向量,該向量保存了與地板平面方程有關的係數coefficients,骨骼跟蹤模塊經過地板裁剪平面除去背景,並將用戶圖像分割出來。對於平面的通常式方程Ax+By+Cz+D=0,該方程通過規範化即D值實際是指傳感器到地板平面的高度值。若是地板不可見,那麼地板裁剪平面向量實際爲0。地板裁剪面向量值可在NUI_SKELETON_FRAME結構的vFloorClipPlane成員中獲取。託管代碼則保存在SkeletonFrame.FloorClipPlane域中。
骨骼鏡像:默認的用戶圖像其實是一個鏡像數據,也就是說該數據表示了用戶當前面朝屏幕內部。然而有時確實須要圖像面向用戶本人一側,那麼須要肯定一個鏡像變換矩陣以達到此類要求。