双边滤波(bilateral filter)以及联合双边滤波(joint bilateral filter)

article/2025/10/26 3:27:08

文章目录

  • 双边滤波
    • 理论公式
    • 代码(C++)
    • 数学辅助理解
  • 联合双边滤波(joint bilateral filter)
    • 参考链接
  • 写在最后

双边滤波

自用备忘,若侵则删。

理论公式

利用二维高斯函数生成空间域核,一维高斯函数生成颜色域核。
- 空间域核:
在这里插入图片描述
其中, ( k , l ) (k,l) (k,l)为核中心坐标, ( i , j ) (i,j) (i,j)为核内邻域坐标。 σ d \sigma_d σd为高斯函数的标准差,我个人感性上认为就是 σ \sigma σ小的时候,高斯函数瘦瘦高高的,反之,矮矮胖胖的。

- 色彩域核(下式仅为灰度值的表示):
在这里插入图片描述
f ( i , j ) f(i,j) f(i,j)代表图像在 ( i , j ) (i,j) (i,j)处的灰度值,其他标识与空间域一致。

- 双边滤波器模板: 空间域核 色彩域核
在这里插入图片描述
- 思考一下,为什么可以保边?
虽然说在边缘处,空间域的权重很大,但是色彩变化大,这就导致了色彩域的权重很小,空间域的大权重优势被色彩域的小权重拉了下来,因此边界邻域的像素作用不大,保住了边缘自身。而对于平坦区域来说,色彩域的作用不大,几乎纯靠空间域核来撑,也就近似于普通的高斯滤波了。

- 示意图:
在这里插入图片描述
在这里插入图片描述

  • 简易表达:
    在这里插入图片描述
    滤波后的y值即为在小模板中加权(融合空间权和色彩权)平均后再除以权重和的值。
    在代码中也是进行了归一化,与公式统一,具体见四重循环内的代码。

代码(C++)

/*
双边滤波器思想:1. 在高斯滤波器基础上增加了图像像素之间的相似度的考虑,进而达到保边的效果。双边滤波器的实现:1. 分别求空间域以及颜色域的权重系数2. 根据双边公式,移动窗口,处理整张影像
*/#include "opencv2/opencv.hpp"
#include"opencv2/highgui/highgui.hpp"
#include <math.h>
using namespace cv;
using namespace std;const int kernel_size = 7;
const int sigma_distance = 3;
const int sigma_color = 20;
#define DEBUG 0// 空间域权重确定
// @ distance_kernel 空间域核,1D
void GetDistanceWeight(double* distance_kernel)
{int k = kernel_size / 2;double distance_kernel_2D[kernel_size][kernel_size];double delta_square = 2* sigma_distance * sigma_distance; //分母for (int i = -k; i <= k; i++) {for (int j = -k; j <= k; j++) {double distance_numerator = i * i + j * j;distance_kernel_2D[i + k][j + k] = exp(-1.0 * distance_numerator / delta_square);
#ifdef DEBUG{cout << i+k << " " <<j+k <<" "<< distance_kernel_2D[i + k][j + k] << endl;}
#endif}}// 将2D kernel 转换为 1D kernelfor (int i = 0; i < kernel_size; i++) {for (int j = 0; j < kernel_size; j++) {distance_kernel[kernel_size * i + j] = distance_kernel_2D[i][j];
#ifdef DEBUG{cout << kernel_size * i + j << " " << distance_kernel[kernel_size * i + j] << endl;}
#endif}}
}// 颜色域权重确定
// @ color_kernel 颜色域核,1D,长度为256
void GetColorWeight(double* color_kernel) {for (int i = 0; i < 256; i++) {color_kernel[i] = exp(-1.0 * (i * i) / (2 * sigma_color * sigma_color));
#ifdef DEBUGcout<< i <<" "<<  color_kernel[i] << endl;
#endif // DEBUG}
}// 双边滤波
// @ src 待滤波的影像
// @ distance_kernel 空间域核
// @ color_kernel 颜色域核
// @ dst 输出的影像void BilateralFilter(Mat& src, double* distance_kernel, double* color_kernel, Mat& dst) {dst = src.clone();int n_rows = dst.rows;int n_cols = dst.cols;int n_channels = dst.channels();int n_cols_with_channels = n_cols * n_channels;int half_kernel_size = kernel_size / 2;int index;double pixel_sum;double weight_sum = 0;double temp_bilateral_weight = 0;// 边界不做处理for (int i = half_kernel_size; i < (n_rows - half_kernel_size); i++) {uchar* pt_dst = dst.ptr<uchar>(i);uchar* pt_src = src.ptr<uchar>(i);for (int j = n_channels * half_kernel_size; j < (n_cols_with_channels - n_channels * half_kernel_size); j++) {index = 0;pixel_sum = weight_sum = 0;// 内层kx,ky循环,空间域内滤波for (int kx = i - half_kernel_size; kx <= i + half_kernel_size; kx++) {uchar* pt_k_src = src.ptr<uchar>(kx);for (int ky = j - n_channels * half_kernel_size; ky <= (j + n_channels * half_kernel_size); ky += n_channels) {temp_bilateral_weight = distance_kernel[index++] * color_kernel[(int)abs(pt_src[j] - pt_k_src[ky])];weight_sum += temp_bilateral_weight;pixel_sum += (pt_k_src[ky] * temp_bilateral_weight); // 邻域某像素与中心点的双边权重乘积}}pixel_sum /= weight_sum; // 归一化pt_dst[j] = saturate_cast<uchar>(pixel_sum); //加权赋值}}
}int main() {Mat src, dst, dst_cv;src = imread("test.png");if (!src.data) {cout << "loading failed" << endl;system("pause");return -1;}double distance_kernel[kernel_size * kernel_size];double color_kernel[256];GetDistanceWeight(distance_kernel);GetColorWeight(color_kernel);// 测试自己实现的双边滤波函数BilateralFilter(src, distance_kernel, color_kernel, dst);namedWindow("src");imshow("src", src);namedWindow("my bf");imshow("my bf", dst);// 测试opencv中的bilateralFilter, 观察与自实现的函数的异同bilateralFilter(src, dst_cv, 7, 50, 3);namedWindow("cv bf");imshow("cv bf", dst_cv);waitKey(0);return 0;
}

