**双边滤波(Bilateral Filter)原理解析及代码实现**

双边滤波(Bilateral Filter)原理解析及代码实现

双边滤波基本原理
双边滤波与高斯滤波器相比,对于图像的边缘信息能够更好的保存。其原理为一个 与空间距离相关的高斯函数与一个灰度距离相关的高斯函数相乘。
空间距离
空间函数
公式中(xi,yi)为当前点位置,(xc,yc)为中心点的位置,sigma为空间域标准差。
灰度距离
灰度距离
公式中gray(xi,yi)为当前点灰度值,gray(xc,yc)为中心点灰度值,sigma为值域标准差。

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

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

两者权重系数相乘,得到最终的卷积模板。由于双边滤波需要每个中心点邻域的灰度信息来确定其系数,所以其速度与比一般的滤波慢很多,而且计算量增长速度为核大小的平方。
opencv中提供了bilateralFilter()函数来实现双边滤波操作,其原型如下:

C++: void bilateralFilter(InputArray src, OutputArray dst, int d, double sigmaColor, double sigmaSpace, int borderType=BORDER_DEFAULT )

参数解释:
. InputArray src: 输入图像,可以是Mat类型,图像必须是8位或浮点型单通道、三通道的图像。
. OutputArray dst: 输出图像,和原图像有相同的尺寸和类型。
. int d: 表示在过滤过程中每个像素邻域的直径范围。如果这个值是非正数,则函数会从第五个参数sigmaSpace计算该值。
. double sigmaColor: 颜色空间过滤器的sigma值,这个参数的值越大,表明该像素邻域内有月宽广的颜色会被混合到一起,产生较大的半相等颜色区域。
. double sigmaSpace: 坐标空间中滤波器的sigma值,如果该值较大,则意味着颜色相近的较远的像素将相互影响,从而使更大的区域中足够相似的颜色获取相同的颜色。当d>0时,d指定了邻域大小且与sigmaSpace五官,否则d正比于sigmaSpace.
. int borderType=BORDER_DEFAULT: 用于推断图像外部像素的某种边界模式,有默认值BORDER_DEFAULT.

双边滤波器可以很好的保存图像边缘细节而滤除掉低频分量的噪音,但是双边滤波器的效率不是太高,花费的时间相较于其他滤波器而言也比较长。
对于简单的滤波而言,可以将两个sigma值设置成相同的值,如果值<10,则对滤波器影响很小,如果值>150则会对滤波器产生较大的影响,会使图片看起来像卡通。
图像可知在这里插入图片描述
已知 0≤△g≤255;

1)假设sigma = 255,当△g = 255时,系数为exp(-1) = 0.3679,当△g = 0时,系数为exp(-0)= 1.灰度最大点的系数与相差最小的灰度值系数之比为 0.3679.

2)假设sigma = 122.5,当△g = 255时,系数为exp(-4) = 0.0183,当△g = 0时,系数为exp(-0)= 1.灰度差最大点的系数与相差最小的灰度值系数之比为 0.0183.

结论:
当simga较大时,灰度差最大值与最小值的系数在很小的一个范围之内,其比值较大。即灰度差较大的点,对于中心点也会有相应的较大的权值,此与双边滤波的保留边缘的初衷相违背。

当sigma较小时,灰度差最大值与最小值的系数在较大的一个范围之内,其比值很小,即灰度差较大的点,对应中心点仅有很小的权重。

综上分析可知:

Sigma越大,边缘越模糊,极限情况为simga无穷大,值域系数近似相等(忽略常数时,将近为exp(0)= 1),与高斯模板(空间域模板)相乘后可认为等效于高斯滤波。

Sigma越小,边缘越清晰,极限情况为simga无限接近0,值域系数近似相等(接近exp(-∞) = 0),与高斯模板(空间域模板)相乘后,可近似为系数皆相等,等效于源图像。
程序运行结果
代码:

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>
//#include<vector>

using namespace std;
using namespace cv;

//定义全局变量
const int g_ndMaxValue = 100;
const int g_nsigmaColorMaxValue = 200;
const int g_nsigmaSpaceMaxValue = 200;
int g_ndValue;
int g_nsigmaColorValue;
int g_nsigmaSpaceValue;

Mat g_srcImage;
Mat g_dstImage;

