双边滤波(Bilateral Filtering)

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

双边滤波(Bilateral Filtering)

1、基本思路

双边滤波(Bilateral Filtering)的基本思路是同时考虑像素点的空域信息和值域信息。即先根据像素值对要用来进行滤波的邻域做一个分割或分类,再给该点所属的类别相对较高的权重,然后进行邻域加权求和,得到最终结果。

2、实现原理

在 Bilateral Filtering 中,两个要素即:空域和值域 ,其数学表达方式相近,如下:

其中积分号前面k为归一化因子,这是考虑对所有的像素点进行加权,c 和 s 是closeness 和 similarity函数,x代表要求的点,f(x)代表该点的像素值。f(x) -->h(x)为滤波前后的图像,我们最后的滤波函数为:

由于空域部分,使得滤波特性较好,由于值域部分,使得边缘保持较好。

下图示意了有边缘的时候的权重和最后的滤波结果,可以看出权重在边界有很明显的分界,从而几乎只对自己所属的边缘一侧的像素点进行加权。

实现 c 和 s 两个函数的一种方法即 Gaussian 核,决定其性质的为各自的sigma参数,即 σd 和 σr

其中,其中,

3、参数讨论

对于空域的Gaussian滤波不需要过多介绍,对于值域滤波,即不考虑空间只考虑像素点的相似性进行加权的结果,值域滤波只是对待滤波图像的直方图的一个变换,而对于单峰值的直方图,值域滤波将值域范围向着峰值的中间即均值方向压缩。

对于参数的选取,进行如下讨论:

首先,两个 sigma 值为 kernel 的方差,方差越大,说明权重差别越小,因此表示不强调这一因素的影响,反之,则表示更强调这一因素导致的权重的不均衡。因此:

  • 两个方面的某个的 sigma 相对变小 表示这一方面相对较重要,得到强调。如 sigma_d 变小,表示更多采用近邻的值作平滑,说明图像的空间信息更重要,即相近相似。如 sigma_r 变小,表示和自己同一类的条件变得苛刻,从而强调值域的相似性。

其次,sigma_d 表示的是空域的平滑,因此对于没有边缘的,变化慢的部分更适合;sigma_r 表示值域的差别,因此强调这一差别,即减小 sigma_r 可以突出边缘。

  • sigma_d 变大,图像每个区域的权重基本都源于值域滤波的权重,因此对于空间邻域信息不是很敏感;sigma_r 变大,则不太考虑值域,权重多来自于空间距离,因此近似于普通的高斯滤波,图像的保边性能下降。因此如果像更多的去除平滑区域的噪声,应该提高 sigma_d ,如果像保持边缘,则应该减小 sigma_r 。

  • 极端情况,如果 sigma_d 无穷大,相当于值域滤波;sigma_r 无穷大,相当于空域高斯滤波。

4、离散数学公式模型

其中,和分别是空间域和值域的滤波参数(不确定度),和分别是像素点、的像素值。归一化权重系数为:

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

