显示人体轮廓
kinect中含有bodyindexframe这种帧,即人体像素索引,可以很简单的捕捉到人体在摄像头的某个位置,只要是人体的某个部位,都会被标记,然后经过格式转换,就会将人体的轮廓显示出来,不过一个缺点就是,人体附近的某些物品或者一些点会被当成是人体身上的点,会被标记,然后经过转换也会被显示出来,这就要改变标记人体的算法了。
//体感器设备 private KinectSensor KinectDevice; //用户编号图像 //玩家轮廓帧读取变量 private BodyIndexFrameReader _BodyIndexfr; //玩家轮廓帧描述 private FrameDescription _BodyIndexDescription; //位图对象 private WriteableBitmap _BodyIndexBitmap; //存放一帧玩家轮廓图像的矩形框 private Int32Rect _BodyIndexBitmapRect; //步长,一维玩家轮廓像素数组转化为矩形框的步长。 private int _BodyIndexStride; //存放一帧玩家轮廓图像像素 private byte[] _BodyIndexPixelData; //用户颜色UINT32位 private static readonly uint[] BodyColor = { 0x0000FFFF, 0x00FF00FF, 0xFF0000FF, 0x00FFFFFF, 0xFF00FFFF, 0xFFFF00FF, }; //显示的图像数组 private uint[] _BodyIndexData; public MainWindow() { InitializeComponent(); //获取默认的连接的体感器 this.KinectDevice = KinectSensor.GetDefault(); //玩家轮廓帧读取变量初始化 this._BodyIndexfr = this.KinectDevice.BodyIndexFrameSource.OpenReader(); //触发玩家轮廓帧事件 this._BodyIndexfr.FrameArrived += _BodyIndexFrameReader_FrameArrived; //玩家轮廓帧描述,宽度和高度 this._BodyIndexDescription = this.KinectDevice.BodyIndexFrameSource.FrameDescription; //位图初始化,宽度,高度,96.0表示分辨率,像素格式,Bgra32 32位。 this._BodyIndexBitmap = new WriteableBitmap(this._BodyIndexDescription.Width, this._BodyIndexDescription.Height, 192.0, 192.0, PixelFormats.Bgra32, null); //存放图像像素的矩形框,起点为(0,0),宽度和高度 this._BodyIndexBitmapRect = new Int32Rect(0, 0, this._BodyIndexDescription.Width, this._BodyIndexDescription.Height); //步长:宽度 this._BodyIndexStride = this._BodyIndexDescription.Width; //存放玩家轮廓图像的字节数组的长度=帧宽度*帧高度 this._BodyIndexPixelData = new byte[this._BodyIndexDescription.Width * this._BodyIndexDescription.Height]; this._BodyIndexData = new uint[this._BodyIndexDescription.Width * this._BodyIndexDescription.Height]; //UI界面的图片控件和位图关联起来 depthBodyImage.Source = this._BodyIndexBitmap; //启动体感器 this.KinectDevice.Open(); } //玩家轮廓处理事件 void _BodyIndexFrameReader_FrameArrived(object sender, BodyIndexFrameArrivedEventArgs e) { //获取一帧玩家轮廓图像 using (BodyIndexFrame bodyIndexFrame = e.FrameReference.AcquireFrame()) { //如果获取成功 if (bodyIndexFrame != null) { //将玩家轮廓帧数据存放在字节数组里面 bodyIndexFrame.CopyFrameDataToArray(this._BodyIndexPixelData); int colorIndex; for (int row = 0; row < this._BodyIndexDescription.Height; row++) { for (int col = 0; col < this._BodyIndexDescription.Width; col++) { //根据行号和列号计算一维数组的下标 colorIndex = row * this._BodyIndexDescription.Width + col; //数组的像素玩家编号小于6时,表示有人。 if (this._BodyIndexPixelData[colorIndex] < BodyColor.Length) { //根据编号,把颜色赋给像素,其他像素为白色。 this._BodyIndexData[colorIndex] = BodyColor[this._BodyIndexPixelData[colorIndex]]; } else { this._BodyIndexData[colorIndex] = 0x00000000; } } } //数组写到位图上 this._BodyIndexBitmap.WritePixels(this._BodyIndexBitmapRect, this._BodyIndexData, this._BodyIndexStride * 4, 0); } } }
比之前做的深度图像的测试,好一点点。
运行实例: