CV toolbox (1) - guided filter

Guided Image Filter 学习笔记

  • 相关滤波器学习
    • Bilateral Filter
      • 空间核函数
      • 值域核函数
      • 权值 w w w
      • 应用模型
        • input_part
        • output_part
        • process_part
      • 代码实现
  • Guided Filter
    • W i j ( I ) W_{ij}(I) Wij(I)的求解过程
    • guided filter 代码实现
      • boxfilter
        • boxfilter代码实现
    • what's more, fast-guided-filter
      • fast-guided-filter代码实现
    • guided filter的应用
      • 图像去雾应用
        • haze_rm 代码实现
        • 去雾实验
          • 就地实验
          • 实验结果反思
            • minfilter 代码实现
            • minfilter 滤波对比

相关滤波器学习

Bilateral Filter

Bilateral Filter 为双边滤波, 其降噪效果在达到平滑降噪的功能的同时亦能保护边缘特征(edge-preserving). 这与他的滤波器的两个功能函数有关, 第一个便是空间核域函数, 这个函数通过欧氏距离来衡量每一个filter中各个像素与中心像素的距离来给每一个像素赋予权重; 第二个便是值域核函数, 这个函数通过对每一个filter中各个像素值与中心像素值的差值来对该filter中的每一个像素赋予权重.

在对Bilateral Filter的学习过程中, 借鉴了pan_jinquan博客的相关内容.

首先, 引用其他博主的关于对区域边缘的理解, 如下:

我们都知道,一幅自然的图像可以被看成是有(过渡平缓的,也就是梯度较小)区域和(过渡尖锐的,也就是梯度较大)边缘(也包括图像的纹理、细节等)共同组成的。噪声是影响图像质量的不利因素,我们希望将其滤除。噪声的特点通常是以其为中心的各个方向上梯度都较大而且相差不多。边缘则不同,边缘相比于区域也会出现梯度的越变,但是边缘只有在其法向方向上才会出现较大的梯度,而在切向方向上梯度较小。

空间核函数

w d i , j ( k , l ) = e x p ( − ( k − i ) 2 + ( l − j ) 2 2 σ 2 ) w_d^{i, j}(k, l) = exp(-\frac{(k - i)^2 + (l - j)^2}{2\sigma^2}) wdi,j(k,l)=exp(2σ2(ki)2+(lj)2)
在该数学函数式中, (i, j)为该filter的中心的坐标, (k, l)为filter中每一个像素点的坐标, ( k − i ) 2 + ( l − j ) 2 (k - i)^2 + (l - j)^2 (ki)2+(lj)2为该像素点与中心像素点的欧式空间距离, 下部的 σ \sigma σ正态分布的标准差;

理解:在某一个filter中, 距离中心像素点越近, 其空间核函数的值越大; 反之, 距离中心像素点越远, 其空间核函数值越小. 在相对较平坦区域, 该函数其主要作用. 可以结合下图理解空间核函数.
CV toolbox (1) - guided filter_第1张图片

值域核函数

w r i , j ( k , l ) = e x p ( − ( f ( k , l ) − f ( i , j ) ) 2 2 σ 2 ) w_r^{i, j}(k, l) = exp(-\frac{(f(k, l) - f(i, j))^2}{2\sigma^2}) wri,j(k,l)=exp(2σ2(f(k,l)f(i,j))2)
在该数学函数式中, f ( i , j ) f(i, j) f(i,j)为该filter中心像素的值, f ( k , l ) f(k, l) f(k,l)为filter中周围的像素点的值.

理解: 在某一个filter中, 周围像素点的值与中心像素点的值越接近, w r w_r wr所给赋予该像素点的值域权重越大; 反之, 周围像素点的值与中心像素点的值相差越大, w r w_r wr所给赋予该像素点的值域权重越小. 这样的处理方式保证了在对边缘处理时的特征保留, 即在陡峭区域, 该函数起主要作用.

权值 w w w