5、双边滤波代码实现

 void BilateralFilter( const Mat& src, Mat& dst, int d, double sigma_color, double sigma_space, int borderType ){int cn = src.channels();int i, j, k, maxk, radius;Size size = src.size();​CV_Assert( (src.type() == CV_8UC1 || src.type() == CV_8UC3) &&src.type() == dst.type() && src.size() == dst.size() &&src.data != dst.data );​if( sigma_color <= 0 ){sigma_color = 1;}if( sigma_space <= 0 ){sigma_space = 1;}​// 计算颜色域和空间域的权重的高斯核系数, 均值 μ = 0;  exp(-1/(2*sigma^2))  double gauss_color_coeff = -0.5/(sigma_color*sigma_color);double gauss_space_coeff = -0.5/(sigma_space*sigma_space);​// radius 为空间域的大小: 其值是 windosw_size 的一半    if( d <= 0 ){radius = cvRound(sigma_space*1.5);}else{radius = d/2;}radius = MAX(radius, 1);d = radius*2 + 1;​Mat temp;copyMakeBorder( src, temp, radius, radius, radius, radius, borderType );​vector<float> _color_weight(cn*256);vector<float> _space_weight(d*d);vector<int> _space_ofs(d*d);float* color_weight = &_color_weight[0];float* space_weight = &_space_weight[0];int* space_ofs = &_space_ofs[0];​// 初始化颜色相关的滤波器系数: exp(-1*x^2/(2*sigma^2))  for( i = 0; i < 256*cn; i++ ){color_weight[i] = (float)std::exp(i*i*gauss_color_coeff);}// 初始化空间相关的滤波器系数和 offset:  for( i = -radius, maxk = 0; i <= radius; i++ ){j = -radius;​for( ;j <= radius; j++ ){double r = std::sqrt((double)i*i + (double)j*j);if( r > radius ){continue;}space_weight[maxk] = (float)std::exp(r*r*gauss_space_coeff);space_ofs[maxk++] = (int)(i*temp.step + j*cn);}}​// 开始计算滤波后的像素值  for( i = 0; i < 0, size.height; i++ ){const uchar* sptr = temp->ptr(i+radius) + radius*cn;  // 目标像素点 uchar* dptr = dest->ptr(i);​if( cn == 1 ){// 按行开始遍历    for( j = 0; j < size.width; j++ ){float sum = 0, wsum = 0;int val0 = sptr[j];// 遍历当前中心点所在的空间邻域  for( k = 0; k < maxk; k++ ){int val = sptr[j + space_ofs[k]];float w = space_weight[k] * color_weight[std::abs(val - val0)];sum += val*w;wsum += w;}// 这里不可能溢出, 因此不必使用 CV_CAST_8U. dptr[j] = (uchar)cvRound(sum/wsum);}}else{assert( cn == 3 );for( j = 0; j < size.width*3; j += 3 ){float sum_b = 0, sum_g = 0, sum_r = 0, wsum = 0;int b0 = sptr[j], g0 = sptr[j+1], r0 = sptr[j+2];k = 0;for( ; k < maxk; k++ ){const uchar* sptr_k = sptr + j + space_ofs[k];int b = sptr_k[0], g = sptr_k[1], r = sptr_k[2];float w = space_weight[k] * color_weight[std::abs(b - b0) + std::abs(g - g0) + std::abs(r - r0)];sum_b += b*w; sum_g += g*w; sum_r += r*w;wsum += w;}wsum = 1.f/wsum;b0 = cvRound(sum_b*wsum);g0 = cvRound(sum_g*wsum);r0 = cvRound(sum_r*wsum);dptr[j] = (uchar)b0; dptr[j+1] = (uchar)g0; dptr[j+2] = (uchar)r0;}}}}
 ​

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

相关文章

三种经典图像滤波方法介绍——双边滤波(Bilateral filter)、导向滤波(Guided Fliter)、滚动导向滤波(RollingGuidedFilter)

文章目录 一、前言二、双边滤波(Bilateral filter)2.1 双边滤波的理论介绍及公式推导2.2 双边滤波的matlab程序实现 三、导向滤波(Guided Fliter)3.1 导向滤波的理论介绍及公式推导3.2 导向滤波matlab代码实现 四、滚动导向滤波(RollingGuidedFilter)4.1 滚动导向滤波的理论介绍…

图像处理:双边滤波算法

今天主要是回顾一下双边滤波&#xff0c;我曾经在这篇——图像处理&#xff1a;推导五种滤波算法中推导过它&#xff0c;其中包含了我自己写的草稿图。 目录 双边滤波算法原理 &#xff08;1&#xff09;空间域核 &#xff08;2&#xff09;值域核 理解双边滤波 空域权重​…

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;提供了从在线地图编辑到正式项目运行…