KinectforWindowsSDK开发入门基础(三)-基础知识下.doc
《KinectforWindowsSDK开发入门基础(三)-基础知识下.doc》由会员分享,可在线阅读,更多相关《KinectforWindowsSDK开发入门基础(三)-基础知识下.doc(12页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、.-译Kinect for Windows SDK开发入门(三):基础知识 下1. 性能改进 上文的代码中,对于每一个彩色图像帧,都会创建一个新的Bitmap对象。由于Kinect视频摄像头默认采集频率为每秒30幅,所以应用程序每秒会创建30个bitmap对象,产生30次的Bitmap内存创建,对象初始化,填充像素数据等操作。这些对象很快就会变成垃圾等待垃圾回收器进行回收。对数据量小的程序来说可能影响不是很明显,但当数据量很大时,其缺点就会显现出来。 改进方法是使用WriteableBitmap对象。它位于System.Windows.Media.Imaging命名空间下面,该对象被用来处理需
2、要频繁更新的像素数据。当创建WriteableBitmap时,应用程序需要指定它的高度,宽度以及格式,以使得能够一次性为WriteableBitmap创建好内存,以后只需根据需要更新像素即可。 使用WriteableBitmap代码改动地方很小。下面的代码中,首先定义三个新的成员变量,一个是实际的WriteableBitmap对象,另外两个用来更新像素数据。每一幅图像的大小都是不变的,因此在创建WriteableBitmap时只需计算一次即可。InitializeKinect方法中加粗的部分是更改的代码。创建WriteableBitmap对象,准备接收像素数据,图像的范围同时也计算了。在初始化
3、WriteableBitmap的时候,同时也绑定了UI元素(名为ColorImageElement的Image对象)。此时WriteableBitmap中没有像素数据,所以UI上是空的。private WriteableBitmap colorImageBitmap;private Int32Rect colorImageBitmapRect;private int colorImageStride;private byte colorImagePixelData;if (kinectSensor != null) ColorImageStream colorStream=kinectSens
4、or.ColorStream; colorStream.Enable(); 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.
5、FrameWidth * colorStream.FrameBytesPerPixel; ColorImageElement.Source = this.colorImageBitMap; kinectSensor.ColorFrameReady += kinectSensor_ColorFrameReady; kinectSensor.Start(); 还需要进行的一处改动是,对ColorFrameReady事件响应的代码。如下图。首先删除之前创建Bitmap那部分的代码。调用WriteableBitmap对象的WritePixels方法来更新图像。方法使用图像的矩形范围,代码像素数据的数组
6、,图像的Stride,以及偏移(offset).偏移量通常设置为0。private void Kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) using (ColorImageFrame frame = e.OpenColorImageFrame() if (frame != null) byte pixelData = new byteframe.PixelDataLength; frame.CopyPixelDataTo(pixelData); this.colorImageBitmap.Writ
7、ePixels(this.colorImageBitmapRect, pixelData, this.colorImageStride, 0); 基于Kinect的应用程序在无论是在显示ColorImageStream数据还是显示DepthImageStream数据的时候,都应该使用WriteableBitmap对象来显示帧影像。在最好的情况下,彩色数据流会每秒产生30帧彩色影像,这意味着对内存资源的消耗比较大。WriteableBitmap能够减少这种内存消耗,减少需要更新影响带来的内存开辟和回收操作。毕竟在应用中显示帧数据不是应用程序的最主要功能,所以在这方面减少内像存消耗显得很有必要。2
8、. 简单的图像处理 每一帧ColorImageFrame都是以字节序列的方式返回原始的像素数据。应用程序必须以这些数据创建图像。这意味这我们可以对这些原始数据进行一定的处理,然后再展示出来。下面来看看如何对获取的原始数据进行一些简单的处理。void kinectSensor_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e) using (ColorImageFrame frame = e.OpenColorImageFrame() if (frame != null) byte pixelData = new byt
9、eframe.PixelDataLength; frame.CopyPixelDataTo(pixelData); for (int i = 0; i pixelData.Length; i += frame.BytesPerPixel) pixelDatai = 0x00;/蓝色 pixelDatai + 1 = 0x00;/绿色 this.colorImageBitMap.WritePixels(this.colorImageBitmapRect, pixelData,this.colorImageStride,0); 以上的实验关闭了每个像素点的蓝色和绿色通道。for循环遍历每个像素,使
10、得i的起始位置重视该像素的第一个字节。由于数据的格式是Bgr32,即RGB32位(一个像素共占4个字节,每个字节8位),所以第一个字节是蓝色通道,第二个是绿色,第三个是红色。循环体类,将第一个和第二个通道设置为0.所以输出的代码中只用红色通道的信息。这是最基本的图像处理。代码中对像素的操作和像素着色函数相识,可以通过很复杂的算法来进行。大家可以试试对这些像素赋予一些其它的值然后再查看图像的显示结果。这类操作通常很消耗计算资源。像素着色通常是GPU上的一些很基础的操作。下面有一些简单的算法用来对像素进行处理。 Inverted ColorpixelDatai=(byte)pixelDatai;p
11、ixelDatai+1=(byte)pixelDatai+1;pixelDatai+2=(byte)pixelDatai+2; Apocalyptic ZombiepixelDatai= pixelDatai+1;pixelDatai+1= pixelDatai;pixelDatai+2=(byte)pixelDatai+2; Gray scalebyte gray=Math.Max(pixelDatai,pixelDatai+1)gray=Math.Max(gray,pixelDatai+2);pixelDatai=gray;pixelDatai+1=gray;pixelDatai+2=gr
12、ay; Grainy black and white moviebyte gray=Math.Min(pixelDatai,pixelDatai+1);gray=Math.Min(gray,pixelDatai+2);pixelDatai=gray;pixelDatai+1=gray;pixelDatai+2 =gray; Washed out colordouble gray=(pixelDatai*0.11)+(pixelDatai+1*0.59)+(pixelDatai+2*0.3);double desaturation=0.75;pixelDatai=(byte)(pixelData
13、i+desaturation*(gray-pixelDatai);pixelDatai+1=(byte)(pixelDatai+1+desaturation*(gray-pixelDatai+1);pixelDatai+2=(byte)(pixelDatai+2+desatuation*(gray-pixelDatai+2); High saturationIf (pixelDatai0xE5)pixelDatai=0x00; else pixelDatai=0Xff;If (pixelDatai+10xE5) pixelDatai+1=0x00; else pixelDatai+1=0Xff
14、;If (pixelDatai+20xE5) pixelDatai+2=0x00; else pixelDatai+1=0Xff;一下是上面操作后的图像:3. 截图 有时候,可能需要从彩色摄像头中截取一幅图像,例如可能要从摄像头中获取图像来设置人物头像。为了实现这一功能,首先需要在界面上设置一个按钮,代码如下: private void TakePictureButton_Click(object sender, RoutedEventArgs e) String fileName = snapshot.jpg; if (File.Exists(fileName) File.Delete(fi
15、leName); using (FileStream savedSnapshot=new FileStream(fileName,FileMode.CreateNew) BitmapSource image =(BitmapSource) ColorImageElement.Source; JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder(); jpgEncoder.QualityLevel = 70; jpgEncoder.Frames.Add(BitmapFrame.Create(image); jpgEncoder.Save(sav
16、edSnapshot); savedSnapshot.Flush(); savedSnapshot.Close(); savedSnapshot.Dispose(); 为了演示,上面的代码中在当前目录创建了一个文件名。这是一种简单保存文件的方法。我们使用FileStream打开一个文件。JpegBitmapEncoder对象将UI上的图像转换为一个标准的JPEG文件,保存完后,需要调用对象的flush方法,然后关闭,最后释放对象。虽然这三部不需要,因为我们使用了using语句,这里是为了演示,所以把这三步加上了。4. ColorImageStream对象图 到此为止,我们讨论了如何发现以及初始
17、化Kinect传感器,从Kinect的影像摄像头获取图片。现在让我们来看看一些关键的类,以及他们之间的关系。下图展现了ColorImageStream的对象模型图。 ColorImageStream是KinectSensor对象的一个属性,如同KinectSensorde其它流一样,色彩数据流在使用之前需要调用Enable方法。ColorImageStream有一个重载的Enabled方法,默认的Eanbled方法没有参数,重载的方法有一个ColorImageFormat参数,他是一个枚举类型,可以使用这个参数指定图像格式。下表列出了枚举成员。默认的Enabled将ColorImageStre
18、am设置为每秒30帧的640*480的RGB影像数据。一旦调用Enabled方法后,就可以通过对象的Foramt属性获取到图像的格式了。 ColorImageStream 有5个属性可以设置摄像头的视场。这些属性都以Nominal开头,当Stream被设置好后,这些值对应的分辨率就设置好了。一些应用程序可能需要基于摄像头的光学属性比如视场角和焦距的长度来进行计算。ColorImageStream建议程序员使用这些属性,以使得程序能够面对将来分辨率的变化。 ImageStream是ColorImageStream的基类。因此ColorImageStream集成了4个描述每一帧每一个像素数据的属性
19、。在之前的代码中,我们使用这些属性创建了一个WriteableBitmap对象。这些属性与ColorImageFormat的设置有关。ImageStream中除了这些属性外还有一个IsEnabled属性和Disable方法。IsEnabled属性是一个只读的。当Stream打开时返回true,当调用了Disabled方法后就返回false了。Disable方法关闭Stream流,之后数据帧的产生就会停止,ColorFrameReady事件的触发也会停止。当ColorImageStream设置为可用状态后,就能产生ColorImageFrame对象。ColorImageFrame对象很简单。他有
20、一个Format方法,他是父类的ColorImageFormat值。他只有一个CopyPixelDataTo方法,能够将图像的像素数据拷贝到指定的byte数组中,只读的PixelDataLength属性定义了数组的大小PixelDataLength属性通过对象的宽度,高度以及每像素多少位属性来获得的。这些属性都继承自ImageFrame抽象类。 数据流的格式决定了像素的格式,如果数据流是以ColorImageFormat.RgbResolution640*480Fps30格式初始化的,那么像素的格式就是Bgr32,它表示每一个像素占32位(4个字节),第一个字节表示蓝色通道值,第二个表示绿色,
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- kinectforwindowssdk 开发 入门 基础 基础知识
限制150内