当频域(DCT)遇见CNN

点击上方“CVer”,选择加"星标"置顶

重磅干货,第一时间送达

本文作者:简单控 |  来源:知乎(已授权)

https://zhuanlan.zhihu.com/p/342991714

0.前情回顾

CNN大家在计算机视觉中运用得已经非常多了,一般认为CNN提取特征是循序渐进的,开始提取 low-level的特征,比如边缘、纹理,中间提取 middle-level的特征,最后提取更加抽象的 high-level的特征。从low到high,特征需要的感受野也在不断扩大,high-level的特征需要前两层的特征进行融合,由此诞生了一系列经典的操作,比如特征融合的Densenet,扩大感受野的Non-local、ASPP,各种注意力机制的SENet、CBAM,以及等会儿会提到的FcaNet。

以上很多操作都是让网络去学习具体的卷积核参数,可以说是对频域的隐式建模。很早就有工作考虑结合传统图像处理领域的各类频率分解方法,显式去建模频域上的特征。

最近在看JPEG deartifacts的文章,因为DCT(离散余弦变换)是JPEG压缩技术中天然的一环,所以观察到很早就有工作在DCT域去解释特征,恰好最近Fcanet的工作也用到了DCT,所以自己做了一个简单的整理。

1.DCT与小波分解的简介及实践

比较常见的与CNN结合的技术主要是小波变换和DCT,也有傅里叶变换,但我还没实践过。这两者能用卷积能很容易的去实现,无缝衔接。

转化到频域的好处也很明显,首先RGB域与频域之间的相互转换是没有信息丢失的,不同的是频域的能量排布更加compact,每个channal明确代表了不同频率带的信息,可以用卷积去进一步融合,可解释性更好。

小波变换主要采用的是Haar小波变换,简单来说是把图像用四个卷积核去提取不同频率分量,分表代表直流、横向、纵向、斜向上的能量。

DCT的部分在Fcanet中有了很详细的推导,这里也不再赘述,简单说是频率带划分更加精细,可以自定义设置不同的频率带,KxK的分块DCT能划分出 K^2个从低到高的频率(channal),卷积核的可视化如下

人眼天然对低频分量更加敏感,高频的丢失并不会显著影响观感,这也是JPEG压缩的原理之一,下面有一个简单的实验来证明这一点。

    class dct(nn.Module):
        def __init__(self):
            super(dct, self).__init__()

            self.dct_conv = nn.Conv2d(3, 192, 8, 8, bias=False,
                                      groups=3)  # 3 h w -> 192 h/8 w/8
            self.weight = torch.from_numpy(
                np.load('models/DCTmtx.npy')).float().permute(2, 0,
                                                              1).unsqueeze(
                1)  # 64 1 8 8, order in Z
            self.dct_conv.weight.data = torch.cat([self.weight] * 3,
                                                  dim=0)  # 192 1 8 8
            self.dct_conv.weight.requires_grad = False

            self.Ycbcr = nn.Conv2d(3, 3, 1, 1, bias=False)
            trans_matrix = np.array([[0.299, 0.587, 0.114],
                                     [-0.169, -0.331, 0.5],
                                     [0.5, -0.419, -0.081]])   # a simillar version, maybe be a little wrong
            trans_matrix = torch.from_numpy(trans_matrix).float().unsqueeze(
                2).unsqueeze(3)
            self.Ycbcr.weight.data = trans_matrix
            self.Ycbcr.weight.requires_grad = False

            self.reYcbcr = nn.Conv2d(3, 3, 1, 1, bias=False)
            re_matrix = np.linalg.pinv(np.array([[0.299, 0.587, 0.114],
                                                 [-0.169, -0.331, 0.5],
                                                 [0.5, -0.419, -0.081]]))
            re_matrix = torch.from_numpy(re_matrix).float().unsqueeze(
                2).unsqueeze(3)
            self.reYcbcr.weight.data = re_matrix

        def forward(self, x):
            # jpg = (jpg * self.std) + self.mean # 0-1
            ycbcr = self.Ycbcr(x)  # b 3 h w

            dct = self.dct_conv(ycbcr)
            return ycbcr, dct

        def reverse(self, x):
            ycbcr = F.conv_transpose2d(x, torch.cat([self.weight] * 3, 0),
                                     bias=None, stride=8, groups=3)
            rgb = self.reYcbcr(ycbcr)
            return rgb, ycbcr

主要设计把RGB转换到 YCbCr,再对YCbCr进行DCT变换,这里DCT采用8*8,系数已经经过重新排列,是标准的从低频到高频。

    ycbcr, dct_ = DCT(img_tensor)
    rgb2, ycbcr2  = DCT.reverse(dct_)

    k = 1
    for i in range(3):
        dct_[0,64*i+k:64*i+64,...] = 0   # 截取64个通道的前K个低频信息
    rgb3, ycbcr2  = DCT.reverse(dct_)

K=1,只有直流信息,压缩比1/64。分别代表原图,全频率还原,K频率还原

可以看出大部分信息

K=5

K=25

可以看出已经很好了,几乎不可见差异,这也是频域的作用,更加直观。

具体代码可以见这里

2.CNN与频率相结合的文章

D3: Deep Dual-Domain Based Fast Restoration of JPEG-Compressed Images
https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Wang_D3_Deep_Dual-Domain_CVPR_2016_paper.pdf

  • 这是2016CVPR, 关于JPEG压缩 deartifacts的,解释了稀疏性和DCT

2020 cvpr,邢波老师,关于CNN对于不同频率的感知程度的

https://zhuanlan.zhihu.com/p/315601295

2020 CVPR, 把频率送进去当输入

https://zhuanlan.zhihu.com/p/112751461

2018年,左旺孟老师,把小波运用到多种low-level任务中的

Multi-Level Wavelet Convolutional Neural Networks

https://ieeexplore.ieee.org/document/8732332

ECCV 2020, 可控SR,其中也用了了特征的频率分解,采用Haar小波变换

ECCV 2020 Oral | 可逆图像缩放:完美恢复降采样后的高清图片

2020,FcaNet

从频域角度重新思考注意力机制——FcaNet

3.想法

运用频率的思想之前就了,如何用好还是很值得思考的,这里的可解释性比单纯CNN撘模型要强。

CV资源下载

后台回复:CVPR2020,即可下载代码开源的论文合集

后台回复:ECCV2020,即可下载代码开源的论文合集

后台回复:YOLO,即可下载YOLOv4论文和代码

后台回复:Transformer综述,即可下载两个最新的视觉Transformer综述PDF,肝起来!

重磅!CVer-细分垂直交流群成立

扫码添加CVer助手,可申请加入CVer-细分垂直方向 微信交流群,可申请加入CVer大群,细分方向已涵盖:目标检测、图像分割、目标跟踪、人脸检测&识别、OCR、姿态估计、超分辨率、SLAM、医疗影像、Re-ID、GAN、NAS、深度估计、自动驾驶、强化学习、车道线检测、模型剪枝&压缩、去噪、去雾、去雨、风格迁移、遥感图像、行为识别、视频理解、图像融合、图像检索、论文投稿&交流、Transformer、PyTorch和TensorFlow等群。

一定要备注:研究方向+地点+学校/公司+昵称(如目标检测+上海+上交+卡卡),根据格式备注,才能通过且邀请进群

▲长按加微信群

▲长按关注CVer公众号

整理不易,请给CVer点赞和在看

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值