Kinect深度图像滤波
2015-06-19 00:49
183 查看
最近在做机器视觉方面的一点工作,用Kinect作sensor获取深度数据、颜色、手势识别等。非常感激CNBlog上的两篇博文:(1)独钓寒江的http://www.cnblogs.com/yangecnu/archive/2012/03/30/KinectSDK_Geting_Started.html 从中学到了不少关于在WPF平台上使用C#,利用微软Kinect SDK开发自己的应用程序的知识,给了我很大的帮助,在此表示感谢!
但是博主独钓寒江的博文中,针对深度图像滤波,只简要说了取反和用Bgr32表示深度图像,效果不是很理想。
后来,发现了另一篇博文(2)何文西的http://www.cnblogs.com/TravelingLight/archive/2012/05/25/2517680.html介绍了国外的一篇文章,上面介绍了外国作者自己开发的两种滤波方法:像素滤波法,加权移动平均法。效果很好!可惜只有代码片段无法试验,而且滤波算法不是特别容易理解。实在可惜!
前几天偶然跟踪并找到了作者的源代码http://kinectdepthsmoothing.codeplex.com/,下载来看。运行发现,程序要求:VS2012以上、Kinect SDK 1.7以上版本,而根据独钓寒江的博文指导,其中的代码用的是SDK 1.0,进一步发现其中的一些API函数,数据类型都不相同,再者,Kinectdepthsmoothing中xaml代码用的是后台创建,而独钓寒江的博文中xaml用的是布局式,而我对xaml又不懂,如何把这两个程序结合起来呢?
由于独钓寒江的博文给出的程序中,有大量的功能实现,比如保存图像、鼠标单击显示像素深度值、彩色渲染、人体尺寸获取,游戏者索引等等,而外国朋友的kinectdepthsmoothing程序只有滤波和保存图像,那么考虑把滤波模块移植到独钓寒江的程序中,并且不改变原来的布局式界面。在移植的过程中,主要解决了以下几个类型不兼容的问题:
a) 将short[] pixelData类型改成DepthImagePixel[] pixelData,这里注意:SDK 1.8版本中,private DepthImagePixel[] depthPixels;其中获取深度数据为
short depth=depthPixels[i].Depth;
而SKD 1.0版本中,short[] pixelData获取深度数据的方式为
Int32 depth = this.depthPixels[pIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;
需要进行移位操作。而且两种方式的depth类型不一样,一个是short16位,一个是Int32位。
b) 用三通道Bgr32格式的colorBitmap存储深度图像,而不是Gray16格式的depthBitmap。除了深度数组的格式不一样之外,外国朋友的程序中,有这样几行代码值得关注,
以及
最后将数据写入colorBitmap时,代码为
使用了 this.colorBitmap.PixelWidth这个写法,而不是独钓寒江博主的程序中,使用depthStream.FrameHeight创建图像的矩形区域this.depthRect = new Int32Rect(0, 0, depthStream.FrameWidth, depthStream.FrameHeight);
c) 此外,初始化变量(数据容器depthPixels和colorPixels)时,要注意colorPixels的大小
总之,将两个程序结合起来,要注意两个方面,一是界面的形式,布局还是后台创建,二是,.cs程序中由于使用的SDK版本不同,有很多API和数据类型不一致的地方,需要修改。由于正在做后续的实验,比如加入了自己的利用深度数据进行边缘检测的代码,还有很多想法没有实现,暂时写到这里吧。到时候会将完整代码上传到网络上,供大家参考!谢谢。
下篇文章将介绍基于深度值的目标分割,并附上完整代码。
但是博主独钓寒江的博文中,针对深度图像滤波,只简要说了取反和用Bgr32表示深度图像,效果不是很理想。
后来,发现了另一篇博文(2)何文西的http://www.cnblogs.com/TravelingLight/archive/2012/05/25/2517680.html介绍了国外的一篇文章,上面介绍了外国作者自己开发的两种滤波方法:像素滤波法,加权移动平均法。效果很好!可惜只有代码片段无法试验,而且滤波算法不是特别容易理解。实在可惜!
前几天偶然跟踪并找到了作者的源代码http://kinectdepthsmoothing.codeplex.com/,下载来看。运行发现,程序要求:VS2012以上、Kinect SDK 1.7以上版本,而根据独钓寒江的博文指导,其中的代码用的是SDK 1.0,进一步发现其中的一些API函数,数据类型都不相同,再者,Kinectdepthsmoothing中xaml代码用的是后台创建,而独钓寒江的博文中xaml用的是布局式,而我对xaml又不懂,如何把这两个程序结合起来呢?
由于独钓寒江的博文给出的程序中,有大量的功能实现,比如保存图像、鼠标单击显示像素深度值、彩色渲染、人体尺寸获取,游戏者索引等等,而外国朋友的kinectdepthsmoothing程序只有滤波和保存图像,那么考虑把滤波模块移植到独钓寒江的程序中,并且不改变原来的布局式界面。在移植的过程中,主要解决了以下几个类型不兼容的问题:
a) 将short[] pixelData类型改成DepthImagePixel[] pixelData,这里注意:SDK 1.8版本中,private DepthImagePixel[] depthPixels;其中获取深度数据为
short depth=depthPixels[i].Depth;
而SKD 1.0版本中,short[] pixelData获取深度数据的方式为
Int32 depth = this.depthPixels[pIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;
需要进行移位操作。而且两种方式的depth类型不一样,一个是short16位,一个是Int32位。
b) 用三通道Bgr32格式的colorBitmap存储深度图像,而不是Gray16格式的depthBitmap。除了深度数组的格式不一样之外,外国朋友的程序中,有这样几行代码值得关注,
//获得当前帧最大和最小可用的深度值 short minDepth = (short)lastDepthFrame.MinDepth; short maxDepth = (short)lastDepthFrame.MaxDepth;
以及
//在这里将depthPixels数组中的深度值,逐元素,转换并存储到colorPixles中 //最后,将colorPixels写入colorBitmap中 int colorPixelIndex = 0; for (int i = 0; i < depthPixels.Length; i++) { //获取该元素(点)的深度值 short depth = depthPixels[i].Depth; byte intensity = (byte)255; int newMax = depth - minDepth; if (newMax > 0) {intensity = (byte)(255 - (255 * newMax / (3150))); } this.colorPixels[colorPixelIndex++] = intensity;//blue this.colorPixels[colorPixelIndex++] = intensity;//green this.colorPixels[colorPixelIndex++] = intensity;//red ++colorPixelIndex; }
最后将数据写入colorBitmap时,代码为
this.colorBitmap.WritePixels( new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight), this.colorPixels, this.colorBitmap.PixelWidth * sizeof(int), 0);
使用了 this.colorBitmap.PixelWidth这个写法,而不是独钓寒江博主的程序中,使用depthStream.FrameHeight创建图像的矩形区域this.depthRect = new Int32Rect(0, 0, depthStream.FrameWidth, depthStream.FrameHeight);
c) 此外,初始化变量(数据容器depthPixels和colorPixels)时,要注意colorPixels的大小
this.depthPixels = new DepthImagePixel[depthStream.FramePixelDataLength]; this.colorPixels = new byte[depthStream.FramePixelDataLength * sizeof(int)];
总之,将两个程序结合起来,要注意两个方面,一是界面的形式,布局还是后台创建,二是,.cs程序中由于使用的SDK版本不同,有很多API和数据类型不一致的地方,需要修改。由于正在做后续的实验,比如加入了自己的利用深度数据进行边缘检测的代码,还有很多想法没有实现,暂时写到这里吧。到时候会将完整代码上传到网络上,供大家参考!谢谢。
下篇文章将介绍基于深度值的目标分割,并附上完整代码。
相关文章推荐
- Decorator Pattern
- apt-cyg package management cli for cygwin
- 「深入Exchange 2013」00 挖坑立碑
- Python正则表达式指南(转)
- 《人月神话》2
- EasyUI上传图片,前台预览,后台读取
- 团队博客第五周 运行与总结
- UNIX环境高级编程之-----信号signal
- hdu 2476 String painter(区间dp)
- .NET跨平台:在CentOS上编译dnx并运行ASP.NET 5示例程序
- net use命令
- Nearest Sequence(lcs)
- .NET跨平台:在CentOS上编译dnx并运行ASP.NET 5示例程序
- .NET跨平台:在CentOS上编译dnx并运行ASP.NET 5示例程序
- Ruby On Rails -- 开发流程
- 顺序表 简单功能
- Linux下不重启永久修改hostname
- 笔记
- Java将网络地址对应的图片转成本地的图片
- Java将网络地址对应的图片转成本地的图片