体感(Kinect)开发要点总结一
體感(Kinect)開發(fā)要點總結一
? ? Kinect有兩類攝像頭,近紅外攝像頭和普通的視頻攝像頭。視頻攝像頭提供了一般攝像頭類似的彩色影像。
?
? ? Kinect的彩色攝像頭默認每秒產(chǎn)生30副ColorImageFrame。
? ? 彩色影像數(shù)據(jù),景深數(shù)據(jù)分別來自ColorImageSteam和DepthImageStream,骨骼數(shù)據(jù)來自SkeletonStream。
? ? Skeleton Tracking(骨骼追蹤)是Kinect的核心技術。
? ? KinectSensor對象有一個名為SkeletonFrameReady事件。當SkeletonStream中有新的骨骼數(shù)據(jù)產(chǎn)生時就會觸發(fā)該事件。通過AllFramesReady事件也可以獲取骨骼數(shù)據(jù)。
? ? SkeletonStream產(chǎn)生的每一幀數(shù)據(jù)都是一個骨骼對象集合。每一個骨骼對象包含有描述骨骼位置以及骨骼關節(jié)的數(shù)據(jù)。每一個關節(jié)有一個唯一標示符如頭(head)、肩(shoulder)、肘(dlbow)等信息和3D向量數(shù)據(jù)。
? ? SkeletonFrameReady事件的響應方法,每一次事件被激發(fā)時,通過調(diào)用事件參數(shù)的OpenSkeletonFrame方法就能夠獲取當前的骨骼數(shù)據(jù)幀。
Kinect傳感器
? ? 基于Kinect開發(fā)的應用程序最開始需要用到的對象就是KinectSensor對象,該對象直接表示Kinect硬件設備。KinectSensor對象是我們想要獲取數(shù)據(jù),包括彩色影像數(shù)據(jù),景深數(shù)據(jù)和骨骼追蹤數(shù)據(jù)的源頭。
? ? 每一個數(shù)據(jù)流以幀(frame)為單位。例如:ColorImageStream當獲取到了新的數(shù)據(jù)時就會觸發(fā)ColorFrameReady事件。
? ? 每一種數(shù)據(jù)流(Color,Depth,Skeleton)都是以數(shù)據(jù)點的方式在不同的坐標系中顯示的。
? ? 將一個數(shù)據(jù)流中的點數(shù)據(jù)轉換到另一個數(shù)據(jù)流中是一個很常見的操作。
? ? KinectSensor對象有一些列的方法能夠進行數(shù)據(jù)流到數(shù)據(jù)點陣的轉換,他們是MapDepthToColorImagePoint,MapDepthToSkeletonPoint以及MapSkeletonPointToDepth。
? ? 在獲取Kinect數(shù)據(jù)前,我們必須先發(fā)現(xiàn)連接的Kinect設備。
發(fā)現(xiàn)連接的Kinect設備
? ? KinectObject對象,該對象是SDK在探測到有連接的Kinect設備時創(chuàng)建的。當有Kinect設備連接到計算機上時,應用程序應該得到通知或者提醒。KinectSeneor對象有一個靜態(tài)的屬性KinectSensors,該屬性是一個KinectSensorCollection集合,該集合繼承自
ReadOnlyCollection,ReadOnlyCollection集合很簡單,他只有一個索引器和一個稱之為StatusChanged的事件。
? ? 使用集合中的索引器來獲取KinectSensor對象。集合中元素的個數(shù)就是Kinect設備的個數(shù)。也就是說,一臺電腦上可以連接多個Kinect設備來從不同的方向獲取數(shù)據(jù)。應用程序可以使用多個Kinect設備來獲取多方面的數(shù)據(jù),Kinect個數(shù)的限制 只有電腦配置的限制。
由于每個Kinect是通過USB來進行數(shù)據(jù)傳輸?shù)?#xff0c;所以每一個Kinect設備需要一條USB線與電腦相連。此外,更多的Kinect設備需要更多的CPU和內(nèi)存消耗。
? ? 查找Kinect設備可以通過簡單的遍歷集合找到;但是KinectSensor集合中的設備不是都能直接使用,所以KinectSensor對象有一個Status屬性,他是一個枚舉類型,標識了當前Kinect設備的狀態(tài)。
? ? 只有設備在Connected狀態(tài)下時,KinectSensor對象才能初始化。在應用的整個生命周期中,傳感器的狀態(tài)可能會發(fā)生變化,這意味著我們開發(fā)的應用程序必須監(jiān)控設備的連接狀態(tài),并且在設備連接狀態(tài)發(fā)生變化時能夠采取相應的措施來提高用戶體驗。
? ? 添加Microsoft.Kinect.dll;
? ? 添加命名空間;
? ? using Microsoft.Research.Kinect.Nui;
? ? using Microsoft.Research.Kinect.Audio;
? ? using Coding4Fun.Kinect.Wpf;
? ? 發(fā)現(xiàn),獲取Kinect傳感器的狀態(tài)
? ? private KinectSensor kinect;
? ? public KinectSensor Kinect
? ? {
? ? ? ? get { return this.kinect;}
? ? ? ? set {
? ? ? ? ? ? //如果帶賦值的傳感器和目前的不一樣
? ? ? ? ? ? if (this.kinect!=value)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? //如果當前的傳感對象不為null
? ? ? ? ? ? ? ? if (this.kinect!=null)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ?//uninitailize當前對象
? ? ? ? ? ? ? ? ? ? this.kinect=null;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? //如果傳入的對象不為空,且狀態(tài)為連接狀態(tài)
? ? ? ? ? ? ? ? if (value!=null&&value.Status==KinectStatus.Connected)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? this.kinect=value;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
打開傳感器
? ? 一旦發(fā)現(xiàn)了傳感器,在應用程序能夠使用傳感器之前必須對其進行初始化。傳感器的初始化包括三個步驟。首先,應用程序必須設置需要使用的數(shù)據(jù)流,并將其狀態(tài)設為可用。每一中類型的數(shù)據(jù)流都有一個Enable方法,該方法可以初始化數(shù)據(jù)流。每一種數(shù)據(jù)流都完
全不同,在使用之前需要進行一些列的設置。在一些情況下這些設置都在Enable方法中處理了。
? ? 初始化之后,接下來就是要確定應用程序如何使用產(chǎn)生的數(shù)據(jù)流。最常用的方式是使用Kinect對象的一些列事件,每一種數(shù)據(jù)流都有對應的事件,他們是:ColorImageStream對應ColorFrameReady事件、DepthImageStream對應DepthFrameReady事件、SkeletonStream
對象對應SkeletonFrameReady事件。以及AllFramesReady事件。各自對應的事件只有在對應的數(shù)據(jù)流enabled后才能使用,AllFramesReady事件在任何一個數(shù)據(jù)流狀態(tài)enabled時就能使用。
? ? 最后,應用程序調(diào)用KinectSensor對象的Start方法后,frame-ready事件就會觸發(fā)從而產(chǎn)生數(shù)據(jù)。
停止傳感器
? ? 一旦傳感器打開后,可以使用KinectSensor對象的Stop方法停止。這樣所有的數(shù)據(jù)產(chǎn)生都會停止,因此在監(jiān)聽frameready事件時要先檢查傳感器是否不為null。
? ? KinectSensor對象以及數(shù)據(jù)流都會使用系統(tǒng)資源,應用程序在不需要使用KinectSensor對象時必須能夠合理的釋放這些資源。在這種情況下,程序不僅要停止傳單器,還用注銷frameready事件。注意,不要去調(diào)用KinectSensor對象的Dispose方法。這將會阻止應用程
序再次獲取傳感器。應用程序必須從啟或者將Kinect從新拔出然后插入才能再次獲得并使用對象。
平滑化
? ? 骨骼運動會呈現(xiàn)出跳躍式的變化。有幾個原因會導致出現(xiàn)這一問題,可能是應用程序的性能,游戲者的動作不夠連貫,也有可能是Kinect硬件的性能問題。骨骼關節(jié)點的相對位置可能在幀與幀之間變動很大,這對應用程序產(chǎn)生一些負面的影響。
? ? SkeletonStream對象有一種方法。他通過將骨骼關節(jié)點的坐標標準化來減少幀與幀之間的關節(jié)點位置差異。當初始化SkeletonStream對象調(diào)用重載的Enable方法時可以傳入一個TransformSmoothParameters參數(shù)。SkeletonStream對象有兩個與平滑有關只讀屬性:IsSmoothingEnabled和SmoothParameters。當調(diào)用Enable方法傳入了TransformSmoothParameters是IsSmoothingEnabled返回true而當使用默認的不帶參數(shù)的Enable方法初始化時,IsSmoothingEnabled對象返回false。SmoothParameters屬性用來存儲定義平滑參數(shù)。
? ? TransformSmoothParameters這個結構定義了一些屬性:
? ? ? ? 修正值(Correction)屬性,接受一個從0-1的浮點型。值越小,修正越多。
? ? ? ? 抖動半徑(JitterRadius)屬性,設置修正的半徑,如果關節(jié)點“抖動”超過了設置的這個半徑,將會被糾正到這個半徑之內(nèi)。該屬性為浮點型,單位為米。
? ? ? ? 最大偏離半徑(MaxDeviationRadius)屬性,用來和抖動半徑一起來設置抖動半徑的最大邊界。任何超過這一半徑的點都不會認為是抖動產(chǎn)生的,而被認定為是一個新的點。該屬性為浮點型,單位為米。
? ? ? ? 預測幀大小(Prediction)屬性,返回用來進行平滑需要的骨骼幀的數(shù)目。
? ? ? ? 平滑值(Smoothing)屬性,設置處理骨骼數(shù)據(jù)幀時的平滑量,接受一個0-1的浮點值,值越大,平滑的越多。0表示不進行平滑。
? ? 對骨骼關節(jié)點進行平滑處理會產(chǎn)生性能開銷。平滑處理的越多,性能消耗越大。設置平滑參數(shù)沒有經(jīng)驗可以遵循。需要不斷的測試和調(diào)試已達到最好的性能和效果。在程序運行的不同階段,可能需要設置不同的平滑參數(shù)。
? ? 平滑化示例代碼;
? ? ? ? ? ? nui.SkeletonEngine.TransformSmooth = true;
? ? ? ? ? ? var parameters = new TransformSmoothParameters
? ? ? ? ? ? {
? ? ? ? ? ? ? ? Smoothing = 0.75f,
? ? ? ? ? ? ? ? Correction = 0.0f,
? ? ? ? ? ? ? ? Prediction = 0.0f,
? ? ? ? ? ? ? ? JitterRadius = 0.05f,
? ? ? ? ? ? ? ? MaxDeviationRadius = 0.04f
? ? ? ? ? ? };
? ? ? ? ? ? nui.SkeletonEngine.SmoothParameters = parameters;
為骨骼幀準備好事件添加處理函數(shù)
? ? ? ? nui.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(nui_SkeletonFrameReady);
在SkeletonData對象的Joints屬性集合中保存了所有骨骼點的信息。每個骨骼點的信息都是一個Joint對象,其中的Position的X、Y、Z表示了三維位置。其中X和Y的范圍都是-1到1,而Z是Kinect到識別物體的距離。
骨骼追蹤系統(tǒng)中涉及到的一些主要的對象模型。有四個最主要的對象,他們是SkeletonStream,SkeletonFrame,Skeleton和Joint。
?
參考
http://blog.sina.com.cn/s/blog_45ef30330100uhoq.html
https://www.cnblogs.com/yangecnu/archive/2012/04/06/KinectSDK_Skeleton_Tracking_Part1.html
https://www.cnblogs.com/yangecnu/archive/2012/03/31/KinectSDK_Application_Fundamentals_Part1.html
總結
以上是生活随笔為你收集整理的体感(Kinect)开发要点总结一的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 微软Kinect 1.7 附带Color
- 下一篇: 图解DIV相关编程实例