w i , j ( k , l ) = w d i , j ( k , l ) ∗ w r i , j ( k , l ) w_{i, j}(k, l) = w_d^{i, j}(k, l) * w_r^{i, j}(k, l) wi,j(k,l)=wdi,j(k,l)wri,j(k,l)

应用模型

将应用模型分为三个部分, input_part§, process_part(箭头), output_part()q
CV toolbox (1) - guided filter_第2张图片

input_part

左图为输入部分, 我们想计算机输入一张图片, 假设该图片为 m ∗ n m*n mn像素, 我们可以用一个矩阵来表示输入的内容:
i n p u t C o n t e n t = [ i n p u t 1 , 1 … i n p u t 1 , n … i n p u t i , j … i n p u t m , 1 … i n p u t m , n ] inputContent = \begin{bmatrix} input_{1, 1}&…&input_{1, n}\\ \\…&input_{i, j}&…\\ \\input_{m, 1}&…&input_{m, n} \end{bmatrix} \quad inputContent=input1,1inputm,1inputi,jinput1,ninputm,n

output_part

右图为输出部分, 经过处理后, 计算机将输出一张和输入图片同尺寸的图片, 我们也用一个矩阵存储.
o u t p u t C o n t e n t = [ o u t p u t 1 , 1 … o u t p u t 1 , n … o u t p u t i , j … o u t p u t m , 1 … o u t p u t m , n ] outputContent = \begin{bmatrix} output_{1, 1}&…&output_{1, n}\\ \\…&output_{i, j}&…\\ \\output_{m, 1}&…&output_{m, n} \end{bmatrix} \quad outputContent=output1,1outputm,1outputi,joutput1,noutputm,n

process_part

处理输入的数据, 输出处理后的数据, 便是process_part的功能, 具体处理过程如下:
i n p u t C o n t e n t inputContent inputContent处理成一个 m ∗ n ∗ ( t ∗ t ) m*n*(t * t ) mn(tt)的矩阵 i n p u t C o n t e n t ′ inputContent' inputContent, 其元素 i n p u t C o n t e n t i , j ′ inputContent'_{i, j} inputContenti,j的值为 ( n ∗ n ) (n * n) (nn)的矩阵,
o u t p u t C o n t e n t i , j ′ = [ i n p u t i − n 2 , j − n 2 … i n p u t i − n 2 , j … i n p u t i , j … i n p u t i + n 2 , j − n 2 … i n p u t i + n 2 , j + n 2 ] outputContent'_{i, j} = \begin{bmatrix} input_{i - \frac{n}{2}, j - \frac{n}{2}}&…&input_{i - \frac{n}{2}, j }\\ \\…&input_{i, j}&…\\ \\input_{i + \frac{n}{2}, j - \frac{n}{2}}&…&input_{i + \frac{n}{2}, j + \frac{n}{2}} \end{bmatrix} \quad outputContenti,j=inputi2n,j2ninputi+2n,j2ninputi,jinputi2n,jinputi+2n,j+2n
w i , j = [ w d i , j ( i − n 2 , j − n 2 ) … w d i , j ( i − n 2 , j ) … w d i , j ( i , j ) … w d i , j ( i + n 2 , j + n 2 ) … w d i , j ( i + n 2 , j + n 2 ) ] w_{i, j} = \begin{bmatrix} w_d^{i, j}(i - \frac{n}{2}, j - \frac{n}{2})&…&w_d^{i, j}(i - \frac{n}{2}, j)\\ \\…&w_d^{i, j}(i, j)&…\\ \\w_d^{i, j}(i + \frac{n}{2}, j + \frac{n}{2})&…&w_d^{i, j}(i + \frac{n}{2}, j + \frac{n}{2}) \end{bmatrix} \quad wi,j=wdi,j(i2n,j2n)wdi,j(i+2n,j+2n)wdi,j(i,j)wdi,j(i2n,j)wdi,j(i+2n,j+2n)
o u t p u t i , j = w i , j ( . ∗ ) o u t p u t C o n t e n t i , j ′ output_{i, j} = w_{i, j}(.*)outputContent'_{i, j} outputi,j=wi,j(.)outputContenti,j
对每一个 o u t p u t i , j output_{i, j} outputi,j重复以上步骤, 便可得到output_part.