数学辅助理解

  • 一维高斯分布:

在这里插入图片描述

高斯函数的 σ \sigma σ设置越小则越窄。

  • 二维高斯分布的公式为:
    在这里插入图片描述
    在二维空间生成的曲面可视化图为:在这里插入图片描述

σ \sigma σ太小的时候平滑效果不明显。

联合双边滤波(joint bilateral filter)

联合双边滤波相对于双边滤波来说,最大的特点就是引入了一幅引导影像。
具体可使用以下数学表达:
J p = 1 k p ∑ q ∈ Ω I q f ( ∥ p − q ∥ ) g ( ∥ I ~ p − I ~ q ∥ ) J_{p}=\frac{1}{k_{p}} \sum_{q \in \Omega} I_{q} f(\|p-q\|) g\left(\left\|\tilde{I}_{p}-\tilde{I}_{q}\right\|\right) Jp=kp1qΩIqf(pq)g( I~pI~q )
其中 I ~ p \tilde I_{p} I~p以及 I ~ q \tilde I_{q} I~q就是引导影像上的像素灰度值。
在opencv的contrib模块中,也提供了联合双边滤波的API:jointBilateralFilter(引导图,待滤波的图,滤波后的图,像素邻域直径,灰度域sigma,空间域sigma)。
简单的代码实现思路可以为将双边滤波中灰度域权重的计算过程进行修改,取引导影像上的灰度而非待处理影像的灰度,在此不赘述。至于opencv中API调用的代码则为:

#include <opencv2/opencv.hpp>
#include <ximgproc.hpp>int main()
{cv::Mat src = cv::imread("data/dp.png", 1); // 原始带噪声的深度图cv::Mat joint = cv::imread("data/teddy.png", 0);cv::Mat dst;cv::ximgproc::jointBilateralFilter(joint, src, dst, -1, 3, 9);imshow("src", src);imshow("joint", joint);imshow("jointBilateralFilter", dst);cv::waitKey(0);return 0;
}

参考链接

https://blog.csdn.net/panda1234lee/article/details/52839205

写在最后

我们最近创建了一个“三维重建技术动向与商业落地”的知识星球,这个星球汇聚了来自985和国际顶级学府的专家和学者,他们分享了最新的三维重建技术和商业应用的前沿知识和经验。如果你对三维重建领域感兴趣,那么这个知识星球是你不可错过的。通过加入这个知识星球,你可以学习到最新的三维重建技术和商业应用,提高自己的技能和能力。同时,如果你是一个三维重建领域的专家,你也可以在这个知识星球上分享自己的知识和经验,让更多的人受益。我们会追踪最新的AIGC与3D的技术,并试图从投资人、技术人、产品人以及用户的视角提出一些看法。加入知识星球,让我们一起探索三维重建领域的商业落地想法和前沿知识!如果你想加入这个知识星球,可以添加我的微信号(zhuanshanqwer),我可以免费为你提供名额。


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

相关文章

双边滤波(Bilateral filter)

双边滤波器&#xff08;Bilateral filter&#xff09;是一种可以保边去噪的滤波器。可以滤除图像数据中的噪声&#xff0c;且还会保留住图像的边缘、纹理等&#xff08;因噪声是高频信号&#xff0c;边缘、纹理也是高频信息&#xff0c;高斯滤波会在滤除噪声的同时使得边缘模糊…

双边滤波器cv2.bilateralFilter

双边滤波器cv2.bilateralFilter 双边滤波是综合考虑空间信息和色彩信息的滤波方式&#xff0c;在滤波过程中能够有效地保护图像内的边缘信息&#xff0c;双边滤波在计算某一个像素点的新值时&#xff0c;不仅考虑距离信息&#xff08;距离越远&#xff0c;权重越小&#xff09…

opencv-双边滤波

一、双边滤波原理 双边滤波&#xff08;Bilateral Filter&#xff09;是非线性滤波中的一种。这是一种结合图像的空间邻近度与像素值相似度的处理办法。在滤波时&#xff0c;该滤波方法同时考虑空间临近信息与颜色相似信息&#xff0c;在滤除噪声、平滑图像的同时&#xff0c;…

