引导滤波(guided filter)理解和代码实现

最近在学习图片的滤波和去噪的相关知识,查阅了一些资料参考了一些博客,这里做一个整合+理解。参考的博客资料在文末。

引入普通滤波的概念

假设输入图像为p,滤波窗口为wk,经过滤波后的输出图像为q,那么q图的第i个像素是由输入图p中以第i个像素为中心的窗口内的所有像素加权平均得到的,即:

在这里插入图片描述
从公式上来看,普通的例如均值滤波与引导滤波区别在于权重的选择上,也就是Wij(I)的不同。

引导滤波

看到的最多的引导滤波的过程图如图所示:
在这里插入图片描述
我们逐步来看这个图,首先引导滤波有两个输入,原始图p和引导图I。经过滤波后有一个输出q,滤波窗口为Wk.整个引导滤波器的表示为公式:
在这里插入图片描述
其中j∈Wk,j仅仅是在某一个窗口内的下标,Wij(I)是仅仅与引导图I相关的加权平均的那个权重。
首先我们看到引导图I,文章有一个重要的假设,就是使输入引导图I与输出图q之间是一个线性关系,表示为:
在这里插入图片描述
其中ak和bk表示常数参数,注意一个窗口Wk只对应一对常熟参数ak和bk。例如以第一个像素为中心的窗口W1的参数为a1,b1。以第二个像素为中心的窗口w2的参数为a2,b2.
也就是总流程图中的这一部分:
在这里插入图片描述
图中还对线性关系两边求导得到
在这里插入图片描述
这就表示引导图的梯度变化与结果图的梯度变化是线性关系的,假设在引导图中我们知道A区是平滑区域,B区是边缘区域,显然B区梯度比A区要大,而且假设B区的梯度是A区的4倍。通过线性变换,我们得到了输出图q中的A区和B区梯度变为引导图的a倍,但是B区的梯度仍然是A区的4倍,同一幅图中的A和B之间的梯度关系没有被扭曲,通俗来讲就是引导图告诉了输出图哪里是平滑区域,哪里是边缘区域。这就是引导图的作用。
我们已知了引导图I,如果能求得系数ab的值,就可以计算出输出了。这时候就需要引入另外一个概念:噪声
在这里插入图片描述
利用最小二乘法就能计算出参数a,b。
在这里插入图片描述
通过上述的最小二乘法可以计算出参数a,b的表达式
在这里插入图片描述
具体详细的公式推导可以参考链接:
https://blog.csdn.net/weixin_43194305/article/details/88959183
计算出了参数之后,我们就可以将线性模型应用到整个图像的滤波窗口,但一个像素会被多个窗口包含,如下图,若Wk大小为3x3,则除边缘区域的外的每个点会被包含在9个窗口里,因此对于同一个像素,会得到|w|个输出qi。
在这里插入图片描述
我们最后需要用的参数a,b就是所求的平均的参数a,b。
最后将参数代回线性关系公式中,就可以得到输出,过程如下图所示
在这里插入图片描述
matlab实现代码在这里
链接:https://pan.baidu.com/s/12B2s8FuvFH1MBQPKhlz5rg
提取码:oxdw

