图像处理:双边滤波算法

article/2025/10/26 5:54:56

今天主要是回顾一下双边滤波,我曾经在这篇——图像处理:推导五种滤波算法中推导过它,其中包含了我自己写的草稿图。

目录

双边滤波算法原理

(1)空间域核

 (2)值域核

理解双边滤波

空域权重​编辑和值域权重​编辑的意义

Opencv实现双边滤波

双边滤波代码实现

参考资料


双边滤波算法原理

双边滤波Bilateral filter是一种非线性的滤波方法,是结合图像的空间邻近度和像素值相似度的一种折中处理,同时考虑空域信息和灰度相似性,达到保边去噪的目的。具有简单、非迭代、局部的特点。双边滤波器的好处是可以做边缘保存Edge preserving),一般用高斯滤波去降噪,会较明显地模糊边缘,对于高频细节的保护效果并不明显。

双边滤波器之所以能够做到在平滑去噪的同时还能够很好的保存边缘Edge Preserve),是由于其滤波器的核由两个函数生成:空间域核和值域核

(1)空间域核

由像素位置欧式距离决定的模板权值\omega _{d} 。

\omega_d(i,j,k,l)=\exp (-\frac{​{(i-k)}^2-{(j-l)}^2}{​{2\sigma}_d^2})

q(i,j) 为模板窗口的其他系数的坐标;

p(k,l) 为模板窗口的中心坐标点;

\sigma _{d} 是空间域上的高斯核函数的标准差,用于控制像素位置的权值。

使用公式生成的滤波器模板和高斯滤波器使用的模板是没有区别的。权值\omega _{d}称为定义域核,也称为空间系数、空间域。显示由\omega _{d}的计算公式可知,它是计算临近点q到中心点p临近程度,因此定义域核\omega _{d}是用于衡量空间临近的程度。

 (2)值域核

由像素值的差值决定的模板权值\omega _{r} 。

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

其中,q(i,j)为模板窗口的其他系数的坐标,f(i,j) 表示图像在点q(i,j)处的像素值;

p(k,l)为模板窗口的中心坐标点,对应的像素值为f(k,l)

\sigma _{r}是像素值域上的高斯核函数的标准差,用于控制像素值的权值。

一般会将权值\omega _{r}称为值域核,或像素值域,但不管是值域核\omega _{r}还是空间域核\omega _{d},其大小都在[0 1]之间。


最后,将上述两个模板相乘就得到了双边滤波器的模板权值:

\omega_d(i,j,k,l)=\exp(-\frac{​{(i-k)}^2-{(j-l)}^2}{​{2\sigma}_d^2}-\frac{\left \| f(i,j)-f(k,l) \right \|}{2\sigma _{r}^{2}})

因此,双边滤波器的数据公式可以表示如下:

g(i,j)=\frac{\sum_{kl}f(k,l)\omega (i,j,k,l)}{\sum_{kl}\omega (i,j,k,l)} 

理解双边滤波

双边滤波(Bilateral filter)其综合了高斯滤波器和α-截尾均值滤波器的特点,同时考虑了空间域与值域的差别,而高斯滤波器和α均值滤波分别只考虑了空间域和值域差别。高斯滤波器只考虑像素间的欧式距离,其使用的模板系数随着和窗口中心的距离增大而减小;α-截尾均值滤波器则只考虑了像素灰度值之间的差值,去掉α%的最小值和最大值后再计算均值。

空域权重\omega _{d}和值域权重\omega _{r}的意义

空域权重\omega _{d}衡量的是两点之间的距离,距离越远权重越低;

值域权重\omega _{r}衡量的是两点之间的像素值相似程度,越相似权重越大。

这里从图像的平坦区域边缘区域定性分析双边滤波的降噪效果:

  • 在平坦区域,临近像素的像素值的差值较小,对应值域权重\omega _{r}接近于1,此时空域权重起主要作用,相当于直接对此区域进行高斯模糊。因此,平坦区域相当于进行高斯模糊。
  • 在边缘区域,临近像素的像素值的差值较大,对应值域权重\omega _{r}接近于0,导致此处核函数下降(因\omega =\omega_{d} \times \omega _{r}),当前像素受到的影响就越小,从而保持了原始图像的边缘的细节信息。

Opencv实现双边滤波

 查阅资料才发现,原来双边滤波函数已经在Opencv中实现了。

我们来查看一下这个函数:

def bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None): # real signature unknown; restored from __doc__"""bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]]) -> dst.   @brief Applies the bilateral filter to an image..   .   The function applies bilateral filtering to the input image, as described in.   http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html.   bilateralFilter can reduce unwanted noise very well while keeping edges fairly sharp. However, it is.   very slow compared to most filters..   .   _Sigma values_: For simplicity, you can set the 2 sigma values to be the same. If they are small (\<.   10), the filter will not have much effect, whereas if they are large (\> 150), they will have a very.   strong effect, making the image look "cartoonish"..   .   _Filter size_: Large filters (d \> 5) are very slow, so it is recommended to use d=5 for real-time.   applications, and perhaps d=9 for offline applications that need heavy noise filtering..   .   This filter does not work inplace..   @param src Source 8-bit or floating-point, 1-channel or 3-channel image..   @param dst Destination image of the same size and type as src ..   @param d Diameter of each pixel neighborhood that is used during filtering. If it is non-positive,.   it is computed from sigmaSpace..   @param sigmaColor Filter sigma in the color space. A larger value of the parameter means that.   farther colors within the pixel neighborhood (see sigmaSpace) will be mixed together, resulting.   in larger areas of semi-equal color..   @param sigmaSpace Filter sigma in the coordinate space. A larger value of the parameter means that.   farther pixels will influence each other as long as their colors are close enough (see sigmaColor.   ). When d\>0, it specifies the neighborhood size regardless of sigmaSpace. Otherwise, d is.   proportional to sigmaSpace..   @param borderType border mode used to extrapolate pixels outside of the image, see #BorderTypes"""pass

在python当中是看不到源代码的,而且参数释义也是英文的,不过它这里倒是给出了一个网址,好像是介绍双边滤波的,我们一起来看看双边滤波。

原来是这是一篇有关于双边滤波论文。

                                   

它这里做了两种实验分别是黑白实验以及颜色实验。

  • 黑白实验中做了三组,分别是猫咪、水果静物、洋葱,经过双边滤波处理后,大部分的精细纹理被消除掉了。
  • 颜色实验做了两组,黑白实验中当使用标准低通滤波器平滑黑白图像, 在边缘上产生中间层次的灰色,从而产生模糊的图像,颜色实验要复杂的多,产生的是两个颜色的融合颜色,例如,在蓝色之间红色有各种深浅不一的粉红色和紫色。而且平滑颜色边缘时可能会产生色带,平滑的图像不仅看起来模糊,而且还表现出物体周围有奇特的彩色光环。第二组是红衣小男孩,图(一)显示出了五次迭代的效果,图(二)单次迭代会比原来的图像更清晰,可能足以满足我们图像处理上的大多数要求,多个迭代具有拼合图像中颜色的效果相当多,但没有模糊的边缘。图(三)卡通形象,所有阴影和边缘都是保留了下来,但大部分阴影都消失了,没有“新”颜色通过过滤引入。

接下来,还是来看看双边滤波的一个效果,我们自己来实现一下看看,万一人家作者是吹嘘的呢?

双边滤波代码实现

既然opencv中有这个函数了,那我们也就不用再费时间自己去写了,毕竟你自己写的效果可能还真不如这里面已经集成好的。

def bilateralFilter(src, d, sigmaColor, sigmaSpace, dst=None, borderType=None):
  • src: 输入的原始图像。
  • d: 表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。
  • sigmaColor:颜色空间过滤器的sigma值,这个参数的值月大,表明该像素邻域内有越宽广的颜色会被混合到一起,产生较大的半相等颜色区域。 (这个参数可以理解为值域核\omega _{r}\sigma _{r}
  • sigmaSpace:,如果该值较大,则意味着颜⾊相近的较远的像素将相互影响,从而使更⼤的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小,那么不考虑sigmaSpace值,否则d正比于sigmaSpace。(这个参数可以理解为空间域核\omega _{d}\sigma _{d}
  • dst:输出图像。
  • borderType:用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT。

双边滤波器可以很好的保存图像边缘细节而滤除掉低频分量的噪音,但是双边滤波器的效率不是太高,花费的时间相较于其他滤波器而言也比较长。
对于简单的滤波而言,可以将两个sigma值设置成相同的值,如果值<10,则对滤波器影响很小,如果值>150则会对滤波器产生较大的影响,会使图片看起来像卡通,就像是上面论文中那样。

import cv2
import numpy as npdef stackImages(scale,imgArray):rows = len(imgArray)cols = len(imgArray[0])rowsAvailable = isinstance(imgArray[0], list)width = imgArray[0][0].shape[1]height = imgArray[0][0].shape[0]if rowsAvailable:for x in range ( 0, rows):for y in range(0, cols):if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)else:imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)imageBlank = np.zeros((height, width, 3), np.uint8)hor = [imageBlank]*rowshor_con = [imageBlank]*rowsfor x in range(0, rows):hor[x] = np.hstack(imgArray[x])ver = np.vstack(hor)else:for x in range(0, rows):if imgArray[x].shape[:2] == imgArray[0].shape[:2]:imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)else:imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)hor= np.hstack(imgArray)ver = horreturn verdef empty(a):passpath = './Images/rgblena.jpg'
img = cv2.imread(path)cv2.namedWindow('image')
cv2.createTrackbar('d', 'image', 1, 50, empty)
cv2.createTrackbar('sigmaColor', 'image', 1, 150, empty)
cv2.createTrackbar('sigmaSpace', 'image', 1, 150, empty)
while True:d = cv2.getTrackbarPos('d', 'image')sigmaColor = cv2.getTrackbarPos('sigmaColor', 'image')sigmaSpace = cv2.getTrackbarPos('sigmaSpace', 'image')print(d,sigmaColor,sigmaSpace)dst = cv2.bilateralFilter(img, d, sigmaColor, sigmaSpace)stackimg=stackImages(0.5,[img,dst])cv2.imshow('image', stackimg)k = cv2.waitKey(1) & 0xFFif k == 27:breakcv2.destroyAllWindows()