代码实现

Guided Filter

导向滤波与前者相比怎加了“导向”的这个概念, 在对 i n p u t input input进行滤波的过程中, 引入了引导图 I I I. 滤波的数学公式如下:
q i = ∑ j W i j ( I ) ⋅ p j q_{i} = \sum_{j}W_{ij}(I)·p_{j} qi=jWij(I)pj
在这个公式中, p i p_{i} pi i n p u t input input的第 j j j个像素的值, q i q_{i} qi o u t p u t output output的第 i i i个像素的值, 参数 W i j ( I ) W_{ij}(I) Wij(I)是在引导图 I I I的基础上的得出的.
Moreover, 该式子可以表达成以下的矩阵形式.
输出的矩阵为一个 j ∗ 1 j*1 j1的矩阵.
q = [ q 1 … q j ] q = \begin{bmatrix} q_{1}&…&q_{j}\\\end{bmatrix} \quad q=[q1qj]
输入的矩阵为一个 i ∗ 1 i*1 i1的矩阵.
p = [ p 1 … p j ] p = \begin{bmatrix} p_{1}&…&p_{j}\\\end{bmatrix} \quad p=[p1pj]
在处理的过程中 W ( I ) W(I) W(I)矩阵便承担起了将输入数据转化为输出数据的任务.
W ( I ) = [ W 1 , 1 ( I ) … W 1 , j ( I ) … … W i , 1 ( I ) … W i j ( I ) ] W(I) = \begin{bmatrix} W_{1, 1}(I)&…&W_{1, j}(I)\\ \\…&&…\\ \\W_{i, 1}(I)&…&W_{ij}(I)\end{bmatrix} \quad W(I)=W1,1(I)Wi,1(I)W1,j(I)Wij(I)
接下来我们的任务便是在已知guided image I I I的情况下, 将 W ( I ) W(I) W(I)矩阵求出来.

W i j ( I ) W_{ij}(I) Wij(I)的求解过程

滤波器在滤波的过程中会将图片磨平, 而传统的滤波器在滤波的过程中容易受到图片区域的边界(陡峭部分)的影响, 会将边界当作需要磨平的区域, 进而将边界也磨平. 而这并不是我们所想要的结果, 于是, guided image便在此发挥的它的作用, 告诉滤波器那里是边界, 在边界的地方我们需要保留图片的边缘特征信息, 而不是将它磨平. 可以引用paper中的图片来理解这一过程.
CV toolbox (1) - guided filter_第3张图片
在图片中, q i = p i − n i q_i = p_i - n_i qi=pini可以看成滤波器降噪的过程, n i n_i ni是噪声; q i = a I i + b q_i = aI_i + b qi=aIi+b便是guided image发挥作用的过程.

q i = a I i + b q_i = aI_i + b qi=aIi+b, 可以看出 q i q_i qi I i I_i Ii之间是线性的, 所以对 a a a b b b的求解就显得非常重要了.

