根據微軟資料顯示,Kinect v2的深度幀數據為0.5m-8m,每一幀的大小為512*424(pixel),每一像素點的深度值存放在一個16位bit的ushort中。
這里的深度是指像素點到Kinect Sensor平面的距離,網上有資料說數據的前13位表示距離,后3位表示用戶ID,也有說12+4的,但根據我獲得的原始
數據顯示,並沒有用戶ID位,全都是表示距離的。
下面介紹一下在unity5.6中獲取深度數據並當紋理顯示在一游戲對象上的過程,離Sensor越近則顏色越紅,越遠則越綠。
首先定義變量
private KinectSensor _Sensor; //Kincet傳感器 private DepthFrameReader _depthReader; //深度幀讀取器 private ushort[] _depthData; //因為深度數據為2字節16bit,所以定為ushort存放數據 private Texture2D _texture; private Color[] pixelColor; //根據每個像素點的深度,賦予顏色 private int nearThreshold; //最近的有效探測距離 private int farThreshold; //最遠的有效探測距離
在Start方法中初始化各變量
_Sensor = KinectSensor.GetDefault (); if (_Sensor != null) { _depthReader = _Sensor.DepthFrameSource.OpenReader (); var frameDescript = _Sensor.DepthFrameSource.FrameDescription; //數組大小為整個像素的長度 _depthData = new ushort[frameDescript.LengthInPixels]; //定義顯示紋理大小為512*424 _texture = new Texture2D (frameDescript.Width, frameDescript.Height); //為每個深度點定義顏色 pixelColor = new Color[frameDescript.LengthInPixels]; //深度幀最近可信距離500mm,最遠可信距離4500mm nearThreshold = _Sensor.DepthFrameSource.DepthMinReliableDistance; farThreshold = _Sensor.DepthFrameSource.DepthMaxReliableDistance; } if (!_Sensor.IsOpen) _Sensor.Open ();
定義Depth2ColorTexture(),並根據各像素點的深度值,賦值不同的顏色,更新紋理
void Depth2ColorTexture() { for (int i = 0; i < _depthData.Length; i++) { ushort data = _depthData [i]; if (data < nearThreshold) {//當小於可信距離,顏色為黑 pixelColor [i].r = 0; pixelColor [i].g = 0; pixelColor [i].b = 0; } else if (data > farThreshold) {//當超過可信距離,顏色為藍 pixelColor [i].r = 0; pixelColor [i].g = 0; pixelColor [i].b = 1; } else { int grade = data / nearThreshold; //0.125 = 1/8 將500-4500之間分為8份;如果離kinect越近越紅 越遠越綠 pixelColor [i].r = 1.0f - 0.125f * grade; pixelColor [i].g = 0.125f * grade; pixelColor [i].b = 0; } } _texture.SetPixels (pixelColor); _texture.Apply (); GetComponent<Renderer> ().material.mainTexture = _texture; }
在Update中獲取深度幀數據,並調用Depth2ColorTexture方法顯示。
if (_depthReader == null) return; var frame = _depthReader.AcquireLatestFrame (); if (frame != null) { frame.CopyFrameDataToArray (_depthData); Depth2ColorTexture (); frame.Dispose (); frame = null; }
最后,當整個程序退出時,銷毀Sensor和Reader
void OnApplicationQuit() { if (_depthReader != null) { _depthReader.Dispose (); _depthReader = null; } if (_Sensor != null) { if (_Sensor.IsOpen) { _Sensor.Close (); } _Sensor = null; } }
效果如圖所示