在我博客里,也多次提到了中值模糊的优化,比如以下两篇文章:
【算法随记三】小半径中值模糊的急速实现(16MB图7.5ms实现) + Photoshop中蒙尘和划痕算法解读。
任意半径中值滤波(扩展至百分比滤波器)O(1)时间复杂度算法的原理、实现及效果。
但是,这些都是这对8位图像的优化,也就是说图像的色阶最多只有256,如果把这个优化算法直接扩展到16位的RAW图像,有以下几个情况:
1、小半径的(3*3 / 5*5)的快速实现,是完全可以借鉴8位的处理方式的,而且速度依旧是非常出色的。
2、更大的半径的,如果直接沿用8位的处理方式(上述第二篇参考文章),有以下几个问题:
(1)对于10、12位的也许还可以,这种情况需要将直方图分别分解为32及64个粗分及细分直方图,然后进行处理,这个时候相关的直方图相加的计算量也会对应的增加,内部的中值的更新计算量也会相应的增加,整体耗时要比8位的增加2倍及4倍以上。
(2)对于14位及16位的图像,如果使用同样的处理方式,细分及粗分直方图的数量增加至128和256个,这个时候的增加的计算量非常客观了,已经不具备任何的性能优势,另外一个重要的问题是,相关的内存分配可能会失败,因为在O(1)时间复杂度的文章中,相关的内存需要下如以下代码所示:
当处理14位图时,H_Fine需要分配128*128*Width*sizeof(unsigned short)字节大小的内存,假定宽度为3072像素,这个尺寸在处理RAW数据时并不是很夸张的,那么H_Fine需要96MB的内存,如果是16位,则增加到384MB,了解计算机内存的都知道,分配这么大的连续内存是很有可能失败的。
当然,内存问题也许有其他的方案可以解决,但是核心的速度问题还是无法满足实际的需求的。
(3)如果是9位、11位、13位、15位这种图像,那其实直接使用8位的方式,除了上述两个问题外,还有就是粗分和细分直方图如何取舍,也是个研究点,当然,实际中我们很少遇到这样的格式,而且即使遇到了,也可以把他们当成向上一位的10/12/14/16格式处理,因为中值处理算法是不会增加新的像素值(在原图中原先不存在的像素色阶)的。
因此,我一直在寻找或者说构思一个能够快速处理unsigned short数据类型的通用的中值算法,不过这么多年也一直没有找到答案。
最近,来自安道尔(谁都知道怎么回事)微信朋友江向我咨询8位的中值和自适应中值能不能用到16位上,又让我在这个问题上摸索了半个月,无意中在GIMP的中值模糊中找到了问题的答案。
我比较了几个能处理16位图像的中值,粗略的做了个耗时统计:
同样大小的8位灰度图,使用SSE优化后的速度耗时约为0.13S。
测试时,我注意观察了下CPU的使用情况,可以确认PS、GIMP、ImageJ等都使用多线程,CPU使用率都接近100%,而OpenCv实测只支持滤波器为3*3或者5*5的16位图像的中值,后面我看了相关说明,确实有如下的讲法:
不过可以确认的是16位的中值也可以是做到非常快速的。既然GIMP也能做到那么快,那我们当然可以参考他

最低0.47元/天 解锁文章
1719

被折叠的 条评论
为什么被折叠?



