引导滤波(guided image filtering)原理及C++实现

引导滤波

引导滤波是由何凯明等人与2010年提出,它本质上具有O(N)复杂度,相对于双边滤波有更好的边缘保持特性,且不会出现梯度反转现象。在不同引导图像的引导下,可广泛应用于降噪、去雾、高动态范围压缩等。
该方法基于局部线性模型:
引导滤波(guided image filtering)原理及C++实现_第1张图片

代码实现

0、伪代码
引导滤波(guided image filtering)原理及C++实现_第2张图片


1、MATLAB代码
见参考资料【2】

2、C++实现
template
void CImageObj::BoxFilter(K** src, T** dst, int r)
{
	int w = 2 * r + 1;
	int pixCount = w * w;
	int nx = m_width;
	int ny = m_height;
	int i, j, m, n;
	
	for (i = 0; i < ny; ++i)
	{
		for (j = 0; j < nx; ++j)
		{
			int k = 0;
			double sum = 0.0;

			for (m = i - r; m <= i + r; ++m)
			{
				for (n = j - r; n <= j + r; ++n)
				{
					if (m < 0 || m >= ny) { k++; continue; }
					if (n < 0 || n >= nx) { k++; continue; }

					sum += src[m][n];
				}
			}  // 一次窗口滤波

			dst[i][j] = sum / (pixCount - k);
		}  
	}
}

void CImageObj::GIF(uchar** guidenceImg, int radius, double eps)
{
	if (guidenceImg == nullptr || *guidenceImg == nullptr)
		return;

	int cx = m_width;
	int cy = m_height;
	int wndsize = 2 * radius + 1;
	int pixcount = wndsize * wndsize;

	double** a = NewDoubleMatrix(cx, cy);
	double** b = NewDoubleMatrix(cx, cy);
	double** mean_a = NewDoubleMatrix(cx, cy);
	double** mean_b = NewDoubleMatrix(cx, cy);

	int i, j, m, n;
	for (i = 0; i < cy; ++i)
		for (j = 0; j < cx; ++j)
		{
			int k = 0;
			double sum_I = 0.0; 
			double sum_p = 0.0;

			for (m = i - radius; m <= i + radius; ++m)
				for (n = j - radius; n <= j + radius; ++n)
				{
					if (m < 0 || m >= cy) { k++; continue; }
					if (n < 0 || n >= cx) { k++; continue; }

					sum_I += guidenceImg[m][n] / 255.0;
					sum_p += m_imgData[m][n] / 255.0;
				}

			double mean_I = sum_I / (pixcount - k);
			double mean_p = sum_p / (pixcount - k);

			k = 0;
			double sum_Ip = 0.0;
			double sum_var_I = 0.0;
			for (m = i - radius; m <= i + radius; ++m)
				for (n = j - radius; n <= j + radius; ++n)
				{
					if (m < 0 || m >= cy) { k++; continue; }
					if (n < 0 || n >= cx) { k++; continue; }

					sum_Ip += (m_imgData[m][n] / 255.0) * (guidenceImg[m][n] / 255.0);
					sum_var_I += (guidenceImg[m][n] / 255.0 - mean_I) * (guidenceImg[m][n] / 255.0 - mean_I);
				}

			a[i][j] = (sum_Ip / (pixcount - k) - mean_I * mean_p) / (sum_var_I / (pixcount - k) + eps);
			b[i][j] = mean_p - a[i][j] * mean_I;
		}

	BoxFilter(a, mean_a, radius);
	BoxFilter(b, mean_b, radius);

	for (i = 0; i < cy; ++i)
		for (j = 0; j < cx; ++j)
		{
			double tmp = 255 * (mean_a[i][j] * guidenceImg[i][j] / 255.0 + mean_b[i][j]);
			tmp = tmp > 255.0 ? 255.0 : tmp;
			tmp = tmp < 0.0 ? 0.0 : tmp;
			m_imgData[i][j] = (uchar)tmp;
		}

	UpdateImage();
	DeleteDoubleMatrix(a, cx, cy);
	DeleteDoubleMatrix(b, cx, cy);
	DeleteDoubleMatrix(mean_a, cx, cy);
	DeleteDoubleMatrix(mean_b, cx, cy);
}

参考资料

[1] Guided Image Filtering, by Kaiming He, Jian Sun, and Xiaoou Tang, in TPAMI 2013.

[2]  Guided Image Filtering


你可能感兴趣的:(图像处理)