[Kinect&Emgu]拉数据方式(延时)获得图像的方法、 对[封装1]和[封装2]简单应用、在拉数据模式下,对WriteableBitmap写入数据,需要采用this.ShowImage.Dispatcher.BeginInvoke方法,否则无法写入数据
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;
using System.Runtime.InteropServices;
using System.ComponentModel;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.Util;
using ImageManipulationExtensionMethods;
/*******本示例包括一下信息*******/
//采用拉数据方法获得数据,类似延时。
//在拉数据模式下,对WriteableBitmap写入数据,需要采用this.ShowImage.Dispatcher.BeginInvoke方法,否则无法写入数据。
//命名空间ImageManipulationExtensionMethods下ToOpenCVImage()简单应用。
//单帧图像获取方法
/*******需要引入的命名空间*******/
//using Microsoft.Kinect;
//using System.Runtime.InteropServices;
//using System.ComponentModel;
//using Emgu.CV;
//using Emgu.CV.CvEnum;
//using Emgu.CV.Structure;
//using Emgu.Util;
//using ImageManipulationExtensionMethods;
namespace WpfApplication11
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
KinectSensor kinectSensor;
/**************************************************************************************/
private WriteableBitmap colorImageBitMap;
private Int32Rect colorImageBitmapRect;
private int colorImageStride;
/**************************************************************************************/
ColorImageFrame colorFrame;
byte[] ColorPixelData;
//初始化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();
/**************************************************************************************/
//创建WriteableBitmap对象,准备接收像素数据
ColorImageStream colorStream = kinectSensor.ColorStream;
this.colorImageBitMap = new WriteableBitmap(colorStream.FrameWidth,
colorStream.FrameHeight, 96, 96, PixelFormats.Bgr32, null);
this.colorImageBitmapRect = new Int32Rect(0, 0, colorStream.FrameWidth,
colorStream.FrameHeight);
this.colorImageStride = colorStream.FrameWidth * colorStream.FrameBytesPerPixel;
ShowImage.Source = this.colorImageBitMap;
/**************************************************************************************/
kinectSensor.Start();
/**************************************************************************************/
BackgroundWorker bw = new BackgroundWorker();
//Lambda表达式用'=>'运算符表明什么参数传递给表达式。
//编译器进一步处理,允许我们忽略类型并自动替我们推断这些类型。
//如果你有2个或更多个参数,你需要用圆括号:(x,y)=>。如果只有一个,直接设置:x=>
bw.DoWork += (a, b) => Pulse();
bw.RunWorkerCompleted += (c, d) => bw.RunWorkerAsync();
bw.RunWorkerAsync();
/**************************************************************************************/
}
else
{
MessageBox.Show("没有检测到Kinect设备");
}
}
public MainWindow()
{
InitializeComponent();
this.Unloaded += delegate
{
kinectSensor.ColorStream.Disable();
};
this.Loaded += delegate
{
InitKinect();
};
}
/**************************************************************************************/
private void Pulse()
{
/**************************************************************************************/
//OpenNextFrame(200),这里的200以毫秒为单位,帧采集的间隔
//类似通过延时的方法采集数据。
using (colorFrame = kinectSensor.ColorStream.OpenNextFrame(200))
{
/**************************************************************************************/
if (colorFrame == null)
return;
/**************************************************************************************/
//这里的ToOpenCVImage就是调用的命名空间ImageManipulationExtensionMethods中的方法
using (Image<Bgr, byte> image = colorFrame.ToOpenCVImage<Bgr, byte>())
{
/**************************************************************************************/
//建立存储像素的矩阵,一维矩阵
//colorFrame.PixelDataLength每一帧的数据长度
ColorPixelData = new byte[colorFrame.PixelDataLength];
//将Kicent获取的彩色像素拷贝存储像素的矩阵中
colorFrame.CopyPixelDataTo(ColorPixelData);
/**************************************************************************************/
//显示图像,ShowImage为Image控件
//使用拉模式采集数据,如果要显示到Image控件上,必须使用 this.ShowImage.Dispatcher.BeginInvoke方法
this.ShowImage.Dispatcher.BeginInvoke(new Action(() =>
{this.colorImageBitMap.WritePixels(this.colorImageBitmapRect, ColorPixelData, this.colorImageStride, 0);}));
/**************************************************************************************/
}
}
}
/**************************************************************************************/
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
this.ShotImage.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96,
PixelFormats.Bgr32, null, ColorPixelData, colorFrame.Width * colorFrame.BytesPerPixel);
}
}
}