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