压缩包中的文件如图所示
在这里插入图片描述
需要注意的是,需要写两个函数文件:boxfilter.m和guidedfilter.m。其中guidedfilter.m需要调用boxfilter.m函数,GuidedFilter_preserveEdge.m是主函数,用来调用guidedfilter函数,本代码用的输入图和引导图是同一张cat.bmp。演示的是保边效果,可以更换引导图和输入图。

  • 26
    点赞
  • 140
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
引导滤波Guided Image Filtering)是一种能够保留图像细节的图像滤波方法,通过引导图像的辅助作用,对待处理图像进行滤波。其主要思想是根据引导图像的特征来调整滤波器的权重,从而使得滤波器更加适应于图像的结构和纹理特征,达到保留细节的效果。 具体实现方法如下: 1. 对待处理图像和引导图像进行预处理,计算它们的均值和方差。 2. 对引导图像进行高斯滤波,得到平滑后的引导图像。 3. 计算待处理图像和引导图像的协方差,并计算得到待处理图像的均值和方差。 4. 计算待处理图像和引导图像的相关系数,并根据相关系数和平滑后的引导图像计算得到滤波器的权重。 5. 根据滤波器的权重和待处理图像的均值、方差,对待处理图像进行滤波。 下面是引导滤波的Matlab代码实现: ```matlab function [q] = guidedfilter(I, p, r, eps) % guidedfilter: Guided image filtering % % Input: % - I: guidance image (should be a gray-scale/single channel image) % - p: filtering input image % - r: radius of filter % - eps: regularization parameter % % Output: % - q: filtering output image % % Reference: % Kaiming He, Jian Sun, and Xiaoou Tang, "Guided Image Filtering," % IEEE Transactions on Pattern Analysis and Machine Intelligence, % Vol. 35, No. 6, pp. 1397-1409, June 2013. % % Author: hqli % Email: hqli@pku.edu.cn % Date: 2016-11-05 % % Check inputs if (ndims(I)~=2) error('The guidance image should be a gray-scale/single channel image.'); end if (ndims(p)==2) % Single-channel image [hei, wid] = size(p); nCh = 1; else % Multi-channel image [hei, wid, nCh] = size(p); end if (size(I,1)~=hei || size(I,2)~=wid) error('The size of the guidance image should be the same as the input image.'); end % Compute mean and covariance matrices mean_I = imboxfilt(I, r) ./ (r^2); mean_p = zeros(hei, wid, nCh); for ii=1:nCh mean_p(:,:,ii) = imboxfilt(p(:,:,ii), r) ./ (r^2); end mean_Ip = zeros(hei, wid, nCh); for ii=1:nCh mean_Ip(:,:,ii) = imboxfilt(I.*p(:,:,ii), r) ./ (r^2); end cov_Ip = mean_Ip - mean_I.*mean_p; % Compute local variances and covariances var_I = imboxfilt(I.^2, r) ./ (r^2) - mean_I.^2; var_p = zeros(hei, wid, nCh); for ii=1:nCh var_p(:,:,ii) = imboxfilt(p(:,:,ii).^2, r) ./ (r^2) - mean_p(:,:,ii).^2; end % Compute weight and bias a = zeros(hei, wid, nCh); b = zeros(hei, wid, nCh); for ii=1:nCh a(:,:,ii) = cov_Ip(:,:,ii) ./ (var_I + eps); b(:,:,ii) = mean_p(:,:,ii) - a(:,:,ii) .* mean_I; end % Compute the filtering output q = zeros(size(p)); for ii=1:nCh q(:,:,ii) = imboxfilt(a(:,:,ii).*p(:,:,ii) + b(:,:,ii), r) ./ (r^2); end ``` 其中,I为引导图像,p为待处理图像,r为滤波器的半径,eps为正则化参数。函数返回值q为滤波后的图像。 下面是引导滤波的OpenCV实现: ```c++ cv::Mat guidedFilter(const cv::Mat& I, const cv::Mat& p, int r, double eps) { // Check inputs CV_Assert(I.channels() == 1); CV_Assert(p.channels() == 1 || p.channels() == I.channels()); CV_Assert(I.rows == p.rows && I.cols == p.cols); // Convert input images to CV_64FC1 cv::Mat I_double, p_double; I.convertTo(I_double, CV_64FC1); p.convertTo(p_double, CV_64FC1); // Compute mean and covariance matrices cv::Mat mean_I, mean_p, mean_Ip, cov_Ip, var_I, var_p; cv::boxFilter(I_double, mean_I, CV_64FC1, cv::Size(r, r)); cv::boxFilter(p_double, mean_p, CV_64FC1, cv::Size(r, r)); cv::boxFilter(I_double.mul(p_double), mean_Ip, CV_64FC1, cv::Size(r, r)); cov_Ip = mean_Ip - mean_I.mul(mean_p); cv::boxFilter(I_double.mul(I_double), var_I, CV_64FC1, cv::Size(r, r)); var_I -= mean_I.mul(mean_I); if (p.channels() == 1) { cv::boxFilter(p_double.mul(p_double), var_p, CV_64FC1, cv::Size(r, r)); var_p -= mean_p.mul(mean_p); } else { std::vector<cv::Mat> p_channels(p.channels()); cv::split(p_double, p_channels); var_p = cv::Mat::zeros(I.rows, I.cols, CV_64FC(p.channels())); for (int i = 0; i < p.channels(); i++) { cv::boxFilter(p_channels[i].mul(p_channels[i]), var_p.channels(i), CV_64FC1, cv::Size(r, r)); var_p.channels(i) -= mean_p.channels(i).mul(mean_p.channels(i)); } } // Compute weight and bias cv::Mat a, b; a = cov_Ip / (var_I + eps); b = mean_p - a.mul(mean_I); // Compute the filtering output cv::Mat q; if (p.channels() == 1) { cv::boxFilter(a.mul(p_double) + b, q, CV_64FC1, cv::Size(r, r)); } else { std::vector<cv::Mat> q_channels(p.channels()); for (int i = 0; i < p.channels(); i++) { cv::boxFilter(a.channels(i).mul(p_channels[i]) + b.channels(i), q_channels[i], CV_64FC1, cv::Size(r, r)); } cv::merge(q_channels, q); } return q; } ``` 其中,I为引导图像,p为待处理图像,r为滤波器的半径,eps为正则化参数。函数返回值q为滤波后的图像。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值