• guided filter总结


     输入有两张图,引导图I和输入的图p,输出的图为q。

    在我们的matting的例子里面,引导图是原图或者是原图的灰度图,输入p为粗粗的分割后的结果, 输出q是具有精细边缘的matting图。

     

    I和输出q之间需要满足一个关系,在任意一个半径为r的窗口内,满足q和I之间是线性的,ak和bk在窗口wk内是常数。

     

    这个设想是合理的,在边界的地方,是想要服从这个的。但是在背景和前景区域,实际上并不想要符合这个,可以看鸭子的脖子和身体之间蓝黄色的交界处,实际上并不想要这个梯度的,所以需要引入下一个约束

     

    要让q和p之间的对应像素间差值尽可能的小,这样在大块的前景和背景区域,就都还是原来的值了。在这种窗口wk内如果输入p都是背景(p=0)的话,那么直接ak=0,bk=0,就可以得到q=0,整个窗口q还是背景。如果p=255,那么ak=0,bk = 255,整个窗口q是前景255。

    这都比较好理解,那么在窗口既有背景又有前景的时候(就是边界),就需要保留I中的像素梯度关系了,这样就需要去求这个窗口wk中的ak和bk,求解也比较简单,就是在这个半径为r的窗口寻找一个ak和一个bk满足以下方程最小,ƹ是正则项。

     

    线性回归,得到

     

    这样就可以求到ak,然后每一个点在实际算的时候,被很多个窗口包围,每个窗口都可以算出一个a和b来,如下图qi这个点被3个窗口包含,实际上比这个还要多。

     

    所以在算的时候会把所有点在这里的a和b去求一个平均,求了平均值后语义就跟之前有一些不一样了,q和I就不是成线性的关系了,但是因为a和b都是平均后的值,梯度非常小,所以在I上有大梯度的时候,仍然可以看做I的梯度和q的梯度是线性的,如下图,后面两项可以忽略不计。

     

    整个算法的流程如下

     

    可以看到,主要是一个boxfilter,即半径为r的窗口内求所有像素的平均

    采用积分图,让这个运算的复杂度和r的大小无关,那么这个是算法就是O(N)的,N是图像的像素数,只与分辨率有关。

    为了加速这个引导滤波,作者提出来可以在小分辨率上计算a和b然后upscale到大分辨率再和I取计算q。这种方法可能会损失一部分非常小的细节,大部分的是可以保留的。

     ------------------------------------------------------------------------------------------------------------------

    Guided filter现在有一个trainable的版本,意思是可以和前面的cnn网络一起训练,不仅仅是一个后处理的模块,这样end-to-end的训练会让结果更好。论文主要是论证了guided Filter的反向传播是可微的。

    论文在这里 https://arxiv.org/pdf/1803.05619v1.pdf

    具体推导是这样的

    这个是guided filter的流程图

     

    有三个输入,Il是小分辨率的RGB图像,Ol是经过网络后初步的mask,也是小分辨率的。根据Il和Ol去计算出小分辨率上面的ak和bk然后upscale,再对输入的大分辨率的Ih去做计算,得到大分辨率的Oh,这里需要注意的是,Il对应的是I,Ol对应的是p,Ih对应的是I,Oh对应的是q。所以Ol和Oh长的像但是不是一个意思。

    仿照guided filter的求解过程,计算Al和Bl。这里先暂时忽略F(I), 这个是作者自己提出来的做guided map的几层卷积,可忽略。那么有以下的推导过程

     

    简单的,如果去计算

    反向传播的时候,需要计算

    然后就可以一步一步推导下去,直到推导出

    具体过程如下图所示,其中的

     

    可以看到确实是可反向求导的。

    这篇文章有source code可以看看具体是怎么用pytorch code实现guided fitler的

     def forward(self, lr_x, lr_y, hr_x):
            n_lrx, c_lrx, h_lrx, w_lrx = lr_x.size()
            n_lry, c_lry, h_lry, w_lry = lr_y.size()
            n_hrx, c_hrx, h_hrx, w_hrx = hr_x.size()
    
            assert n_lrx == n_lry and n_lry == n_hrx
            assert c_lrx == c_hrx and (c_lrx == 1 or c_lrx == c_lry)
            assert h_lrx == h_lry and w_lrx == w_lry
            assert h_lrx > 2*self.r+1 and w_lrx > 2*self.r+1
    
            ## N
            N = self.boxfilter(Variable(lr_x.data.new().resize_((1, 1, h_lrx, w_lrx)).fill_(1.0)))
    
            ## mean_x
            mean_x = self.boxfilter(lr_x) / N
            ## mean_y
            mean_y = self.boxfilter(lr_y) / N
            ## cov_xy
            cov_xy = self.boxfilter(lr_x * lr_y) / N - mean_x * mean_y
            ## var_x
            var_x = self.boxfilter(lr_x * lr_x) / N - mean_x * mean_x
    
            ## A
            A = cov_xy / (var_x + self.eps)
            ## b
            b = mean_y - A * mean_x
    
            ## mean_A; mean_b
            mean_A = F.interpolate(A, (h_hrx, w_hrx), mode='bilinear', align_corners=True)
            mean_b = F.interpolate(b, (h_hrx, w_hrx), mode='bilinear', align_corners=True)
    
            return mean_A*hr_x+mean_b

     看起来也还是可以的。

    文章后面又提出了conv guided filter,用卷积去做的几层, 其中dilated conv的rate就是radius,感觉可解释性下降了。下面是conv guided filter的具体思想。

     

  • 相关阅读:
    201403-1
    201312-5 I’m stuck!
    201312-4
    201312-3
    201312-2 ISBN号码
    深度学习-李宏毅PPT总结
    梯度下降
    离散时间信号与系统-频域:5
    离散时间信号与系统-时域:4
    离散时间信号与系统-时域:3
  • 原文地址:https://www.cnblogs.com/sunny-li/p/14327611.html
Copyright © 2020-2023  润新知