Kinect體系架構
Kinect 數據模式
1.Sensor
KinectSensor類
private KinectSensor kinectSensor = null; this.kinectSensor = KinectSensor.GetDefault(); this.kinectSensor.Open(); this.kinectSensor.Close();
2.Source
源,Kinect上的各個傳感器
它公開了每一個傳感器源的元數據然后給你一個入口
體感器每一數據類型展示一個源
屬性(字段):
AudioSource 獲取音頻的源
BodyFrameSource 獲取身體框架的源
BodyIndexFrameSource 獲取身體索引幀的源
ColorFrameSource 獲取顏色幀的源
DepthFrameSource 獲取景深幀的源
InfraredFrameSource 獲取紅外幀的源
LongExposureInfraredFrameSource 獲取長曝光紅外幀的源
3.Reader
一旦有了Reader,你就可以使用事件來訪問各幀
在一個源上,可以使用多個Reader
Reader可以暫停
//為紅外幀源創建一個讀出器,賦值給InfraredFrameReader類的實例:reader
InfraredFrameReader reader = sensor.InfraredFrameSource.OpenReader();
//為FrameArrived事件注冊方法,事件的觸發條件是一旦捕獲到幀(就緒)就觸發
reader.FrameArrived += InfraredReaderFrameArrived;
打開讀出器,訂閱已經就緒的幀事件,當有幀進來時就回調
4.Frame References
幀引用
幀引用,在幀事件的數據變量中,事實發送的就是幀引用
這樣你才能訪問幀本身
方法:
AcquireFrame 獲取此引用所持有的幀
如果在事件觸發之前,或者在你對其進行處理之前幀就已經過期,你就只能從已獲得的幀方法中得到一個空幀。這就是為什么需要查看一下的原因
屬性:
RelativeTime (相對時間)可以使你對不同的幀建立暫時的相關
不是絕對時間,是讓你能比較各個源之間的時間
使用方法:1.注冊幀事件,獲得幀引用
2.使用using數據塊即可,這個using數據塊將自動處理幀,完成后腰准備好處理下一幀
某一時刻只有一種類型的一個幀可用,如果不關閉、不處理幀,你就不能得到新的幀
void irReader_FrameArrived(InfraredFrameReader sender, InfraredFrameArrivedEventArgs args) { using (InfraredFrame frame = args.FrameReference.AcquireFrame()) { if (frame != null) { // Get what you need from the frame } } }
5.Frame
幀本身
有了幀,就可以訪問實際數據並加以利用了
建議拷貝一個本地副本或直接訪問基礎緩沖區,這樣你就可以迅速做出反應而無需長時間地使幀保持在當前可用狀態
每個幀都有寬度和高度數值等格式
6.FrameDescription類
繼承於接口IFrameDescription
幀描述,獲得幀的相關數據(寬、高等)
幀描述的長度以像素為單位
使用紅外源在Windows應用商店應用內輸出圖像
public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); this.Loaded += MainPage_Loaded; } KinectSensor sensor; InfraredFrameReader irReader; ushort[] irData;//儲存讀出器讀出的數據,IR數據的格式是Ushort byte[] irDataConverted;//將紅外數據轉換為圖像,創建緩沖區 WriteableBitmap irBitmap;//提供可寫入並可更新的位圖流,將我們轉換好的圖像送入XAML中的image //其實和在構造函數里寫是一樣的,MainPage構建時觸發事件執行下面的方法 private void MainPage_Loaded(object sender, RoutedEventArgs e) { //初始化 #region sensor = KinectSensor.GetDefault();//獲取默認Kinect irReader = sensor.InfraredFrameSource.OpenReader();//打開紅外讀出器 FrameDescription fd = sensor.InfraredFrameSource.FrameDescription;//創建紅外幀描述 irData = new ushort[fd.LengthInPixels];//幀描述的長度以像素為單位,16位整數數組 65535 irDataConverted = new byte[fd.LengthInPixels * 4];//IR需要轉換為RGBA圖像需要進行四次 #FF FF FF FF irBitmap = new WriteableBitmap(fd.Width, fd.Height);//創建位圖 image.Source = irBitmap; #endregion sensor.Open();//1.打開傳感器 irReader.FrameArrived += IrReader_FrameArrived;//2.為讀出器訂閱事件 } private void IrReader_FrameArrived(InfraredFrameReader sender, InfraredFrameArrivedEventArgs args) { //能否能從事件數組變量中的幀引用獲取幀 using(InfraredFrame irFrame = args.FrameReference.AcquireFrame()) { if (irFrame!=null) { irFrame.CopyFrameDataToArray(irData);//將幀數據復制到數組中 for (int i = 0; i < irData.Length; i++)//循環得到RGBA { byte intensity = (byte)(irData[i] >> 8); irDataConverted[i * 4] = intensity; irDataConverted[i * 4+1] = intensity; irDataConverted[i * 4+2] = intensity; irDataConverted[i * 4+3] = 255;//A為透明度,指定為255為不透明 } irDataConverted.CopyTo(irBitmap.PixelBuffer);//將RGBA復制到位圖的緩沖區中 irBitmap.Invalidate();//請求繪制或重繪位圖 } } } }