kinect2.0 基础篇第3篇 用C#在Visual Studio上编写把深度图像转换成彩色图像
Posted 1988博客园
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kinect2.0 基础篇第3篇 用C#在Visual Studio上编写把深度图像转换成彩色图像相关的知识,希望对你有一定的参考价值。
本示例实现的功能有:有两个Radiobutton控件 选一个,点击启动按钮,
第一个是将深度图像转换成彩色图像
第二个是将深度图像做一些简单处理(例如太暗的调白一点)
涉及到一点遥感图像处理知识,将深度数据值转换为色调和饱和度
遥感图像处理那块不懂,有兴趣的自己可以研究研究,代码的基于kinect1的教程,慢慢尝试出来的,虽然功能实现了,但是原理还不是很懂
<Window x:Class="EnhancedDepthWPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:EnhancedDepthWPF" mc:Ignorable="d" Title="MainWindow" Height="520" Width="525"> <Grid Background="Gray" Width="512" Height="500" > <Grid VerticalAlignment="Top"> <Grid HorizontalAlignment="Left"> <RadioButton x:Name="radioBtnColor" Content="彩色的深度图像" /> </Grid> <Grid HorizontalAlignment="Center"> <RadioButton x:Name="radioBtnCommon" Content="普通的深度图像" IsChecked="True"/> </Grid> <Button x:Name="btnStartSensor" Click="btnStartSensor_Click" Content="启动kinect" HorizontalAlignment="Right"/> </Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="9*"/> <ColumnDefinition Width="5*"/> </Grid.ColumnDefinitions> <Image x:Name="EnhancedDepthImage" Width="512" Height="424" Grid.ColumnSpan="2" Margin="3,0,3.4,-104"/> </Grid> </Grid> </Window>
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; 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 EnhancedDepthWPF { /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { private KinectSensor sensor; private DepthFrameReader depthReader; private FrameDescription depthDescription; private WriteableBitmap depthBitmap; private Int32Rect depthRect; private int depthStride; ushort[] pixelData; Int32 depth; Int32 loThreshold = 50; //最近能测距离50mm Int32 hiThreshold = 450; //最远能测距离450mm Int32 bytesPerPixel = 4; //32位彩色图像,4字节 byte[] enhPixelData; //用于保存彩色图像的数据 public MainWindow() { InitializeComponent(); sensor = KinectSensor.GetDefault(); depthReader = sensor.DepthFrameSource.OpenReader(); depthReader.FrameArrived += depthFrame_FrameArrived; depthDescription = sensor.DepthFrameSource.FrameDescription; enhPixelData = new byte[depthDescription.Width * depthDescription.Height * bytesPerPixel]; } private void depthFrame_FrameArrived(object sender, DepthFrameArrivedEventArgs e) { using (DepthFrame depthFrame = e.FrameReference.AcquireFrame()) { if (depthFrame != null) { depthFrame.CopyFrameDataToArray(pixelData); if (radioBtnColor.IsChecked == true) { enhPixelData= DepthToColorImage(ref pixelData); depthBitmap.WritePixels(depthRect, enhPixelData, depthStride, 0); } else { DepthCommonImage(ref pixelData); depthBitmap.WritePixels(depthRect, pixelData, depthStride, 0); } } } } private void DepthCommonImage(ref ushort[] pixelData) { //在数字光谱中0代表黑色,65536(16位灰阶)表示白色 for (int i = 0; i < pixelData.Length; i++) { depth = pixelData[i] >> 3; //把像素数据转换成深度数据 if (depth < loThreshold || depth > hiThreshold) //正常识别范围0.5m-4.5 { pixelData[i] = 35000; } else { pixelData[i] += 20000; //太黑了,把颜色整体调白一点 } //pixelData[i] = (ushort)~pixelData[i]; //按位翻转像素值 } } private byte[] DepthToColorImage(ref ushort[] pixelData) { byte[] rgb = new byte[3]; Double hue; for (int i = 0, j = 0; i < pixelData.Length; i++, j += bytesPerPixel) { depth = pixelData[i] >> 3; if (depth < loThreshold || depth > hiThreshold) { enhPixelData[j] = 0x00; enhPixelData[j + 1] = 0x00; enhPixelData[j + 2] = 0x00; } else { hue = ((360 * depth / 0xFF) + loThreshold); ConvertHslToRgb(hue, 100, 100, rgb); enhPixelData[j] = rgb[2]; //Blue enhPixelData[j + 1] = rgb[1]; //Green enhPixelData[j + 2] = rgb[0]; //Red } } return enhPixelData; } /// <summary> /// 遥感图像处理,将深度数据值转换为色调和饱和度 /// </summary> /// <param name="hue">色调</param> /// <param name="saturation">饱和度</param> /// <param name="lightness">亮度</param> /// <param name="rgb"></param> private void ConvertHslToRgb(Double hue, Double saturation, Double lightness, byte[] rgb) { Double red = 0.0; Double green = 0.0; Double blue = 0.0; hue = hue % 360.0; saturation = saturation / 100.0; lightness = lightness / 100.0; if (saturation == 0.0) { red = lightness; green = lightness; blue = lightness; } else { Double huePrime = hue / 60.0; Int32 x = (Int32)huePrime; Double xPrime = huePrime - (Double)x; Double L0 = lightness * (1.0 - saturation); Double L1 = lightness * (1.0 - (saturation * xPrime)); Double L2 = lightness * (1.0 - (saturation * (1.0 - xPrime))); switch (x) { case 0: red = lightness; green = L2; blue = L0; break; case 1: red = L1; green = lightness; blue = L0; break; case 2: red = L0; green = lightness; blue = L2; break; case 3: red = L0; green = L1; blue = lightness; break; case 4: red = L2; green = L0; blue = lightness; break; case 5: red = lightness; green = L0; blue = L1; break; } } rgb[0] = (byte)(255.0 * red); rgb[1] = (byte)(255.0 * green); rgb[2] = (byte)(255.0 * blue); } private void btnStartSensor_Click(object sender, RoutedEventArgs e) { //存放深度图像的字节数组的长度=帧长度*帧高度 pixelData = new ushort[depthDescription.LengthInPixels]; if (radioBtnColor.IsChecked == true) { depthBitmap = new WriteableBitmap(depthDescription.Width, depthDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null); //根据数据帧的宽高创建colorBitmap的实例 this.depthRect = new Int32Rect(0, 0, this.depthBitmap.PixelWidth, depthBitmap.PixelHeight); this.depthStride = this.depthDescription.Width * 4; EnhancedDepthImage.Source = this.depthBitmap; } else { //位图初始化,宽度,高度,96.0表示分辨率,像素格式 depthBitmap = new WriteableBitmap(depthDescription.Width, depthDescription.Height, 96.0, 96.0, PixelFormats.Gray16, null); //存放图像像素的矩形框 depthRect = new Int32Rect(0, 0, depthBitmap.PixelWidth, depthBitmap.PixelHeight); //步长:宽度*2(字节/像素) depthStride = depthDescription.Width * 2; EnhancedDepthImage.Source = depthBitmap; } sensor.Open(); } } }
运行结果如下:
以上是关于kinect2.0 基础篇第3篇 用C#在Visual Studio上编写把深度图像转换成彩色图像的主要内容,如果未能解决你的问题,请参考以下文章