为了得到最适合的 a a a b b b, 依据无约束图像复原的方法, 优化目标是 m i n i m i z e ( n ) minimize(n) minimize(n), 于是有
a r g m i n ∑ i ( q i − p i ) 2 argmin\sum_{i}(q_i - p_i)^2 argmini(qipi)2
在求解此类问题, 通常采用最小二乘法的方法, 为了防止过拟合问题, 在loss function中添加惩罚项是有必要的, 优化目标函数如下:
E ( a k , b k ) = ∑ i ∈ w k [ ( a k I i + h k − p i ) 2 + ϵ a k 2 ] E(a_k, b_k) = \sum_{i \in w_k}[(a_kI_i + h_k - p_i)^2 + \epsilon a_k^2] E(ak,bk)=iwk[(akIi+hkpi)2+ϵak2]
可得, 最终的优化结果为:
a k = 1 ∣ w ∣ ∑ i ∈ w k I i p i − μ i p k ‾ σ k 2 + ϵ a_k = \frac{\frac{1}{|w|}\sum_{i \in w_k}I_ip_i - \mu_i\overline{p_k}}{\sigma_k^2 + \epsilon} ak=σk2+ϵw1iwkIipiμipk
b k = p k ‾ − a k μ k b_k = \overline{p_k} - a_{k}\mu_{k} bk=pkakμk
在式子中, μ k \mu_k μk是guided image中第 k k k个窗口 w k w_k wk的平均值, σ K 2 \sigma_K^2 σK2是其方差, ∣ w ∣ |w| w为窗口 w k w_k wk的像素数量, p k ‾ \overline{p_k} pk为input image p p p的窗口 w k w_k wk的平均值.

在计算 q i q_i qi时, 我们可以发现 o u t p u t output output的每一个像素会被多个filter给包含, 于是我们可以用每个像素的权重平均值来处理, 如下:
q i = 1 ∣ w ∣ ∑ k : i ∈ w k ( a k I i + b k ) = a i ‾ I i + b i ‾ q_i = \frac{1}{|w|}\sum_{k:i\in w_k}(a_kI_i + b_k) = \overline{a_i}I_i + \overline{b_i} qi=w1k:iwk(akIi+bk)=aiIi+bi

式子中, a i ‾ = 1 ∣ w ∣ ∑ k ∈ w i a k \overline{a_i} = \frac{1}{|w|}\sum_{k\in w_i}a_k ai=w1kwiak, b i ‾ = 1 ∣ w ∣ ∑ k ∈ w i b k \overline{b_i} = \frac{1}{|w|}\sum_{k\in w_i}b_k bi=w1kwibk.

综上, 整个算法的流程下:

B e g i n : Begin: Begin:

1 s t 1st 1st, 计算 I I I p p p的每个窗口的平均值, 存入 m e a n O f L meanOfL meanOfL m e a n O f P meanOfP meanOfP中;

2 n d 2nd 2nd, 计算 I I I的方差和和 I − p I-p Ip协方差, 存入 v a r O f L varOfL varOfL c o v O f L P covOfLP covOfLP中; 用于接下来的最小二乘法优化求解;

3 r d 3rd 3rd, 最小二乘法优化求解, 求解出 a a a b b b;

4 t h 4th 4th, 求出 a a a b b b的中每个窗口的均值保存在 m e a n O f A meanOfA meanOfA m e a n O f B meanOfB meanOfB中;

5 t h 5th 5th, q = m e a n o f A . ∗ L + m e a n O f B q = meanofA .* L + meanOfB q=meanofA.L+meanOfB

E n d End End

在以上的算法中, 出现了求一个image的每个窗口均值的过程, 在此处我们使用boxfilter的方法(后文附实现过程).

guided filter 代码实现

function q = guidedfilter(L, P, r, epsilon)
% L为guided image
% P为待处理的image
% r为filter的半径
% epsilon为最小二乘法中的惩罚参数

sizeOfFilter = boxfilter(ones(size(L)), r);
%% 1st
meanOfL = boxfilter(L, r) ./ sizeOfFilter;
meanOfP = boxfilter(P, r) ./ sizeOfFilter;
meanOfLtimeL = boxfilter(L .* L, r) ./ sizeOfFilter;
meanOfLtimeP = boxfilter(L .*P, r) ./ sizeOfFilter;

%% 2nd
% 在协方差计算公式中, 如果两个变量下相同, 计算结果便是该变量的方差
varOfL = meanOfLtimeL - meanOfL .* meanOfL;
% 协方差计算
covOfLP = meanOfLtimeP - meanOfL .* meanOfP;

%% 3rd
% 计算a的值
a = covOfLP ./ (varOfL + epsilon);
% 计算b的值
b = meanOfP - a .* meanOfL;

