图片预处理
大家好,我是阿赵。
这一篇将两种基础的降噪算法。
之前介绍过均值模糊和高斯模糊。如果从降噪的角度来说,模糊算法也算是降噪的一类,所以之前介绍的两种模糊可以称呼为均值降噪和高斯降噪。不过模糊算法对原来的图像特征的减弱性太强,我们想在降噪的过程中,尽量保持原土地特征
1、 双边滤波降噪
模糊算法降噪,是使用卷积核,对像素点周围一定范围内的点进行加权平均。这种加权平均的权重只考虑了周围像素点和中心点像素的距离。
如果在距离的条件上,再加多一个色值差的条件,对比周围像素点和中心点像素点的色值差,然后再加进权重里面,最终求出色值,就是双边滤波算法了。
所以我们需要传入三个参数:
1. 滤波的半径,决定了中心像素点会搜索多大范围的周边像素点进行加权平均
2. 距离的sigma参数,决定了高斯核的权重,距离sigma值越大,离中心像素越远的点权重就越小
3. 色差值的sigma参数,决定了颜色差异的大小权重,色差值sigma值越大,像素差值的权重就越小
用伪代码来检查一个像素,就是:
循环每一个像素点,再循环周围一定范围内的像素:
float weight = -1*(像素距离差X+像素距离差Y)/距离sigma - (周边像素和中间像素色值差)/色差值;
weight = math.exp(weight);
为什么要用负数,是为了用指数函数,归一化为0-1的范围。
为了能明显看清降噪的效果,我拿一张图直接二阶偏导求边缘
可以看到结果上面存在很多噪点
接下来使用双边滤波算法,进行降噪:
可以看到,降噪之后,图像还是变模糊了一些,不过一些明显的杂点已经消失了。
双边滤波降噪算法
优点是
1、 算法简单,只是比高斯模糊算多了一个色差,很容易实现
2、 计算量不大
缺点是
1、 由于只是比较周围一圈像素点,所以还是会产生模糊的效果
2、 对参数敏感,对于距离sigma和色差值sigma这两个参数,调节不同的值,会得到差别很大的效果。
正是由于对参数敏感,所以很难用一个固定的参数去降噪不同的图片,要根据实际情况做调整。如果色差值的参数无限大,其实这个结果就无限接近于高斯模糊了。
2、 NLM降噪
非局部均值降噪算法(Non-Local Means,简称NLM),所谓的非局部,其实是相对于类似高斯模糊或者双边滤波这种只对比当前像素点周边局部范围内的像素点的做法。非局部,指的是对比整个图片所有的像素范围。
NLM不是以一个像素点作为单位,而是以一个范围的色块作为单位。比如以某个像素点为中心的3X3的像素块,对比整个图片其他像素点为中心的3X3像素块,然后做2个事情:
1、 判断当前3X3像素块和目标3X3像素块的相似程度,求出一个相似值。具体做法是对应3X3个格子每一个位置,对两个色块对应位置的色值进行求差,然后再加起来。
2、 把所有和当前3X3像素块色值相似程度高的其他3X3色块的颜色加权平均,求出当前像素点的最终色值。加权的权重就是第一步求出的色块相似程度。
上面的3X3色块只是举一个例子,也可以是更大的范围,比如5X5之类。这个计算量是非常大的,不止要遍历每个像素点,还要遍历每个像素点周围范围内的像素点。
上图左边的是双边滤波的结果,右边是NLM降噪的结果。可以看出,NLM会保留了更多原图的细节,并不会产生很明显的模糊。
NLM的优点是 :由于只和色值相近的色块进行加权平均,所以不会被没必要的色块模糊掉,保留的细节会更多。
但NLM的缺点 也是很明显的:
1、 计算量非常的大,如果由CPU来做循环,对于稍大的图片处理起来会很慢。不过由于每个像素点的计算都是独立的,如果由并行处理的GPU来计算,还可以接受。
2、 对参数的敏感度更高。怎样才算是颜色相近,是没有一个标准的,如果标准很低,最后就变成了整张图所有像素的平均。如果标准很高,就可能找不到可以加权平均的色块,达不到降噪的效果。