[db:标题]

摘要:浮点数据集如何实现快速的中值滤波,这个问题困扰我大概有20年,百度也一直没有找到过比较合适的解决方案,然而在有些情况下确实需要这类数据的中值处理。在昨日实现16位图像中值滤波的基础上,结合GIMP的相关技巧,终于客服了这个问题。
昨天实现了16位unsigned short数据的高效中值模糊算法,后面就在想其实我还有一个中值算法一直没有想到好的解决方案,那就是浮点数的中值,这个在某些场合还是有较高的应用价值的。   同样,3*3或者5*5的浮点中值可以直接实现,而且效率一样非常高。   其他半径的了,怎么办,浮点数嘛,不能使用直方图,而且数据范围也很广,不像8位或者16位数据范围都是有限的。这两个问题我一直没有想到解决之道。 在【16位RAW图像处理五】任意位深16位图像的中值模糊快速实现及其应用一文中看到了解析了Gimp的median_blur实现,文章最后我们提到了GIMP里用了排序获取局部图像的实际使用的色阶数以及对原始色阶做压缩处理,在哪里这个压缩主要是为了提高速度,一切看起来都是那么的自然,我在文章里提了另外一个不用排序就可以快速的实现同样功能的方法,从而避免了排序这个较为缓慢的过程。   但是浮点数无法直接使用直方图进行统计,那个快速方法就无法使用的。   可是,我们如果还是回到排序上去,我们把局部的浮点数进行排序,然后进行同样的编号,编号后的数据不就是整形数了吗,如果对这些整形数进行中值计算,得到的中值不就是真正的中值在浮点有序数列中的索引吗,这样不就可以借助整形数据的中值算法进行浮点的中值计算了吗。   同样举个例子,10个浮点数,他们的值分别为:      1.2     100.3    2000.2    150.1    100.3    40000.5    350.7    1.2    2000.2    300.6 5000.2   排序去重后,得到的数据序列如下:      1.2    100.3   150.1     300.6    350.7    2000.2    5000.2  40000.5   10个浮点数对应的编号为:      0      1      5        2     1      7       4      0       5      3    6    然后把这个编号理解为需要排序的数据,进行中值排序,得到的中值数据为3,这个3即为索引值,在排序去重的数据列,找到索引为3的值,即300.6作为最终的中值。   这样,16位排序算法里后续用到的技巧都可以直接用在浮点数上。   问题迎刃而解了。   细节:     1、测试了GIMP提供的排序算法,然后使用标准的qsort排序,似乎GIMP的排序要更快。     2、GIMP里获取浮点数对应的编号的代码部分技巧也是不错的,可以参考参考。   速度测试:     使用随机生成的浮点数做测试,3072*3072的数据,半径25,耗时约为1500ms,如果使用多线程,在现在的4个物理核心上普通CPU上,也能有500ms的速度。     使用稍微有点重复数据的数据集做测试,一般大概需要1000ms左右的耗时,开启线程可以得到300ms的速度。