Opencv之图像滤波:6.双边滤波(cv2.bilateralFilter)

前面我们介绍的滤波方法都会对图像造成模糊&#xff0c;使得边缘信息变弱或者消失&#xff0c;因此需要一种能够对图像边缘信息进行保留的滤波算法&#xff0c;双边滤波是综合考虑空间信息和色彩信息的滤波方式&#xff0c;在滤波过程中能够有效地保护 图像内的边缘信息。 6.1…

Bilateral Filters(双边滤波算法)原理及实现

双边滤波算法原理&#xff1a; 双边滤波是一种非线性滤波器&#xff0c;它可以达到保持边缘、降噪平滑的效果。和其他滤波原理一样&#xff0c;双边滤波也是采用加权平均的方法&#xff0c;用周边像素亮度值的加权平均代表某个像素的强度&#xff0c;所用的加权平均基于高斯分…

双边滤波的基本原理

双边滤波&#xff08;Bilateral filter&#xff09;是一种非线性的滤波方法&#xff0c;本质是基于高斯滤波&#xff0c;目的是解决高斯滤波造成的边缘模糊。结合图像的空间邻近度和像素值相似度的一种折处理&#xff0c;同时考虑空域信息和灰度相似性&#xff0c;达到保边去噪…

双边滤波算法原理

1. 简介 图像平滑是一个重要的操作&#xff0c;而且有多种成熟的算法。这里主要简单介绍一下Bilateral方法&#xff08;双边滤波&#xff09;&#xff0c;这主要是由于前段时间做了SSAO&#xff0c;需要用bilateral blur 算法进行降噪。Bilateral blur相对于传统的高斯blur来说…

Bilateral Filters(双边滤波算法)原理及实现(一)

双边滤波算法原理 双边滤波是一种非线性滤波器&#xff0c;它可以达到保持边缘、降噪平滑的效果。和其他滤波原理一样&#xff0c;双边滤波也是采用加权平均的方法&#xff0c;用周边像素亮度值的加权平均代表某个像素的强度&#xff0c;所用的加权平均基于高斯分布[1]。最重要…

双边滤波与引导滤波

双边滤波与引导滤波 分类&#xff1a; AI and Computer Vision 2014-03-07 17:04 344人阅读 评论(0) 收藏 举报 图像处理 滤波 双边滤波 双边滤波很有名&#xff0c;使用广泛&#xff0c;简单的说就是一种同时考虑了像素空间差异与强度差异的滤波器&#xff0c;因此具有保持图…

【图像处理】——双边滤波

【fishing-pan&#xff1a;https://blog.csdn.net/u013921430 转载请注明出处】 双边滤波 高斯滤波是最常用的图像去噪方法之一&#xff0c;它能很好地滤除掉图像中随机出现的高斯噪声&#xff0c;但是在之前的博客中提到过&#xff0c;高斯滤波是一种低通滤波&#xff08;有兴…

【八】双边滤波

1.高斯滤波 高斯滤波的定义如下&#xff1a; 其中高斯函数为&#xff1a; 高斯滤波是领域内相邻像素的加权平均&#xff0c;权重值为G(||p-q||)&#xff0c;和均值滤波&#xff0c;中值滤波一样&#xff0c;都是将噪声&#xff08;高频信息&#xff09;滤除&#xff0c;但是边…

双边滤波原理和实现

双边滤波原理 双边滤波&#xff08;Bilateral filter&#xff09;是一种非线性的滤波方法&#xff0c;是结合图像的空间邻近度和像素值相似度的一种折衷处理&#xff0c;同时考虑空域信息和灰度相似性&#xff0c;达到保边去噪的目的。 双边滤波器之所以能够做到在平滑去噪的同…

双边滤波

1 双边滤波简介 双边滤波&#xff08;Bilateral filter&#xff09;是一种非线性的滤波方法&#xff0c;是结合图像的空间邻近度和像素值相似度的一种折衷处理&#xff0c;同时考虑空域信息和灰度相似性&#xff0c;达到保边去噪的目的。具有简单、非迭代、局部的特点。 双边滤…

数字图像处理(九)双边滤波

文章目录 一、何为双边滤波&#xff1f;二、为什么要使用双边滤波&#xff1f;三、双边滤波原理1.空间域核2.值域核3.模板相乘 四、 w d w_d wd​和 w r w_r wr​和 σ \sigma σ的理解五、C代码实现1.opencv中Mat的一点小知识2.关于边界的处理3.双边滤波代码 一、何为双边滤波…

双边滤波(Bilateral Filtering)

双边滤波&#xff08;Bilateral Filtering&#xff09; 1、基本思路 双边滤波&#xff08;Bilateral Filtering&#xff09;的基本思路是同时考虑像素点的空域信息和值域信息。即先根据像素值对要用来进行滤波的邻域做一个分割或分类&#xff0c;再给该点所属的类别相对较高的…

三种经典图像滤波方法介绍——双边滤波(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;是一个类库。 $代…