%% 4th
% a中每个filter的平均值
meanOfA = boxfilter(a, r) ./ sizeOfFilter;
% b中每个filter的平均值
meanOfB = boxfilter(b, r) ./ sizeOfFilter;

%% 5th
q = meanOfA .* L + meanOfB;

end

boxfilter

CV toolbox (1) - guided filter_第4张图片

Boxfilter的初始化过程如下:
1、给定一张图像,宽高为(M,N),确定待求矩形模板的宽高(m,n),如图紫色矩形。图中每个黑色方块代表一个像素,红色方块是假想像素。
2、开辟一段大小为M的数组,记为buff, 用来存储计算过程的中间变量,用红色方块表示
3、将矩形模板(紫色)从左上角(0,0)开始,逐像素向右滑动,到达行末时,矩形移动到下一行的开头(0,1),如此反复,每移动到一个新位置时,计算矩形内的像素和,保存在数组A中。以(0,0)位置为例进行说明:首先将绿色矩形内的每一列像素求和,结果放在buff内(红色方块),再对蓝色矩形内的像素求和,结果即为紫色特征矩形内的像素和,把它存放到数组A中,如此便完成了第一次求和运算。
4、每次紫色矩形向右移动时,实际上就是求对应的蓝色矩形的像素和,此时只要把上一次的求和结果减去蓝色矩形内的第一个红色块,再加上它右面的一个红色块,就是当前位置的和了,用公式表示 sum[i] = sum[i-1] - buff[x-1] + buff[x+m-1]
5、当紫色矩形移动到行末时,需要对buff进行更新。因为整个绿色矩形下移了一个像素,所以对于每个buff[i], 需要加上一个新进来的像素,再减去一个出去的像素,然后便开始新的一行的计算了。

boxfilter代码实现

function imDist = boxfilter_w_h(imSrc, r_w, r_h)

% imSrc 是待boxfilter处理的矩阵
% r_w, r_h 分别是窗口的x, y方向的半径
[hei, wid] = size(imSrc);
imCum = zeros(size(imSrc));
imDist = zeros(size(imSrc));

% 对y方向求窗口中心值累加
imCum = cumsum(imSrc, 1);
imDist(1: r_h + 1, :) = imCum(r_h + 1: 2 * r_h + 1, :);
imDist(r_h + 2: hei - r_h, :) = imCum(2 * r_h + 2: hei, :) - imCum(1: hei - 2 * r_h - 1, :);
imDist(hei - r_h + 1: hei, :) = repmat(imCum(hei, :), [r_h, 1]) - imCum(hei - 2 * r_h: hei - r_h - 1, :);

% 对x方向求窗口中心值累加
imCum = cumsum(imDist, 2);
imDist(:, 1: r_w + 1) = imCum(:, r_w + 1: 2 * r_w + 1);
imDist(:, r_w + 2: wid - r_w) = imCum(:, 2 * r_w + 2: wid) - imCum(:, 1: wid - 2 * r_w - 1);
imDist(:, wid - r_w + 1: wid) = repmat(imCum(:, wid), [1, r_w]) - imCum(:, wid - 2 * r_w: wid - r_w - 1);

end

e.g. 在guided filter中调用时使用的是 r w r_w rw r h r_h rh相等的boxfilter函数.

what’s more, fast-guided-filter

在guided filter的基础上, 我们引入采样率的概念, 假设采样率为s, guided filter的时间复杂度可以从原本的 O ( N ) O(N) O(N)降低到 O ( N / s 2 ) O(N/s^2) O(N/s2). 而实现采样率的方法便是在原guided filter的算法前通过MATLAB中的imresize()将图像缩小 s 2 s^2 s2倍, 并在原guided filter算法的 5 t h 5th 5th之前加上imresize()将图像放大原缩小倍数.

fast-guided-filter代码实现