网上都是有关于轨迹栏控制C++版本的双边滤波,这里我就用python来实现轨迹栏控制。请一定一定要注意的是,轨迹栏滑动条请慢点调试,双边滤波的计算是比较费时间的,搞不好窗口会被卡住。

这里我使用了cv2.namedWindow函数创建了一个名为“image”的窗口,并使用cv2.createTrackbar函数创建了三个滑动条,分别用来调整d、sigmaColor和sigmaSpace参数。

在while循环中,使用cv2.getTrackbarPos函数获取滑动条的当前值,并将其作为双边滤波函数的参数,然后将滤波结果显示在窗口中。

参考资料

双边滤波 (ed.ac.uk)

浅析bilateral filter双边滤波器的理解-面圈网

双边滤波方法原理与代码实践(附完整代码)_双边滤波器公式_小小何先生的博客-CSDN博客

基于卷积神经网络的坝面表观缺陷实时检测方法与应用 - 中国知网 (cnki.net)


http://chatgpt.dhexx.cn/article/oIsNcsMO.shtml

相关文章

Bilateral Filters(双边滤波算法)的超简单原理,学不会你打我。

摘要&#xff1a; 双边滤波(Bilateral Filters)是非常常用的一种滤波&#xff0c;它可以达到保持边缘、降噪平滑的效果。和其他滤波原理一样&#xff0c;双边滤波也是采用加权平均的方法&#xff0c;用周边像素亮度值的加权平均代表某个像素的强度&#xff0c;所用的加权平均基…

jQuery源码分析理解

1&#xff1a; 首先我们先来看一下jquery代码的整体结构 代码从16行开始为真正的jquery源码&#xff0c;我们看到Jquery源码第一个()中是定义了一个匿名function( window, undefined ) {}&#xff1b;接着末尾有个(window)&#xff0c;就表示执行这个匿名function&#xff0c;…

jQuery源码分析(一)

jQuery源码分析&#xff08;一&#xff09; 我们知道在jQuery中在使用选择器或者给元素绑定事件的时候都是通过$来操作的。那么基于JavaScript面向对象的思想&#xff0c;我们可以把jQuery看做一个函数或者对象&#xff0c;它里边存储了大量的方法&#xff0c;是一个类库。 $代…

jQuery源码阅读(一)---jQuery源码整体架构

之前用jQuery库写了两个小例子&#xff08;结合Apache、PHP实现的简易聊天室以及音乐播放器&#xff09;&#xff0c;详见我的上两篇博客jQuery aJax技术以及PHP实现简单聊天室、 利用jQuery实现音乐播放器。为了更加深入了解jQuery库的架构以及巩固原生JS的基础和深度&#xf…

jquery源码解析

(function(a,b){})() JQuery源码的开头 (function(a,b){})(window)通常(function(){})()用来封装一些私有成员或者公共成员的导出。 1. 定义一个匿名函数&#xff0c;创建了一个“私有”的命名空间&#xff0c;该命名空间的变量和方法&#xff0c;不会破坏全局的命名空间。确…

jQuery源码下载和编译

下载 git clone https://github.com/jquery/jquery.git编译 下载完成后&#xff0c;进入jquery文件夹&#xff0c;运行如下命令&#xff1a; npm run build最后全部编译完成&#xff0c;生成的文件在目录dist文件夹下&#xff1a; 有兴趣的就可以开始研究源码了。

jQuery源码阅读

1. 立即执行函数 简化后的代码就是这样 (function(global, factory) {... })(window, function () {}); Q&#xff1a;采用立即执行函数的好处是什么呢&#xff1f; A: 通过定义一个匿名函数&#xff0c;创建了一个新的函数作用域&#xff0c;相当于创建了一个私有的命名空…

jQuery -- jQuery源码(一):核心功能

一、jQuery无new构建实例 1、$就是jQuery的别称 可以在$和jQuery对象挂在在window中&#xff0c;实现全局引用。 给Windows对象扩展一个$的属性&#xff0c;让它拿到jQuery构造函数的引用 可以用$访问到jQuery的构造函数 // jQuery.js (function(root) {var jQuery functio…

