因为微软本身的绿屏很简单,边缘十分粗糙,因此学弟项目需要优化kinectV2绿屏技术(也就是背景移除),今天我下午窝在宿舍,就配置很久没用过的opencv尝试了下实现这个算法,如何进行优化。配置opencv时差点没配置成功,原来把路径填错地方了,说真的那几个引用目录、包含目录什么的真的很容易混淆啊。
在实现kinect2绿屏技术也就是green screen时,我总结出几点,告诉大家避免入坑:
1.直接使用MapDepthFrameToColorSpace函数对深度数据投影到彩色空间会很卡。可以通过bodyindex判断哪些点需要单独处理,调用MapDepthPointsToColorSpace方法(最少可以对一个坐标投影)对所需要的坐标投影即可。
2.投影后的得到的坐标很可能是无效的,可以通过isnan判断是否有效,对无效的数据最好不要处理,忽略掉。其他投影函数也会得到无效的坐标,这点要注意。
3.当然由于无效数据肯定会有,并且有时投影可能从小的投到大的必然存在孔洞,这时就需要填补这些孔洞,并且尽可能圆滑边缘。
由于这个算法还在优化中,并且将作为产品,代码就不能提供给大家了。如果有需要购买算法(C++源码,目前正在移植到emgucv上,还不清楚emgucv效率如何),可以和我联系(网站右上角–>本站–>关于我,可以找到我的联系方式)。
下面是一些我计算过程和结算结果的图,大家可以看看,以下图片都是纯算法保存的结果,不含人工处理(如果人工ps下那还搞毛算法。。。):
投影后的无字天书图:
对点点图进行填充,我也不知道这图为啥会有一种三维效果,囧,我没用到三维信息啊:
首先看微软的效果(微软的图本来是bmp,我这里另存为jpg,肉眼看上去是一致的哈),注意边缘像素:
我弄了两种算法,这是算法一的结果(图是1920*1080的,可以右键保存下来看细节),仔细比较边缘确实好很多。方法一的处理方式确实有点复杂,其中还涉及到一些算法优化,不然达不到很高的实时性:
这是方法二,放大图片仔细观察后,你可以看到方法二锯齿很大,因为方法二的处理是对微软方法流程上的一些优化得到,因此锯齿会大,但效果依旧比微软原始的好:
除了绿屏技术,这次顺便也做了边缘检测,这是一种算法的效果。可见检测出很多边缘,真正使用时我们还需要判断下哪个边缘是比较大的,排除掉其他边缘的噪声(也就是图中非红色的边缘):