function q = fastguidedfilter(L, P, r, epsilon, s)
% L 是guded image
% P 是输入的图像
% r是filter的半径大小
% epsilon是loss function的惩罚项
% s 是采样度

Ls = imresize(L, 1/s, 'nearest');
Ps = imresize(P, 1/s, 'nearest');
rs = r / s;

% sizeOfFilter保存每个filter的大小
sizeOfFilter = boxfilter(ones(size(Ls)), rs);
% meanOfLs保存L中每个filter的平均值
meanOfLs = boxfilter(Ls, rs) ./ sizeOfFilter;
meanOfPs = boxfilter(Ps, rs) ./ sizeOfFilter;
meanOfLsTimeLs = boxfilter(Ls .* Ls, rs) ./ sizeOfFilter;
meanOfLsTimePs = boxfilter(Ls .* Ps, rs) ./ sizeOfFilter;

% 协方差中两个变量若一样, 所得结果便是方差
varOfLs = meanOfLsTimeLs - meanOfLs .* meanOfLs;
% Ls和Ps的协方差
covOfLsPs = meanOfLsTimePs - meanOfLs .* meanOfPs;

% 最小二乘法求解参数a和b
a = covOfLsPs ./ (varOfLs + epsilon);
b = meanOfPs - a .* meanOfLs;

% 参数a的filter平均值
meanOfA = imresize(boxfilter(a, rs) ./ sizeOfFilter, size(L), 'bilinear');
% 参数b的filter平均值
meanOfB = imresize(boxfilter(b, rs) ./ sizeOfFilter, size(L), 'bilinear');

q = meanOfA .* L + meanOfB;

end

guided filter的应用

图像去雾应用

Single Image Haze Removal Using Dark Channel Prior

haze_rm 代码实现

clear
clc
close all
kenlRatio = 0.01;
minAtomsLight = 240;
% 图片路径
image_name =  './HFUT.JPG';
img=imread(image_name);
figure,imshow(uint8(img)), title('src');

sz=size(img);

w=sz(2);

h=sz(1);

dc = zeros(h,w);

for y=1:h

    for x=1:w

        dc(y,x) = min(img(y,x,:));

    end

end


figure,imshow(uint8(dc)), title('Min(R,G,B)');

krnlsz = floor(max([3, w*kenlRatio, h*kenlRatio]))

dc2 = minfilt2(dc, [krnlsz,krnlsz]);

dc2(h,w)=0;

figure,imshow(uint8(dc2)), title('After filter ');

t = 255 - dc2;

figure,imshow(uint8(t)),title('t');

t_d=double(t)/255;

sum(sum(t_d))/(h*w)


A = min([minAtomsLight, max(max(dc2))])

J = zeros(h,w,3);

img_d = double(img);

J(:,:,1) = (img_d(:,:,1) - (1-t_d)*A)./t_d;

J(:,:,2) = (img_d(:,:,2) - (1-t_d)*A)./t_d;

J(:,:,3) = (img_d(:,:,3) - (1-t_d)*A)./t_d;

figure,imshow(uint8(J)), title('J');
% figure,imshow(rgb2gray(uint8(abs(J-img_d)))), title('J-img_d');
% a = sum(sum(rgb2gray(uint8(abs(J-img_d))))) / (h*w)
% return;
%----------------------------------
r = krnlsz*4
eps = 10^-6;

% filtered = guidedfilter_color(double(img)/255, t_d, r, eps);
filtered = guidedfilter(double(rgb2gray(img))/255, t_d, r, eps);

t_d = filtered;

figure,imshow(t_d,[]),title('filtered t');

J(:,:,1) = (img_d(:,:,1) - (1-t_d)*A)./t_d;

J(:,:,2) = (img_d(:,:,2) - (1-t_d)*A)./t_d;

J(:,:,3) = (img_d(:,:,3) - (1-t_d)*A)./t_d;
% 

img_d(1,3,1)
imwrite(uint8(J),'./HFUT_haze_rm.jpg');
figure,imshow(uint8(J)), title('J_guild_filter');

