Class="ImageLibrarySamples.MainWindow"
xmlns="
xmlns:
x="
Title="ImageLibrarySamples">
现在来编写后台代码,与之前的类似,首先添加对Microsoft.Kinect.dll引用,然后声明KinectSensor对象并在MainWindows的构造函数中实例化,代码如下所示。
实例化KinectSensor对象,处理ColorFrameReady和DepthFrameReady事件,然后打开color和depth数据流。
Microsoft.Kinect.KinectSensor_kinectSensor;
publicMainWindow()
{
InitializeComponent();
this.Unloaded+=delegate
{
_kinectSensor.ColorStream.Disable();
_kinectSensor.DepthStream.Disable();
};
this.Loaded+=delegate
{
_kinectSensor=KinectSensor.KinectSensors[0];
_kinectSensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
_kinectSensor.DepthStream.Enable(DepthImageFormat.Resolution320x240Fps30);
_kinectSensor.ColorFrameReady+=ColorFrameReady;
_kinectSensor.DepthFrameReady+=DepthFrameReady;
_kinectSensor.Start();
};
}
voidDepthFrameReady(objectsender,DepthImageFrameReadyEventArgse)
{
}
voidColorFrameReady(objectsender,ColorImageFrameReadyEventArgse)
{
}
1.2.2创建类及扩展方法
在项目中创建一个新的名为ImageExtensions.cs的类来包含扩展方法。
这个类的实际名字并不重要,需要用到的只是命名空间。
在下面的代码中,我们使用的命名空间是ImageManipulationExtensionMethods。
另外,还需要添加对System.Drawing.dll的引用。
如前所述,System.Drawing和System.Windows.Media中有些类的名称是一样的。
为了消除命名空间的冲突,我们必须选取一个作为默认的命名空间。
在下面的代码中,我们将System.Drawing作为默认的命名空间,而给System.Windows.Media起了一个名为Media的别名。
最后,我们为最重要的两个图像转换创建了扩展方法。
一个是将字节序列(bytearray)转换为Bitmap对象,另一个是将字节序列(bytearray)转换为BitmapSource对象。
这两个扩展方法会用到彩色图像的显示中。
我们还创建了另外两个扩展方法,通过这些方法中的字节序列替换短字节序列(shortarray)来对深度影像进行变换,因为深度影像数据是由short类型而不是byte类型组成的。
namespaceImageManipulationExtensionMethods
{
publicstaticclassImageExtensions
{
publicstaticBitmapToBitmap(thisbyte[]data,intwidth,intheight
PixelFormatformat)
{
varbitmap=newBitmap(width,height,format);
varbitmapData=bitmap.LockBits(
newSystem.Drawing.Rectangle(0,0,bitmap.Width,bitmap.Height),
ImageLockMode.WriteOnly,
bitmap.PixelFormat);
Marshal.Copy(data,0,bitmapData.Scan0,data.Length);
bitmap.UnlockBits(bitmapData);
returnbitmap;
}
publicstaticBitmapToBitmap(thisshort[]data,intwidth,intheight
PixelFormatformat)
{
varbitmap=newBitmap(width,height,format);
varbitmapData=bitmap.LockBits(
newSystem.Drawing.Rectangle(0,0,bitmap.Width,bitmap.Height),
ImageLockMode.WriteOnly,
bitmap.PixelFormat);
Marshal.Copy(data,0,bitmapData.Scan0,data.Length);
bitmap.UnlockBits(bitmapData);
returnbitmap;
}
publicstaticMedia.Imaging.BitmapSourceToBitmapSource(thisbyte[]data
Media.PixelFormatformat,intwidth,intheight)
{
returnMedia.Imaging.BitmapSource.Create(width,height,96,96
format,null,data,width*format.BitsPerPixel/8);
}
publicstaticMedia.Imaging.BitmapSourceToBitmapSource(thisshort[]data
Media.PixelFormatformat,intwidth,intheight)
{
returnMedia.Imaging.BitmapSource.Create(width,height,96,96
format,null,data,width*format.BitsPerPixel/8);
}
}
}
1.2.3创建其它的扩展方法
现在影像流和深度流数据的字节序列都可以通过从ColorImageFrame和DepthImageFrame类型获取。
我们还可以创建一些额外的扩展方法来处理这些类型而不是字节序列。
获取bit序列数据并将其转换为Bitmap或者BitmapSource类型过程中,最重要的因素是考虑像元的格式。
影像数据流返回的是一系列32位的RGB影像,深度数据流返回的是一系列16位的RGB影像。
在下面的代码中,我们使用没有透明值的32个字节的影像数据作为默认的数据类型,也就是说,影像数据流可以简单的调用ToBitmap或者ToBitmapSource方法,其他扩展方法的名称应该给予影像数据格式一些提示。
//bitmapmethods
publicstaticBitmapToBitmap(thisColorImageFrameimage,PixelFormatformat)
{
if(image==null||image.PixelDataLength==0)
returnnull;
vardata=newbyte[image.PixelDataLength];
image.CopyPixelDataTo(data);
returndata.ToBitmap(image.Width,image.Height
format);
}
publicstaticBitmapToBitmap(thisDepthImageFrameimage,PixelFormatformat)
{
if(image==null||image.PixelDataLength==0)
returnnull;
vardata=newshort[image.PixelDataLength];
image.CopyPixelDataTo(data);
returndata.ToBitmap(image.Width,image.Height
format);
}
publicstaticBitmapToBitmap(thisColorImageFrameimage)
{
returnimage.ToBitmap(PixelFormat.Format32bppRgb);
}
publicstaticBitmapToBitmap(thisDepthImageFrameimage)
{
returnimage.ToBitmap(PixelFormat.Format16bppRgb565);
}
//bitmapsourcemethods
publicstaticMedia.Imaging.BitmapSourceToBitmapSource(thisColorImageFrameimage)
{
if(image==null||image.PixelDataLength==0)
returnnull;
vardata=newbyte[image.PixelDataLength];
image.CopyPixelDataTo(data);
returndata.ToBitmapSource(Media.PixelFormats.Bgr32,image.Width,image.Height);
}
publicstaticMedia.Imaging.BitmapSourceToBitmapSource(thisDepthImageFrameimage)
{
if(image==null||image.PixelDataLength==0)
returnnull;
vardata=newshort[image.PixelDataLength];
image.CopyPixelDataTo(data);
returndata.ToBitmapSource(Media.PixelFormats.Bgr555,image.Width,image.Height);
}
publicstaticMedia.Imaging.BitmapSourceToTransparentBitmapSource(thisbyte[]data
intwidth,intheight)
{
returndata.ToBitmapSource(Media.PixelFormats.Bgra32,width,height);
}
注意到上面的代码中有三种不同的像元格式。
Bgr32格式就是32位彩色影像,它由RGB三个通道。
Bgra32也是32位,但是她使用了第四个称之为alpha的通道,用来表示透明度。
最后Bgr555是16位影像格式。
在之前的深度影像处理那篇文章中,深度影像中的每一个像元都代表2个字节,555代表红绿蓝三个通道每一个通道占用5位。
在深度影像处理中,也可以使用Bgr565格式,这种格式中绿色通道占用6位,你也可以添加一个使用这种格式的扩展方法。
1.2.4调用扩展方法
为了在之前的MainWindows的后台代码中使用之前写的扩展方法,我们首先需要添加ImageManipulationExtensionMethods命名空间,这是扩展方法所在的命名空间。
现在利用这些扩展方法,我们能够方便的将影像和深度数据转换为字节数组了,如下代码:
voidDepthFrameReady(objectsender,DepthImageFrameReadyEventArgse)
{
this.depthImage.Source=e.OpenDepthImageFrame().ToBitmap().ToBitmapSource();
}
voidColorFrameReady(objectsender,ColorImageFrameReadyEventArgse)
{
this.rgbImage.Source=e.OpenColo