C#WPF + Kinect V1开发,获取IR & RGB Raw Data

来源:互联网 发布:网内通讯软件 编辑:程序博客网 时间:2024/05/16 10:35

Kinect V1深度图重构原理,基于PrimeSense 公司提供的一种编码结构光(激光散斑)技术对三维空间进行深度编码,摄像头不同距离产生的激光散斑图案唯一可区分,通过计算物体表面pattern图案与指定参考平面pattern的相关性,可以计算实际物体表面的深度信息。

1. Kinect V1 sdk+toolkit

sdk1.8.0 & toolkit1.8.0 下载地址:https://www.microsoft.com/en-us/download/

Kinect V1 Demo简介:

1.1) Kinect Explorer - D2D

同时捕获Color Stream, Depth Stream,并且能够调节sensor settings 主要是俯仰角度。


1.2) Kinect Skelton Basis ——可以获取人体骨骼信息


1.3) Kinect Controls Basis——可以通过手掌控制左右移动


1.4) Kinect Speech Basis——语音控制


2. C# WPF读取kinect设备,获取Raw Data

2.1在实际编程中,我们可以根据需求选取不同的图像数据格式,在Kinect for windows的API中,彩色图像类型用 ColorImageFormat表示,可枚举的值如下:

  在实际工程中,如何利用Kinect获取彩色数据与红外数据流,并实现静态图片的抓取,具体的过程如下:

Step1. 创建WPF工程。打开VS2010,新建WPF工程,并命名为 KinectColorViewer。

Step2. 添加 Kinect SDK程序集的引用。Solution Explorer -》右键 Reference -》Add reference -》添加 Microsoft.Kinect.

Step3. 添加控件。双击打开MainWindow.xaml文件,在设计器中添加一个Image控件,另外还添加一个“保存图片”的按钮。用于显示和保存获取到的图像,对应的MainWindow.xaml中的代码如下:

<Grid>        <Image Height="480" HorizontalAlignment="left"               Name="ColorImage" Stretch="Fill" VerticalAlignment="Top" Width="640" />        <Button x:Name="saveButton" Content="保存图片" Margin="645,60,0,389"                Click="saveButton_Click" VerticalAlignment="Center" RenderTransformOrigin="0.538, -0.638"                 Height="30" HorizontalAlignment="Left" Width="77"/>        </Grid>

Step4. 添加窗口加载和关闭函数,打开MainWindow.xaml设计器,在“Properties”中选择“Events”选项卡,找到“Loaded”和“Closed”事件,双击添加相应事件处理函数。

Title="MainWindow" Height="518" Width="750" Closed="Window_Closed" Loaded = "Window_Loaded">

Step5. 引用命名空间并添加事件函数,打开MainWindow.xaml.cs,主体代码如下:

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; //使用命名空间using System.IO;using System.Threading;namespace KinectColorViewer{    /// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        KinectSensor kinectSensor; //定义 KinectSensor对象        private byte[] pixelData;  //存放获取到的图像数据        WriteableBitmap writeableBitmap = null;        int width = 0;        int height = 0;        bool takePicture = false;        BitmapSource pictureBitmap = null;        Thread updateVideoThread;        bool displayActive = true;        public MainWindow()        {            InitializeComponent();        }        private void Window_Loaded(object sender, EventArgs e)        {            if (KinectSensor.KinectSensors.Count == 0)            {                MessageBox.Show("No kinect detected", "Camera Viewer");                Application.Current.Shutdown();            }            try            {                kinectSensor = KinectSensor.KinectSensors[0];                kinectSensor.ColorStream.Enable();                //kinectSensor.ColorStream.Enable(ColorImageFormat.RawBayerResolution640x480Fps30);                //kinectSensor.ColorStream.Enable(ColorImageFormat.InfraredResolution640x480Fps30);//infrared pattern                kinectSensor.Start();            }            catch            {                MessageBox.Show("The first kinect initialize failed", "Camera Viewer");                Application.Current.Shutdown();             }            updateVideoThread = new Thread(new ThreadStart(videoDisplay));            updateVideoThread.Start();        }        void videoDisplay()        {            while (displayActive)            {                using (ColorImageFrame colorFrame = kinectSensor.ColorStream.OpenNextFrame(10))                {                    if (colorFrame == null) continue;                    if (pixelData == null)                        pixelData = new byte[colorFrame.PixelDataLength];                    width = colorFrame.Width;                    height = colorFrame.Height;                    colorFrame.CopyPixelDataTo(pixelData);                    if (takePicture)                    {                        pictureBitmap = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96,                            PixelFormats.Bgr32, null, pixelData, colorFrame.Width * colorFrame.BytesPerPixel);                        //infrared pattern                        //pictureBitmap = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96,                         //PixelFormats.Gray16, null, pixelData, colorFrame.Width * colorFrame.BytesPerPixel);                        takePicture = false;                    }                    Dispatcher.Invoke(new Action(() => updateDisplay()));                }            }            kinectSensor.Stop();        }        void updateDisplay()        {            if (writeableBitmap == null)            {                this.writeableBitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Bgr32, null);                //this.writeableBitmap = new WriteableBitmap(width, height, 96, 96, PixelFormats.Gray16, null);//infrared pattern                ColorImage.Source = writeableBitmap;            }            writeableBitmap.WritePixels(new Int32Rect(0, 0, width, height), pixelData, width * 4, 0);            //writeableBitmap.WritePixels(new Int32Rect(0, 0, width, height), pixelData, width * 2, 0);//infrared pattern        }        private void saveButton_Click(object sender, RoutedEventArgs e)        {            takePicture = true;            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();            dlg.FileName = "kinectShot";            dlg.DefaultExt = ".bmp";            dlg.Filter = "Pictures(.bmp)|*.bmp";            if (dlg.ShowDialog() == true)            {                string filename = dlg.FileName;                using (FileStream stream = new FileStream(filename, FileMode.Create))                {                    //save bytes of pixelData                    System.IO.File.WriteAllBytes(filename.Substring(0,filename.Length - 4) + ".txt", pixelData);                    BmpBitmapEncoder encoder = new BmpBitmapEncoder();                    encoder.Frames.Add(BitmapFrame.Create(writeableBitmap));                    encoder.Save(stream);                }            }        }        private void Window_Closed(object sender, EventArgs e)        {            kinectSensor.Stop();            displayActive = false;        }    }}

2.2 彩色与红外数据获取方式区别

彩色数据对应的数据流格式为:kinectSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);

红外数据对应的数据流格式为:kinectSensor.ColorStream.Enable(ColorImageFormat.InfraredResolution640x480Fps30);

彩色数据pixelFormat:PixelFormats.Bgr32

红外数据pixelFormat:PixelFormats.Gray16

彩色数据写入像素数据:writeableBitmap.WritePixels(new Int32Rect(0, 0, width, height), pixelData, width * 4, 0);

红外数据写入像素数据:writeableBitmap.WritePixels(new Int32Rect(0, 0, width, height), pixelData, width * 2, 0);

2.3 获取的图像Raw数据


2.4 保存的Raw Data -- Gray16,第一位为低位,第二位为高位   (06 C0)h = 1728




原创粉丝点击