本文最后更新于:2024年1月14日 晚上

双边滤波是一种非线性滤波器,它可以达到保持边缘、降噪平滑的效果。和其他滤波原理一样,双边滤波也是采用加权平均的方法,用周边像素亮度值的加权平均代表某个像素的强度,本文记录原理与实现。

简介

双边滤波(Bilateral filter)是一种可以保边去噪的滤波器,是结合图像的空间邻近度和像素值相似度的一种折衷处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。

之所以可以达到此去噪效果,是因为滤波器是由两个函数构成。一个函数是由几何空间距离决定滤波器系数。另一个由像素差值决定滤波器系数。

双边滤波器的好处是可以做边缘保存(edge preserving),一般用高斯滤波去降噪,会较明显地模糊边缘,对于高频细节的保护效果并不明显。双边滤波器顾名思义比高斯滤波多了一个高斯方差sigma-d,它是基于空间分布的高斯滤波函数,所以在边缘附近,离的较远的像素不会太多影响到边缘上的像素值,这样就保证了边缘附近像素值的保存。但是由于保存了过多的高频信息,对于彩色图像里的高频噪声,双边滤波器不能够干净的滤掉,只能够对于低频信息进行较好的滤波。

为什么要使用双边滤波?

高斯滤波去降噪,会较明显地模糊边缘,对于高频细节的保护效果并不明显。

直觉来源

需要降噪,又想要保留细节,只能根据图像情况决定如何应用卷积核了,如果可以在非边缘区域做模糊,在边缘区域只用和当前像素接近的像素做模糊就好了呢 ~

原理

对图像进行空间域滤波的方法是使用一个结构元素(核)来对原图像进行卷积。比如说高斯核像是这样的:

而这个结构元素就会对原图像进行卷积操作,从而得到一个新的图像,即输出图像。我们知道,这个结构元素是不会变的。但是!但是!但是!在双边滤波算法中就不是如此了。为了使图像的边缘得到保留,就要根据当前被卷积像素的邻域进行观察,“推断”是否是边缘点和接近边缘的点。因此,结构元素就会改变,从而保留边缘点。

下面的一组图中,图a是原图像,图c是输出。而中间的图像是什么呢?显然,这是原图中根据某个点的邻域生成的,专属于这个点的结构元素。

可以看到,原图中显然有一个灰度的突变,这就表示是边缘。灰度值高的地方不应该和灰度低的区域进行混合,所以,图像中接近边缘的一个点就会生成图b这样的结构元素。

而生成这样的结构元素的方法,是将我们原本的高斯核,与一个能“推断”出是否在边缘点的结构元素相乘,如下图中间的结构元素。

另一幅原理示意图:

双边滤波器的输出像素依赖于当前被卷积像素的邻域。 $i$ 和 $j$ 是当前被卷积像素的坐标点, $k$ 和 $l$ 是邻域像素的坐标点:

  • 输出像素的值依赖于邻域像素的值的加权组合:

$$
g(i, j)=\frac{\sum_{k, l} f(k, l) w(i, j, k, l)}{\sum_{k, l} w(i, j, k, l)}
$$

  • 权重系数$w(i,j,k,l)$取决于空间域核,即领域像素和当前像素差异,越小权重越大:
$$ d(i, j, k, l)=\exp \left(-\frac{(i-k)^{2}+(j-l)^{2}}{2 \sigma_{d}^{2}}\right) $$
  • 和值域核,即高斯核强度,距离该像素越近强度越大:

$$
r(i, j, k, l)=\exp \left(-\frac{|f(i, j)-f(k, l)|^{2}}{2 \sigma_{r}^{2}}\right)
$$

  • 二者的乘积构成权重:
$$ w(i, j, k, l)=\exp \left(-\frac{(i-k)^{2}+(j-l)^{2}}{2 \sigma_{d}^{2}}-\frac{\|f(i, j)-f(k, l)\|^{2}}{2 \sigma_{r}^{2}}\right) $$
  • 同时考虑了空域和值域的信息,简单来说:距离越近、颜色越接近的像素权重越大

API

1
2
3
4
5
6
void bilateralFilter( InputArray src, 
OutputArray dst,
int d,
double sigmaColor,
double sigmaSpace,
int borderType = BORDER_DEFAULT );

参数:

  • 第一个参数,InputArray类型的src,输入图像,即源图像,需要为8位或者浮点型单通道、三通道的图像。
  • 第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。
  • 第三个参数,int类型的d,表示在过滤过程中每个像素邻域的直径。如果这个值我们设其为非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它来。
  • 第四个参数,double类型的sigmaColor,颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
  • 第五个参数,double类型的sigmaSpace坐标空间中滤波器的sigma值,坐标空间的标注方差。他的数值越大,意味着越远的像素会相互影响,从而使更大的区域足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。
  • 第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。

实现

1
cv.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]]	) ->	dst
  • 示例代码
1
2
3
img = mt.cv_rgb_imread('img1.jpg', gray=False)
res = cv2.bilateralFilter(img, 9, 100, 1000)
PIS(img, res)

参考资料



文章链接:
https://www.zywvvd.com/notes/study/image-processing/bilateral-filter/bilateral-filter/


“觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭”

微信二维码

微信支付

支付宝二维码

支付宝支付

Bilateral Filters 双边滤波
https://www.zywvvd.com/notes/study/image-processing/bilateral-filter/bilateral-filter/
作者
Yiwei Zhang
发布于
2022年3月14日
许可协议