滤波器的种类显式定义的线性移不变LTI滤波器有高斯滤波器拉普拉斯滤波器Sobel算子用在图像平滑锐化边缘检测特征提取中。这些LTI滤波器的参数有的是手工定义的如sobel算子有的是求解Poisson方程的过程中得到的比如高动态范围HDR图像拼接图像matting抠图在这些应用中滤波器的核被隐式定义为homogenous Laplacian matrix的逆。但共同点是滤波器参数和图像内容是无关的并且是平移不变的。双边滤波器LTI的不变性指的是滤波器核在不同位置处参数是相同的所以也不会根据图像内容做出调整。而在很多应用中输出都是和输入密切关联的比如图像上色图像抠图所以我们需要额外的信息作为参考。具体的实现方法有两种一种是最优化的方法通过优化一个二次方程quadratic function在输出与引导图直接添加约束通过求解一个稀疏矩阵得到结果在这个过程中实际隐式定义了一个移变的滤波器核。这种方法性能好但是耗时长。第二种方法是显示定义滤波器核。双边滤波就是最成功的一个它同时考虑了邻域像素加权还考虑了引导图中灰度值的相似性。从公式上看就是两个高斯的乘积一个高斯是正常的和像素坐标相关的另外一个是和对应位置的像素值有关。双边滤波可以在平滑的同时保留边缘不需要迭代复杂度暴力实现的话是O(r^2)直方图或者积分图可以达到O(1)。但是更严重的问题是可能出现梯度失真产生梯度反转的人造现象gradient reversal artifacts。联合双边滤波双边滤波虽然考虑了图像内容但仍然是自身的图像。联合双边滤波是在双边滤波的基础上引入了guidance image I这样滤波器参数由I决定得到的参数就是 translation-variant 的。在具体参数的确定上沿用的还是双边滤波高斯权重的思路表达式结构是两个e指数的乘积两个e指数分别代表空间的相似度和灰度值上的相似度。所以当引导图就是输入图时联合双边滤波退化为双边滤波。导向滤波导向滤波其实是何恺明为了解决暗通道去雾的一个计算过程提出的一种滤波方法。这里假设带雾的图是干净图和雾图的加权融合其中雾图也就是透射率图Transmission Map可以通过暗通道先验粗略得到暗通道不仅仅是“通道间取最小”还包含了“局部区域内取最小”的空间操作。在代码实现中第一步通常用np.min(image, axis2)实现而第二步通常通过形态学腐蚀cv2.erode或最小值滤波min-filter来高效完成。但是这样得到的Transmission Map还是太粗糙不仅有很多噪点而且在物体的边缘处会出现严重的“块效应Blocking Artifacts”和“光晕效应Halo”。所以就需要导向滤波进一步加工。下面最右就是导向滤波之后的效果如果我们想要滤波的同时保留边缘很自然地会想到先使用边缘检测器得到边缘图滤波的时候就可以以此作为参考。导向滤波其实也一样导向滤波有一个十分重要的假设输出是导向图的局部线性变换。这样就保证了引导图和滤波后的图梯度相同最起码也是线性相关的即实现了“保边”特别地可以将原图作为guidance image此时的结果输出就是保留边缘的平滑结果在这个过程中其实就利用了guidance image中的结构信息。作为边缘保持滤波器导向滤波效果更好速度快时间线性复杂度计算复杂度与滤波器核尺寸无关。引导滤波可以保留边缘但是不会有人工效应而且它还和matting Lapalacian 矩阵有关复杂度和像素点的数目呈线性。但更重要的是导向滤波还有其他用处与matting Laplacian matrix有理论联系可以用在图像去噪HDRdetail 平滑/增强等领域中。求解系数和普通的滤波器一样导向滤波的输出q也是输入原始图像p的线性加权和只不过加权函数是关于引导图的线性函数。为了确定线性模型的系数a和b使用了最小二乘滤波/维纳滤波的思想。维纳假定线性滤波器的输入为有用信号和噪声之和两者均为广义平稳过程且知它们的二阶统计特性根据最小均方误差准则(滤波器的输出信号与需要信号之差的均方值最小)求得了最佳线性滤波器的参数计算位置i处的权重参数a和b需要假定ab在窗口为的范围内是常数这样就可以使用上面的公式求解。但这样就造成每个像素点位置会属于多个窗口而每个窗口会计算一组ab所以每个像素都会经历多组ab的滤波之后再求均值即便如此我们仍然可以认为q的梯度和I的梯度是呈正比的。式子中还有一个正则项避免系数a过大。所以求线性模式参数的过程是线性岭回归的过程认为噪声是加性噪声同时以参数a的L2范数作为正则项。a的解整体形式是引导图与输入图的协方差与引导图方差的比值可以看作是输入图p与引导图I的相关性。b则是在p的均值滤波的基础上结合引导图的均值做一个补偿。像双边滤波一样保边即便引导图是原图引导滤波也有保留边缘的特性这一点怎么理解呢由公式可以看出当Ip输入图的均值和引导图的均值相等ab公式可以写为下面的样子如果窗口位于平坦区域方差远小于epsliona0bavg(p)滤波效果相当于均值滤波如果位于边缘区域协方差/方差很大a1b0所以在这个位置没有进行平均可以保持边缘。这样正则系数控制了滤波平滑的程度正则系数越大越容易平滑正则系数越大则越接近保留边缘。事实上正则系数相当于双边滤波器中的range variance参数。除了正则系数还有窗口大小的参数这样构成了两级的平均值滤波器。窗口大小参数r相当于双边滤波器中的space variance。但是不会梯度反转图像增强的一般流程是这样的input经过保边滤波得到base layerbase layer和input相减得到detail对detail放大后再加在base layer上。在双边滤波中base layer会和input不一致因为在边缘的地方range kernel会不可靠base layer会更sharpdetail在减法时就会出现负数而之后的放大操作会把这个误差放大。而在导向滤波中保证了系数a一直是小于1的所以原始信号减去滤波结果一直的大于0的所以也就不会出现梯度的反转。还可以细化边缘mask既然导向滤波的输出是导向图的线性关系当滤波的输入图是图像分割mask导向图是原图时可以通过导向滤波将结构细节传递给分割mask这时导向滤波就作为了Structure-Transferring Filtering。实现代码代码的关键就是求引导图与输入图的协方差矩阵和引导图的方差图。设X和Y是两个随机变量,它们各自的期望分别是E(X)和E(Y)。那么X和Y的协方差定义为:Cov(X,Y)E[(X-E(X))(Y-E(Y))]利用期望的线性性质,可以展开上式得到:Cov(X,Y)E(XY)-E(X)E(Y)具体到图像均值和加窗都可以使用blur运算得到元素相乘直接使用矩阵对应元素相乘。计算得到ab之后再加窗void guidedFilter(cv::Mat guidiance, cv::Mat src, cv::Mat dst, const int r, float eps) { // Convert to float cv::Mat p, I; src.convertTo(p, CV_32F); guidiance.convertTo(I, CV_32F); ​ // Guided Filtering const cv::Size wsz(r, r); cv::Mat pm, Im, Ipm, IIm; cv::blur(p, pm, wsz); cv::blur(I, Im, wsz); cv::blur(p.mul(I), Ipm, wsz); cv::blur(I.mul(I), IIm, wsz); ​ cv::Mat a, b, am, bm; a (Ipm- pm.mul(Im)) / (IIm - Im.mul(Im) eps); b pm- a.mul(Im); cv::blur(a, am, wsz); cv::blur(b, bm, wsz); ​ dst am.mul(I) bm; dst.convertTo(dst, CV_8U); }referencehttps://kaiminghe.github.io/eccv10/eccv10ppt.pdfhttps://arxiv.org/pdf/1505.00996.pdfGuided Image Filtering | IEEE Journals Magazine | IEEE Xplore机器学习| 算法笔记-线性回归Linear Regression - 知乎导向滤波 - 知乎https://github.com/atilimcetin/guided-filter/blob/master/guidedfilter.cpphttps://link.springer.com/content/pdf/10.1007/978-3-642-15549-9_1.pdf