《opencv实用探索·十》opencv双边滤波的简单理解

1、引言

OpenCV中的双边滤波(Bilateral Filtering)是一种保持边缘清晰的滤波方法,它考虑像素的空间关系和像素值之间的差异。双边滤波对于去除噪声的同时保持图像的边缘非常有效,它也是一种非线性滤波。

双边滤波采用了两个高斯滤波的结合。一个负责计算空间邻近度的权值,也就是常用的高斯滤波器原理。而另一个负责计算像素值相似度的权值。在两个高斯滤波的同时作用下,就是双边滤波。

高斯滤波和双边滤波的效果对比图如下,可以清晰的看到双边滤波在模糊图像的同时也保持了图像边缘的清晰。

2、双边滤波的数学解析

双边滤波的数学表示如下所示:

S(i, j):指以 (i, j) 为中心的 (2N+1)x(2N+1) 的大小的范围;

f(k, l):(多个) 输入点;

g(i, j):输出点;

ω(i,j,k,l)为加权系数,其取值决定于空间域滤波器和像素域滤波器的乘积

空间域滤波器和像素域滤波器表现形式分别如下所示:

第一个函数表示当前点与中心点的欧式距离,第二个函数表示当前点灰度与中心点灰度差的绝对值。

对于高斯滤波,仅用空间距离的权值系数核与图像卷积后,确定中心点的灰度值。即认为离中心点越近的点,其权重系数越大。

双边滤波中加入了对灰度信息的权重,即在邻域内灰度值越接近中心点的灰度值的点权重越大,与中心点灰度值相差大的点权重越小,此权重大小则由像素范围域高斯函数确定。

两者相乘得到最终的卷积模板:

由于双边滤波需要每个中心点邻域的灰度信息来确定系数,所以速度比一般的滤波慢很多,而且计算量增长速度是核大小的平方。

双边滤波的核函数是空间域核与像素范围域核的综合结果:在图像的平坦区域,像素值变化很小,对应的像素范围域权重接近于1,此时空间域权重起主要作用,相当于进行高斯模糊;在图像的边缘区域,像素值变化很大,像素范围域权重变大,从而保持了边缘的信息。

为了使图像的边缘得到保留,就要根据当前被卷积像素的邻域进行观察,"推断"是否是边缘点和接近边缘的点。因此,结构元素就会改变,从而保留边缘点。下图大概演示了双边滤波的一个过程,右边是输入图像,图中有段灰度的突变,这表示边缘区域。中间的滤波核是将我们原本的高斯核,与一个能"推断"出是否在边缘点的结构元素相乘,得到专属于这个点的结构元素。灰度值高的地方不应该和灰度低的区域进行混合,所以,图像中接近边缘的一个点就会生成中间图这样的结构元素。左边是输出图像,可以看到原图像中的噪声被很好的去除同时也保留了清晰的边缘。

3、opencv双边滤波接口使用

cpp 复制代码
void bilateralFilter(InputArray src, 
                      OutputArray dst, 
                      int d,
                      double sigmaColor, 
                      double sigmaSpace,
                      int borderType = BORDER_DEFAULT );

第一个参数,输入图像,图像数据类型为必须是CV_8U、CV_32F和CV_64F三者之一,并且通道数必须为单通道或者三通道

第二个参数,OutputArray类型的dst,即目标图像,需要和源图片有一样的尺寸和类型。

第三个参数,int类型的d,表示在滤波过程中每个像素邻域的直径。如果这个值我们设其为非正数,那么OpenCV会从第五个参数sigmaSpace来计算出它来。

第四个参数,颜色空间滤波器的sigma值。这个参数的值越大,就表明该像素邻域内有更宽广的颜色会被混合到一起,产生较大的半相等颜色区域。

第五个参数,空间坐标中滤波器的标准差值,这个参数越大表明越远的像素会相互影响,从而使更大领域中有足够相似的颜色获取相同的颜色。当d>0,d指定了邻域大小且与sigmaSpace无关。否则,d正比于sigmaSpace。

第六个参数,int类型的borderType,用于推断图像外部像素的某种边界模式。注意它有默认值BORDER_DEFAULT。

d怎么设置?

对于每个像素,双边滤波器在其周围的一个正方形窗口内查看相邻像素。这个窗口的大小由 d 控制,它定义了窗口的直径。窗口的大小决定了在进行滤波时考虑的空间范围。

