by HPC_ZY
最近一个项目中需要用到中值滤波(不能调库),但是核半径相当大,用传统的方法运行速度极慢。因此查阅文献找到快速中值滤波的方法。写成三种语言并分享给大家。
一、中值滤波
简单说就是,就是对某点邻域内所有像素进行排序,取序数在中间的值替代原始值。
这样做对脉冲噪声有良好的滤除作用,特别是在滤除噪声的同时,能够保护信号的边缘,使之不被模糊。
实现方法
step 1:通过从图像中的某个采样窗口取出奇数个像素进行排序
step 2:用排序后的中值取代要处理的像素即可
代码见后文。
注:本文主要讲图像处理,所有使用 “像素 ” 替代 “ 数据”。
二、快速中值滤波
介绍
中值滤波主要耗时就在于对窗口(邻域)内像素进行排序,因此针对如何获取中值进行优化。
最初——经典的中值滤波对窗口内所有像素进行排序,所以排序算法的选择就很重要。
接着——但后来有人意识到 “我们只需要中间值”,没必要将整个序列进行排序,因此出现了一些快速搜索数组中间值的方法。
然后——由于图像的像素值为0~255的整数,1979年有人就提出了用累积直方图寻找中值的方法。
最后——人们又在这基础上不断改进。
本文主要讲基于直方图的快速中值滤波方法
原理
- 实现方法
step 1:统计 N ∗ N N*N N∗N窗口内像素
step 2:计算累积直方图
step 3:找到累积直方图值刚好超过 N ∗ N 2 \frac{N*N}{2} 2N∗N时对应的灰度值。
通过一个简单的例子更直观的说明。
这里假设一个只有8个灰度级的图像,某个 5 ∗ 5 5*5 5∗5的窗口内值如下,
[ 0 4 5 5 5 3 4 7 6 5 6 7 7 7 6 3 2 1 1 0 0 1 1 0 0 ] \begin{bmatrix} 0 &4 &5&5&5 \\ 3 & 4&7&6&5\\6&7&7&7&6\\3&2&1&1&0\\0&1&1&0&0 \end{bmatrix} ⎣⎢⎢⎢⎢⎡0363044721577115671055600⎦⎥⎥⎥⎥⎤