[KinectWPF程序]将深度图像用彩色图像表示,其实就是深度值和像素值的简单转换

来源:互联网 发布:脑基因优化健脑仪 编辑:程序博客网 时间:2024/04/29 22:08

[KinectWPF程序]将深度图像用彩色图像表示,其实就是深度值和像素值的简单转换

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using Microsoft.Kinect;namespace WpfApplication9{    /// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        KinectSensor kinectSensor;        private const int LowDepthThreshold = 800;        private const int HighDepthThreshold = 3000;        private const int DepthDistanceOffset = HighDepthThreshold - LowDepthThreshold;        //BGR32图像,红色、绿色、蓝色分别对应的偏移(32位,4字节中的第几个)        private const int RedIndex = 2;        private const int GreenIndex = 1;        private const int BlueIndex = 0;        short[] DepthValueData;        //初始化Kinect直接调用InitKinect()即可;注册的同步事件为AllFramesReadyEventArgs        /// <summary>        /// 启动Kinect设备,初始化选项,并注册AllFrameReady同步事件        /// </summary>        /// <param name="sender"></param>        /// <param name="e"></param>        private void InitKinect()        {            if (KinectSensor.KinectSensors.Count > 0)            {                kinectSensor = (from sensor in KinectSensor.KinectSensors                                where sensor.Status == KinectStatus.Connected                                select sensor).FirstOrDefault();                kinectSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);                kinectSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);                kinectSensor.SkeletonStream.Enable();                kinectSensor.Start();                kinectSensor.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(kinectSensor_AllFramesReady);            }            else            {                MessageBox.Show("没有检测到Kinect设备");            }        }        /// <summary>        /// 单色直方图计算公式,返回256色灰阶。颜色越黑约远,约白则约近。        /// 将DepthDistanceOffset控制在0~255的范围内        /// </summary>        /// <param name="distance">深度值,有效范围LowDepthThreshold到HighDepthThreshold之间</param>        /// <returns>256色灰阶</returns>        private static byte CalculateIntensityFromDepth(int distance)        {            return (byte)(255 - (255 * Math.Max(distance - LowDepthThreshold, 0) / (HighDepthThreshold)));        }        /// <summary>        /// 将深度数据帧转换成彩色图像帧        /// </summary>        private byte[] convertDepthFrameToColorFrame(DepthImageFrame depthFrame)        {            //创建Height*Width*4的RGB数组(Red,Green,Blue,empty byte)            Byte[] pixels = new byte[depthFrame.Height * depthFrame.Width * 4];            //Bgr32 - Blue,Green,Red,empty byte;            //Bgra32 - Blue,Green,Red,transparency            //需要为Bgra32设置透明度transparency,.NET默认设置该字节为0(全透明)            for (int depthIndex = 0, colorIndex = 0; depthIndex < DepthValueData.Length && colorIndex < pixels.Length;                depthIndex++, colorIndex += 4)            {                //用户分割,0代表该像素不属于用户身体,低3位字节代表被跟踪的使用者的索引编号                int player = DepthValueData[depthIndex] & DepthImageFrame.PlayerIndexBitmask;                //获得深度数值,高13位字节。                int depth = DepthValueData[depthIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;                //0.8m内                if (depth <= 800)                {                    //离Kinect很近                    pixels[colorIndex + BlueIndex] = 255;                    pixels[colorIndex + GreenIndex] = 0;                    pixels[colorIndex + RedIndex] = 0;                }                else if (depth > 800 && depth < 2000)                {                    pixels[colorIndex + BlueIndex] = 0;                    pixels[colorIndex + GreenIndex] = 255;                    pixels[colorIndex + RedIndex] = 0;                }                else if (depth > 2000)                {                    pixels[colorIndex + BlueIndex] = 0;                    pixels[colorIndex + GreenIndex] = 0;                    pixels[colorIndex + RedIndex] = 255;                }                //直方图着色                byte intensity = CalculateIntensityFromDepth(depth);                pixels[colorIndex + BlueIndex] = intensity;                pixels[colorIndex + GreenIndex] = intensity;                pixels[colorIndex + RedIndex] = intensity;                //如果是人体区域,用亮绿色标注                if (player > 0)                {                    pixels[colorIndex + BlueIndex] = Colors.LightGreen.B;                    pixels[colorIndex + GreenIndex] = Colors.LightGreen.G;                    pixels[colorIndex + RedIndex] = Colors.LightGreen.R;                }            }            return pixels;        }        public MainWindow()        {            InitializeComponent();        }        private void Button_Click(object sender, RoutedEventArgs e)        {            InitKinect();        }        void kinectSensor_AllFramesReady(object sender, AllFramesReadyEventArgs e)        {              //获取深度图像            using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())            {                if (depthFrame != null)                {                    //建立存储深度值的矩阵,一维矩阵                    //depthFrame.PixelDataLength每一帧的数据长度                    DepthValueData = new short[depthFrame.PixelDataLength];                    depthFrame.CopyPixelDataTo(DepthValueData);                    //将Kicent获取的深度值拷贝存储像素的矩阵中                    byte[] pixels = convertDepthFrameToColorFrame(depthFrame);                    //创建BGR32格式的图片                    ShowImage.Source = BitmapSource.Create(depthFrame.Width, depthFrame.Height, 96, 96, PixelFormats.Bgr32,                        null, pixels, depthFrame.Width * 4);                }            }        }    }}
0 0