%----------------------------------
%imwrite(uint8(J), ['_', image_name])

去雾实验

就地实验

今天恰好是个大雾天, 于是用手机拍了张雾天照片, 想着着试下模型的泛化性如何.
CV toolbox (1) - guided filter_第5张图片CV toolbox (1) - guided filter_第6张图片
如上图, 左图为随手拍的雾天的照片, 右图为去雾后的照片. 发现效果不错, xixi.

于是接下来从原理上开始理解去雾的过程.
1 s t 1st 1st
首先, 将RGB图的每个通道的最小值取出, 并保存到与原图同像素大小的单通道图中.
通过计算得到paper中 A A A 的值为208.
CV toolbox (1) - guided filter_第7张图片
2 n d 2nd 2nd,
将上图通过之前学习的guided filter进行滤波, 得到paper中 t t t , 如下图
CV toolbox (1) - guided filter_第8张图片
3 r d 3rd 3rd, 通过如下公式进行计算
在这里插入图片描述
便得到了去雾后的图片, 如下:
CV toolbox (1) - guided filter_第9张图片

实验结果反思

倘若我们使用原始的minfilter进行滤波处理, 结果又会如何呢.

minfilter 代码实现
function Y = minfilt2(X,varargin)
%  MINFILT2    Two-dimensional min filter
%
%     Y = MINFILT2(X,[M N]) performs two-dimensional minimum
%     filtering on the image X using an M-by-N window. The result
%     Y contains the minimun value in the M-by-N neighborhood around
%     each pixel in the original image. 
%     This function uses the van Herk algorithm for min filters.
%
%     Y = MINFILT2(X,M) is the same as Y = MINFILT2(X,[M M])
%
%     Y = MINFILT2(X) uses a 3-by-3 neighborhood.
%
%     Y = MINFILT2(..., 'shape') returns a subsection of the 2D
%     filtering specified by 'shape' :
%        'full'  - Returns the full filtering result,
%        'same'  - (default) Returns the central filter area that is the
%                   same size as X,
%        'valid' - Returns only the area where no filter elements are outside
%                  the image.
%
%     See also : MAXFILT2, VANHERK
%

% Initialization
[S, shape] = parse_inputs(varargin{:});

% filtering
Y = vanherk(X,S(1),'min',shape);
Y = vanherk(Y,S(2),'min','col',shape);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [S, shape] = parse_inputs(varargin)
shape = 'same';
flag = [0 0]; % size shape

for i = 1 : nargin
   t = varargin{i};
   if strcmp(t,'full') & flag(2) == 0
      shape = 'full';
      flag(2) = 1;
   elseif strcmp(t,'same') & flag(2) == 0
      shape = 'same';
      flag(2) = 1;
   elseif strcmp(t,'valid') & flag(2) == 0
      shape = 'valid';
      flag(2) = 1;
   elseif flag(1) == 0
      S = t;
      flag(1) = 1;
   else
      error(['Too many / Unkown parameter : ' t ])
   end
end

if flag(1) == 0
   S = [3 3];
end
if length(S) == 1;
   S(2) = S(1);
end
if length(S) ~= 2
   error('Wrong window size parameter.')
end
minfilter 滤波对比

在使用minfilter的过程中, 在上面的 2 n d 2nd 2nd步骤, 和用guidedfilter便产生了差别.
CV toolbox (1) - guided filter_第10张图片CV toolbox (1) - guided filter_第11张图片
如图所示, 左边是用guided filter处理得到的 t t t 图像, 右边使用minfilter处理得到的图像.
中间过程的结果如是, 到了最终的输出的结果变因此产生了天翻地覆的差别, 如下所示:
CV toolbox (1) - guided filter_第12张图片CV toolbox (1) - guided filter_第13张图片
在这个实例中, 我们也可以看出guided filter 在边缘处理的时候是发挥了很大的作用的. 就如同上图一样.

你可能感兴趣的:(CV toolbox (1) - guided filter)