Kinect获取深度数据利用色彩展示
根据微软资料显示,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; } }
效果如图所示