当 d 小于等于 0 时,窗口大小会由 sigmaSpace 来决定。这种情况下,d 的值会根据 sigmaSpace 来计算,确切的说,d 被计算为:d=int(sigmaSpace×1.5)。

这是 OpenCV 中对 d 的特殊处理,使得用户可以直接通过调整 sigmaSpace 控制滤波器的空间范围,而无需显式指定 d 的值。

这种方式可以方便用户,尤其是在不知道或不确定合适的 d 值时。通过调整 sigmaSpace,用户可以更直观地控制滤波器在空间上的影响范围,而无需手动计算 d。

当 d 值较大时,滤波器窗口变得较大,涵盖更广泛的像素,从而导致平均化效果更为显著。这可能导致较大结构的平滑,但也可能使图像细节变得模糊,为了保留图像细节,特别是边缘,通常选择较小的 d 值。较小的 d 值使得滤波器只关注较小的空间邻域,更有效地保留图像的细节和边缘。
保留细节:

如果你的目标是尽量保留图像的细节,特别是图像中的边缘和纹理,可以选择较小的 d 值。通常来说,尝试从 5 或更小的值开始是一个合理的起点
减少噪声:

如果你的图像包含大量噪声,选择稍大一些的 d 值可能会更有效地降低噪声。尝试从 10 或更大的值开始,然后根据需要进行调整。
图像平滑:

如果你的目标是对整个图像进行平滑,可以尝试较大的 d 值。这将导致较大的滤波窗口,对图像的整体结构进行平滑

sigmaColor怎么设置?
平衡平滑和细节:

如果你的目标是在平滑图像的同时尽量保留细节使边缘清晰,可以尝试选择一个中等大小的 sigmaColor。开始时,可以从 25 或 50 开始尝试。
对噪声敏感度:

较小的 sigmaColor 值通常会对颜色变化较小的区域更为敏感,因此可能更适合在图像中有较多噪声的情况。如果你希望减少噪声的影响,可以尝试选择较小的 sigmaColor 值。
颜色变化程度:

根据图像中的颜色变化程度来选择 sigmaColor。如果图像中的颜色变化较大,可能需要选择较大的 sigmaColor。

sigmaSpace怎么设置?
平滑整体图像但保留较多细节:

sigmaSpace: 25-50
对噪声敏感,但仍要进行平滑:

sigmaSpace: 10-20
强烈平滑整个图像,减小细节:

sigmaSpace: 75-100
对大结构保持较好细节,但平滑小结构:

sigmaSpace: 10-20

总结:
平滑整体图像但保留较多细节:

sigmaColor: 25-50

sigmaSpace: 25-50

d: 尝试较小的值,如5-10

对噪声敏感,但仍要进行平滑:

sigmaColor: 相对较小的值,例如10-20

sigmaSpace: 相对较小的值,例如10-20

d: 可以选择中等大小的值,如10-15

强烈平滑整个图像,减小细节:

sigmaColor: 较大的值,例如75-100

sigmaSpace: 较大的值,例如75-100

d: 可以选择相对较大的值,如15-20

对大结构保持较好细节,但平滑小结构:

sigmaColor: 25-50

sigmaSpace: 相对较小的值,例如10-20

d: 中等大小的值,例如10-15

下面是不同参数配比显示的效果:

相关推荐
于越海6 分钟前
Python工程师向项目管理转型的深度分析与学习道路规划
笔记·python·学习
机器之心37 分钟前
好莱坞特效师展示AI生成的中文科幻大片,成本只有330元
人工智能·openai
二闹44 分钟前
discard和remove的那些事儿
python
Codebee1 小时前
用原生AI-IDE快速搞定OneCode视图注解:AI与注解驱动开发的完美结合
人工智能·低代码
aneasystone本尊1 小时前
GraphRAG 快速入门
人工智能
用户5191495848451 小时前
TypeScript Record类型完全指南:从基础到高级应用
人工智能·aigc
大志说编程1 小时前
LangChain框架入门18: 十分钟带你搞定LLM工具调用
python·langchain·ai编程
听风.8251 小时前
机器学习6
人工智能·机器学习·概率论
钢铁男儿1 小时前
使用 TensorBoardX 实现 PyTorch 神经网络可视化:从入门到进阶
人工智能·pytorch·神经网络
苍何1 小时前
DeepSeek V3.1正式发布,专为下代国产芯设计
人工智能