双边滤波原理与C++实现

一、原理

双边滤波(Bilateral filter)是一种可以去噪保边的滤波器。之所以可以达到此效果,是因为滤波器是由两个函数构成:一个函数是由几何空间距离决定滤波器系数,另一个由像素差值决定滤波器系数。

原理示意图如下:

双边滤波器中,输出像素的值依赖于邻域像素的值的加权组合,

权重系数w(i,j,k,l)取决于定义域核

值域核

的乘积

二、C++实现

2.1 OpenCV调用方法:

cvSmooth(m_iplImg, dstImg, CV_BILATERAL, 2 * r + 1, 0, sigma_r, sigma_d);

2.2 MATLAB版代码:

http://www.mathworks.com/matlabcentral/fileexchange/12191-bilateral-filtering/content/Bilateral%20Filtering/bfilter2.m

调用方法参见资料[1]

2.3 C++代码

void CImageObj::Bilateral_Filter(int r, double sigma_d, double sigma_r)
{
	int i, j, m, n, k;
	int nx = m_width, ny = m_height;
	int w_filter = 2 * r + 1; // 滤波器边长

	double gaussian_d_coeff = -0.5 / (sigma_d * sigma_d);
	double gaussian_r_coeff = -0.5 / (sigma_r * sigma_r);

	double** d_metrix = NewDoubleMatrix(w_filter, w_filter);  // spatial weight
	double r_metrix[256];  // similarity weight

	// copy the original image
	double* img_tmp = new double[m_nChannels * nx * ny];
	for (i = 0; i < ny; i++)
		for (j = 0; j < nx; j++)
			for (k = 0; k < m_nChannels; k++)
			{
				img_tmp[i * m_nChannels * nx + m_nChannels * j + k] = m_imgData[i * m_nChannels * nx + m_nChannels * j + k];
			}

	// compute spatial weight
	for (i = -r; i <= r; i++)
		for (j = -r; j <= r; j++)
		{
			int x = j + r;
			int y = i + r;

			d_metrix[y][x] = exp((i * i + j * j) * gaussian_d_coeff);
		}

	// compute similarity weight
	for (i = 0; i < 256; i++)
	{
		r_metrix[i] = exp(i * i * gaussian_r_coeff);
	}

	// bilateral filter
	for (i = 0; i < ny; i++)
		for (j = 0; j < nx; j++)
		{
			for (k = 0; k < m_nChannels; k++)
			{
				double weight_sum, pixcel_sum;
				weight_sum = pixcel_sum = 0.0;

				for (m = -r; m <= r; m++)
					for (n = -r; n <= r; n++)
					{
						if (m*m + n*n > r*r) continue;

						int x_tmp = j + n;
						int y_tmp = i + m;

						x_tmp = x_tmp < 0 ? 0 : x_tmp;
						x_tmp = x_tmp > nx - 1 ? nx - 1 : x_tmp;   // 边界处理,replicate
						y_tmp = y_tmp < 0 ? 0 : y_tmp;
						y_tmp = y_tmp > ny - 1 ? ny - 1 : y_tmp;

						int pixcel_dif = (int)abs(img_tmp[y_tmp * m_nChannels * nx + m_nChannels * x_tmp + k] - img_tmp[i * m_nChannels * nx + m_nChannels * j + k]);
						double weight_tmp = d_metrix[m + r][n + r] * r_metrix[pixcel_dif];  // 复合权重

						pixcel_sum += img_tmp[y_tmp * m_nChannels * nx + m_nChannels * x_tmp + k] * weight_tmp;
						weight_sum += weight_tmp;
					}

				pixcel_sum = pixcel_sum / weight_sum;
				m_imgData[i * m_nChannels * nx + m_nChannels * j + k] = (uchar)pixcel_sum;

			} // 一个通道

		} // END ALL LOOP

	UpdateImage();
	DeleteDoubleMatrix(d_metrix, w_filter, w_filter);
	delete[] img_tmp;
}

性能方面,跟OpenCV处理速度有差距,有兴趣的,可以自己研究OpenCV版本的源代码

三、效果图

四、参考资料

资料[4]是MIT的学习资料,最全面,包括课件、论文、代码等,涵盖原理、改进、应用、与PDE的联系等等,最值得一看。

[1] 双边滤波器的原理及实现[Rachel-Zhang]

[2]【OpenCV】邻域滤波:方框、高斯、中值、双边滤波

[3] Bilateral Filtering(双边滤波) for SSAO

[4] MIT学习资料

时间: 2024-08-05 02:11:39

双边滤波原理与C++实现的相关文章

双边滤波

Qt 平台,双边滤波原理代码例如以下: #include <QCoreApplication> #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <iostream> #include <cmath> using namespace cv; usi

OpenCL双边滤波实现美颜功能