//定义回调函数
void on_bilateralFilterTrackbar(int, void*);

int main(int argc, char**argv)
{
	g_srcImage = imread("D:/picture/opencv/images/Lenna.png");

	//判断图像是否加载成功
	if (g_srcImage.empty())
	{
		cout << "could not load image..." << endl;
		return -1;
	}
	namedWindow("src", WINDOW_AUTOSIZE);
	imshow("src", g_srcImage);

	//定义输出图像窗口属性和轨迹条属性
	namedWindow("bilateralFilter", WINDOW_AUTOSIZE);
	g_ndValue = 10;
	g_nsigmaColorValue = 10;
	g_nsigmaSpaceValue = 10;

	char dName[20];
	sprintf(dName, "邻域直径 %d", g_ndMaxValue);

	char sigmaColorName[20];
	sprintf(sigmaColorName, "sigmaColor %d", g_nsigmaColorMaxValue);

	char sigmaSpaceName[20];
	sprintf(sigmaSpaceName, "sigmaSpace %d", g_nsigmaSpaceMaxValue);

	//创建轨迹条
	createTrackbar(dName, "bilateralFilter", &g_ndValue, g_ndMaxValue, on_bilateralFilterTrackbar);
	on_bilateralFilterTrackbar(g_ndValue, 0);

	createTrackbar(sigmaColorName, "bilateralFilter", &g_nsigmaColorValue,
		g_nsigmaColorMaxValue, on_bilateralFilterTrackbar);
	on_bilateralFilterTrackbar(g_nsigmaColorValue, 0);

	createTrackbar(sigmaSpaceName, "bilateralFilter", &g_nsigmaSpaceValue,
		g_nsigmaSpaceMaxValue, on_bilateralFilterTrackbar);
	on_bilateralFilterTrackbar(g_nsigmaSpaceValue, 0);

	waitKey(0);
	//system("pause");
	//getchar();
	//Sleep(10000);
	return 0;
}

void on_bilateralFilterTrackbar(int, void*)
{
	bilateralFilter(g_srcImage, g_dstImage, g_ndValue, g_nsigmaColorValue, g_nsigmaSpaceValue);
	imshow("bilateralFilter", g_dstImage);
}
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
双边滤波是一种可以同时考虑空间距离和像素值差异的滤波方法,可以在去除图像噪声的同时保留图像细节。下面是双边滤波的Matlab代码实现: ```matlab function [output_image] = bilateral_filter(input_image, sigma_d, sigma_r) % 双边滤波函数 % input_image: 输入图像 % sigma_d: 空域滤波器的标准差 % sigma_r: 像素值差异滤波器的标准差 % 将输入图像转换为double类型 input_image = im2double(input_image); % 获取输入图像的大小 [M, N, ~] = size(input_image); % 初始化输出图像 output_image = zeros(M, N, 3); % 定义空域滤波器 [X, Y] = meshgrid(-ceil(3*sigma_d):ceil(3*sigma_d)); space_filter = exp(-(X.^2+Y.^2)/(2*sigma_d^2)); % 对于每个像素进行滤波 for i = 1:M for j = 1:N % 计算像素值差异滤波器 pixel_filter = exp(-((input_image(i,j,1)-input_image(:,:,1)).^2+... (input_image(i,j,2)-input_image(:,:,2)).^2+... (input_image(i,j,3)-input_image(:,:,3)).^2)/(2*sigma_r^2)); % 计算双边滤波bilateral_filter = space_filter .* pixel_filter; % 归一化 bilateral_filter = bilateral_filter / sum(bilateral_filter(:)); % 计算输出像素值 output_image(i,j,1) = sum(sum(input_image(:,:,1).*bilateral_filter)); output_image(i,j,2) = sum(sum(input_image(:,:,2).*bilateral_filter)); output_image(i,j,3) = sum(sum(input_image(:,:,3).*bilateral_filter)); end end % 将输出图像转换为uint8类型 output_image = uint8(output_image*255); ``` 使用方法: ```matlab input_image = imread('input_image.png'); sigma_d = 2; sigma_r = 0.1; output_image = bilateral_filter(input_image, sigma_d, sigma_r); imshow(output_image); ``` 其中,`input_image.png`为输入图像的文件名,`sigma_d`为空域滤波器的标准差,`sigma_r`为像素值差异滤波器的标准差。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值