制作一个游戏编辑器玩玩(1)

今天准备着手例用空闲时间制作一个游戏编辑器&#xff0c;一是因为这些年来积累了不少的算法和制作经验&#xff0c;它们是分散的&#xff0c;零乱的&#xff0c;想搞一次规整。二是自己一起想做一个简单点的游戏编辑器&#xff0c;可以让自己的小朋友把自己的想法在上面实现&a…

游戏策划的软件与工具

游戏策划的软件与工具 UXplayer https://www.jianshu.com/p/ceddde705933 gongjutitle.png 本文修改自前公司的一份交接文档&#xff0c;分享了工作中一些常用的软件。 Axure 界面示意图/流程图制作软件 大前提&#xff1a;Windows系统、无法直连外网 Mac系统的话&#xff0c;…

Tiled游戏地图编辑器

下载 软件是免费的,直接官网下载就好了 下载链接:https://www.mapeditor.org/ 新建地图 左上角 >> 文件 >> 创建新地图 快捷键:ctrln 根据你的需求设置地图大小 导入素材新建图块集 左上角 >> 文件 >> 新图块 新建你的图集文件.png 如果你已…

Android游戏开发之地图编辑器的使用以及绘制地图 (四)

雨松MOMO带你走进游戏开发的世界之地图编辑器的使用以及绘制地图 雨松MOMO原创文章如转载&#xff0c;请注明&#xff1a;转载至我的独立域名博客雨松MOMO程序研究院&#xff0c;原文地址:http://www.xuanyusong.com/archives/211 Mappy中文地图编辑器的使用说明下载地址&#…

编辑器

问题描述 你现在要实现一个针对于数字序列的编辑器。 初始的时候&#xff0c;序列是空的。 在之后&#xff0c;有以下五种操作&#xff1a; I x 在光标之后插入x D 删除光标之前的数字 L 将光标向左移动&#xff0c;如果已经在最左&#xff0c;则不移动 R 将光标向右移动&#…

代码编辑器

文章来源&#xff1a;几款非常优秀且常用的代码编辑器 ... VS CodeSource InsightVimUltraEditeclipseUnderstandAtomSublime Text 对于软件开发人员&#xff0c;代码编辑器好用与否直接影响代码编辑的效率。软件开发&#xff0c;基本上都有集成开发环境&#xff08;IDE&#x…

Unity的编辑器

1大部分人Unity编辑器是vistual 2.变量 2.1新建C#文件 鼠标点击Assets-->再点击create-->点击C#Sprite 2.2先用鼠标点击游戏物体(Cube)将c#文件拖拽到Inspector下&#xff0c;双击C#文件可以进入编写代码 2.3变量 public 变量类型 变量; //公有属性在Inspector下可…

游戏编辑器框架

原文&#xff1a;http://www.cnblogs.com/winsonchen/archive/2008/03/29/1128575.html 《游戏创造》08年第二期有一篇关于“&#xff57;xWidget游戏编辑器框架”开发的文章&#xff0c;作者使用过unreal引擎&#xff0c;熟悉unreal编辑器实现细节。该作者建议采用wWidget开发…

RPG++——游戏编辑器的开发

完整资料进入【数字空间】查看——baidu搜索"writebug" 随着当下电子设备的普及以及人们对娱乐需求的上升&#xff0c;电子游戏逐渐走进千家万户。RPG&#xff08;角色扮演&#xff09;游戏作为最经典的游戏种类之一&#xff0c;因其游戏形式多样&#xff0c;自由度…

RPG或SLG游戏在线地图编辑器

有做大型RPG或SLG游戏需求的朋友请进&#xff0c;有在线地图编辑器 我凭借多年的游戏开发经验&#xff0c;用cocoscreator2.13开发了一款web在线地图编辑器&#xff0c;暂且命名为EasyMapEditor&#xff0c;用Google浏览器打开&#xff0c;提供了从在线地图编辑到正式项目运行…

游戏编辑器制作(10)

差不多一年左右没有更新了&#xff0c;今天把这段时间的工作内容记录一下&#xff0c;从上一篇开始&#xff0c;制了很多相关功能&#xff0c;花了很多时间研究了RTS游戏的结构部分&#xff0c;也研究了RVO&#xff0c;还有些著名的开源游戏代码。自己实现了自己的rtssim(RTS模…

从零开始入门创作游戏——Unity编辑器的使用

还没找到工作的我继续瞎折腾中&#xff0c;上次搭建环境就花了我3天的时间 从零开始入门创作游戏——Unity3d的环境搭建_默哀d的博客-CSDN博客 接下来是根据油土鳖的视频学习创作的一个小恐龙跳跳跳游戏&#xff0c;直接上手做一次学得更多 https://www.youtube.com/watch?…