OpenCL是一个并行异构计算的框架,包括intel,AMD,英伟达等等许多厂家都有对它的支持,不过英伟达只到1.2版本,主要发展自己的CUDA去了.虽然没有用过CUDA,但个人感觉CUDA比OpenCL更好一点,但OpenCL支持面更管,CPU,GPU,DSP,FPGA等多种芯片都能支持OpenCL.OpenCL与D3D中的像素着色器非常相似. 1.双边滤波原理 双边滤波器的原理参考女神Rachel-Zhang的博客 双边滤波器的原理及实现. 引自Rachel-Zhang的博客,原理如下: 双

图像平滑技术之盒滤波、均值滤波、中值滤波、高斯滤波、双边滤波的原理概要及OpenCV代码实现

图像平滑是指直接对源图像的每个像素数据做邻域运算以达到平滑图像的目的.实质上主要就是通达卷积核算子实现的,卷积核算子的相关知识大家可以参考我写的博文http://blog.csdn.net/wenhao_ir/article/details/51691410 图像平滑也称为模糊或滤波,是图像处理中常用的技术之一,进行平滑处理时需要用到滤波器核(其实就是卷积核算子),根据滤波器核函数来实现不同的滤波技术.下面介绍几种 常用的图像平滑方法的大概原理及OpenCV下的实现代码. 一.盒滤波(均值滤波)

双边滤波算法原理及实现

双边滤波算法原理 双边滤波是一种非线性滤波器,它可以达到保持边缘.降噪平滑的效果.和其他滤波原理一样,双边滤波也是采用加权平均的方法,用周边像素亮度值的加权平均代表某个像素的强度,所用的加权平均基于高斯分布[1].最重要的是,双边滤波的权重不仅考虑了像素的欧氏距离(如普通的高斯低通滤波,只考虑了位置对中心像素的影响),还考虑了像素范围域中的辐射差异(例如卷积核中像素与中心像素之间相似程度.颜色强度,深度距离等),在计算中心像素的时候同时考虑这两个权重. 双边滤波的核函数是空间域核与像素范围域核的

双边滤波和引导滤波的原理

双边滤波很有名,使用广泛,简单的说就是一种同时考虑了像素空间差异与强度差异的滤波器,因此具有保持图像边缘的特性. 先看看我们熟悉的高斯滤波器 其中W是权重,i和j是像素索引,K是归一化常量.公式中可以看出,权重只和像素之间的空间距离有关系,无论图像的内容是什么,都有相同的滤波效果. 再来看看双边滤波器,它只是在原有高斯函数的基础上加了一项,如下 其中 I 是像素的强度值,所以在强度差距大的地方(边缘),权重会减小,滤波效应也就变小.总体而言,在像素强度变换不大的区域,双边滤波有类似于高斯滤波的效

Bilateral Filtering(双边滤波) for SSAO

原网址:http://blog.csdn.net/bugrunner/article/details/7170471 1. 简介 图像平滑是一个重要的操作,而且有多种成熟的算法.这里主要简单介绍一下Bilateral方法(双边滤波),这主要是由于前段时间做了SSAO,需要用bilateral blur 算法进行降噪.Bilateral blur相对于传统的高斯blur来说很重要的一个特性即可可以保持边缘(Edge Perseving),这个特点对于一些图像模糊来说很有用.一般的高斯模糊在进行采样

Bilateral Filtering(双边滤波) for SSAO(转)

原文链接:http://blog.csdn.net/bugrunner/article/details/7170471 另外一篇相似的英文资料:http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MANDUCHI1/Bilateral_Filtering.html#Index   1. 简介 图像平滑是一个重要的操作,而且有多种成熟的算法.这里主要简单介绍一下Bilateral方法(双边滤波),这主要是由于前段时间做了SSAO,需要用b

双边滤波CUDA优化——BilateralFilter CUDA

=======双边滤波概述======= 双边滤波(Bilateral filter)是一种可以保边去噪的滤波器.之所以可以达到此去噪效果,是因为滤波器是由两个函数构成.一个函数是由几何空间距离决定滤波器系数.另一个由像素差值决定滤波器系数.可以与其相比较的两个filter:高斯低通滤波器(http://en.wikipedia.org/wiki/Gaussian_filter)和α-截尾均值滤波器(去掉百分率为α的最小值和最大之后剩下像素的均值作为滤波器). =======双边滤波公式====

Bilateral Filtering(双边滤波)算法研究

1. 简介 图像平滑是一个重要的操作,而且有多种成熟的算法.这里主要简单介绍一下Bilateral方法(双边滤波),这主要是由于前段时间做了SSAO,需要用bilateral blur 算法进行降噪.Bilateral blur相对于传统的高斯blur来说很重要的一个特性即可可以保持边缘(Edge Perseving),这个特点对于一些图像模糊来说很有用.一般的高斯模糊在进行采样时主要考虑了像素间的空间距离关系,但是却并没有考虑像素值之间的相似程度,因此这样我们得到的模糊结果通常是整张图片一团模