EDVR: Video Restoration with Enhanced Deformable Convolutional Networks阅读笔记

EDVR: Video Restoration with Enhanced Deformable Convolutional Networks

EDVR:基于增强可变形卷积网络的视频恢复


论文:https://arxiv.org/pdf/1905.02716.pdf

代码:xinntao/EDVR: Winning Solution in NTIRE19 Challenges on Video Restoration and Enhancement (CVPR19 Workshops) - Video Restoration with Enhanced Deformable Convolutional Networks. EDVR has been merged into BasicSR and this repo is a mirror of BasicSR. (github.com)

本篇笔记主要对整篇论文从头到尾进行阅读分析,本文内容有点多,主要是对不同部分的总结以及图例解释,如果只对模型原理部分有兴趣,可直接观看第四部分。

本文为了详细说明各图、公式在各组件中的情况,所以对原文图片、公式做了切割和拼接,保证该内容是在该组件中生效的。

目录

(1)摘要

(2)引言

(3)相关工作

(4)本文方法介绍

(4.1)PCD模块(Alignment with Pyramid, Cascading and Deformable Convolution)

(4.2)TSA模块(Fusion with Temporal and Spatial Attention)

(4.3) 两阶段策略

(5)实验

(5.1)相比较其他模型的实验结果:

 (5.2)消融实验实验结果:

总结 :


(1)摘要

NTURE19挑战赛的REDS任务,两个挑战:(1)对齐大运动的多个帧。(2)有效融合具有不同运动和模糊的不同帧。本文的解决方案:(1)处理大范围运动,本文设计一种金字塔、级联和可变形(PCD)模块(从这就可以看出,本文模型的参数量应该不小),应用于特征级的针对齐。(2)提出时间和空间的注意力机制(TSA)融合模块,用于后续帧的恢复。

(2)引言

目前的VSR的pipelines通常由特征提取、对齐、融合和重建构成(可以看BasicVSR中的对于目前的VSR的归类,实际上可以普遍分为传播、对齐、融合以及上采样四部分),对于遮挡、大运动和严重模糊主要是对对齐和融合产生挑战。

对齐:当前的方法主要是两个分支,(1)显示运动估计,通过明确估计目标帧和参考帧之间的光流场,根据估计的运动长扭曲参考帧来实现对齐。(2)隐式运动估计,目前的研究是通过研究动态滤波器(DUF,可以看我前面的文章)和可变形卷积(DCN)来实现隐式的运动补偿,实现对齐。而对于基于光流的方法,精确的光流估计和扭曲很耗时,并且在大运动情况下,很难执行显示或隐式的运动补偿。

融合:当前的方法分为两种:(1)使用卷积对所有帧进行早期融合。(2)采用递归网络进行逐步融合。但是这两种方式没有考虑对齐帧上潜在的视觉信息量和位置信息都是不同的,受到模糊和不完美对齐的问题,不利于进行重建。

本文的解决方案:

EDVR:两个核心(1)金字塔(Pyramid)、级联(Cascading)和可变形(Deformable),(PCD)对齐模块。(2)时间和空间的注意力机制(TSA)融合模块

PCD模块使用可变形卷积将每个参考帧与目标帧对齐,将特征信息从粗到细进行对齐,但是对于文中的说明我觉得可能存在问题,文中说以金字塔的模式从低尺度的特征获得粗略运动信息,然后再到高尺度获得高精度运动信息。根据文中的内容,在金字塔形的可变形卷积中,作者是将特征图进行下采样获得低尺度的特征图,下采样会丢失某些特征,使可变形卷积获得粗略的运动信息,然后将粗略信息上传,提高大尺度特征图的在卷积中获得运动补偿信息的速率和效果

TSA融合模块,通过计算目标帧和参考帧特征之间的元素相关引入注意力机制,通过相关系数对每个位置的相邻特征进行加权,来表示该特征对于重建特征的影响,最后对所有加权特征进行卷积核融合。

从现在来看,本文对于视频处理的实时性要求不高,但是优于19之前的模型,缺点就是参数太大,相比较DUF可以看出还是比较有优势的。

(3)相关工作

本章节对VSR方法、DCN卷积以及注意力机制进行了简单介绍,文中主要应用这些思想,所以了解的话就没必要看了。

(4)本文方法介绍

本文的EDVR模型应用于视频超分和去模糊方面,下图是EDVR的统一架构,图中架构说明,左边的下半部分和PreDeblur Module模块是用于去模糊的,不是本次blog说明的重点,所以进行简要的说明:(去模糊在于将模糊内容通过其他相邻参考帧的补充,来补充模糊内容,对连续视频帧进行下采样,输入模糊的预处理模块,进行pipline中处理)。左边的上半部分用于视频超分。

本文中的VSR方法,将2N+1帧视频作为输入,t时刻帧作为目标帧,[N-t , N+t]范围帧作为参考帧,经过PCD对齐模块后,得到目标帧的以及2N个对齐后的特征,经过TSA模块,将进行融合,并提取出特征后重建SR视频帧。
 

作者提出PCD模块用于处理帧间对齐和TSA用于进行特征融合。所以我们着重讲一下这两个模块。

(4.1)PCD模块(Alignment with Pyramid, Cascading and Deformable Convolution)

本文使用的PCD模块,使用DCN可变形卷积进行扭曲,如上所说的使用隐式运动补偿来进行扭曲对齐操作。在PCD中采用金字塔模式进行多级对齐,由粗到细的方式,最后进行对齐操作,解决出现复杂运动和大范围运动的问题。

文章中首先对VSR中的DCN使用进行介绍,将输入的目标帧(t 帧)与参考帧(t + i帧)进行简单concat之后,通过卷积学习到offset,将offset用于参考帧,配上权重 以及调制参数,其中K表示的位置的个数,例如k=3,表示3*3的卷积核∈{(−1, −1), (−1, 0), · · · , (1, 1)},经过求和留下p0位置的特征。

而对于输入的连续帧,包含每个参考帧与目标帧的对齐都生成一组偏移矩阵,所有帧的偏移矩阵如下图计算。其中其中[⋅,⋅] 表示concat操作,

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

上述的内容是对DCN在VSR中使用的介绍,而在本文中,作者介绍不考虑 调制参数 ,只关注offset。所以PCD模块的结构如下图所示:

 首先,如上图所示,左边蓝线表示这是一个金字塔层级的模型,每层都是使用DCN进行变形卷积,对上图 t帧 和 t+i 帧的对齐进行说明。首先,将目标帧和参考帧通过卷积各自输出feature map作为金字塔L1层的特征信息

1,黑色虚线部分,对t帧图片和t+i帧图片进行使用跨步卷积stride=2进行下采样,生成L2层的两个特征信息。如法炮制,生成L3层的特征信息

2,到达顶层的L3层之后,根据黄色实线,将的特征做Concat,并进行卷积降低通道数之后,生成L3层的offset。根据蓝色实线方向,获得offset之后,将和offset通过DConv进行对齐,生成对齐特征

具体的计算过程如下图所示,^{\Delta P_{t+i}^{l}}是表示  l 层的 t+i 帧偏移矩阵,f(\cdot )表示学习offset网络,使用双线性插值进行2倍上采样。DCon(\cdot )表示可变形卷积。g(\cdot )h(\cdot)表示一般的卷积过程。例如L2层的偏移矩阵,是L3层的偏移矩阵经过上采样后于L2层特征concat数据计算出这一层的offset,逐层上移,得到最终的对齐结果。

3,左侧紫色虚线是对上一层的offset进行双线性插值的上采样。右侧紫色虚线是对上层对齐的特征进行双线性插值的上采样。

至此就完成了PCD模块的帧对齐工作,该模块不依赖于光流估计的精确度,使用DCN进行隐式运动补偿的对齐操作,并且利用金字塔模型的层级,对不同分辨率的特征进行由粗到细的提取对齐,使其能应对复杂运动和大视差的问题。

(4.2)TSA模块(Fusion with Temporal and Spatial Attention)

本模块的设计主要是针对两个方面:

  1. 不同的相邻帧因为时序、模糊、视差以及遮挡等问题,为目标帧提供的参考特征信息量是不相同的;
  2. 对齐效果不好的帧,会导致融合的时候前后帧的内容不一致,影响重建效果。

本模块的结构流程如下图所示:

时间注意力:

pipeline中到TSA模块,获得2N个对齐特征,对每个对齐特征都使用目标帧F_{t}来计算一个注意力热图,表示帧间的相似距离。这个就是时间注意力。

计算方式如下图:

            (1) 求权值公式

           (2) 得到最终的时间融合特征 

其中F_{a}^{t+i}是相邻帧的对齐特征,F_{a}^{t}是目标帧的特征。\theta\phi分别表示对目标帧的特征和参考帧的特征的卷积,之后按通道进行相乘和累加得到单通道的特征图,最后经过sigmoid得到时间注意力图。

空间注意力

融合之后的结果包含2N个时间维度的特征图,如图中下半部分所示,得到的时间注意力图,首先使用两次下采样,然后在通过上采样的操作获得和尺寸相同的空间注意力,进行element-wise相乘、相加得到最终的融合特征,输入重构模块中。

其中图中下半部分的标志:\bigodot表示element-wise相乘、\bigoplus相加、上采样

(4.3) 两阶段策略

级联类似但较浅的EDVR网络以细化第一级的输出帧。其好处有两个:

1)有效地消除了前一种模型无法处理的严重运动模糊,提高了恢复质量;

2) 它缓解了输出帧之间的不一致性。 

(5)实验

训练数据集:REDS、Vimeo-90K

测试数据集:REDS4(从REDS中抽取的4个视频)、Vid4、Vimeo-90K-T

迭代优化器:Adam optimizer

学习率:4*10^-4

PCD模块:5个RB(残差块)

EVDR2:级联的第二阶段20RB

重建模块:40个RB

batchsize:32

LR的size:64*64

损失函数:Charbonnier loss

(5.1)相比较其他模型的实验结果:

 (5.2)消融实验实验结果:

总结 :

这篇文章也是针对对齐和融合部分,进行了设计改进,提出金字塔级联可变形对齐模块以及时空注意力融合模块,这个片模型的设计可以对提取出的特征进行权重分配,更好的对提取和融合的特征信息进行提取。利用不同层级之间的信息传递以及由粗到细的特征提取,完成大视差和复杂运动的对齐。但是因为本模型为了解决上述的两个问题,所以使用了复杂的结构,金字塔型的信息传递、注意力机制的使用以及两阶段策略,所以本模型在取得良好效果的同时,也附带较大的参数量,对于部分工业需求,可能需要对模型本身进行缩减。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设`Edvr.cfg`文件内容如下: ``` [General] Version=1.0 Name=Edvr [Parameters] InputFile=input.mp4 OutputFile=output.mp4 FrameRate=30 ``` 可以通过以下步骤将`Edvr.cfg`文件解析为一个`Config`结构体: 1. 定义`Config`结构体,包含`General`和`Parameters`两个结构体。`General`结构体包含版本号和名称,`Parameters`结构体包含输入文件名、输出文件名和帧率。 ```c typedef struct { struct { float version; char name[50]; } general; struct { char input_file[100]; char output_file[100]; int frame_rate; } parameters; } Config; ``` 2. 编写解析函数,读取`Edvr.cfg`文件,并将读取的内容存储到`Config`结构体中。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> Config parse_config_file(const char* file_name) { Config config = {0}; char line[100]; char section[20] = ""; FILE* fp; fp = fopen(file_name, "r"); if (fp == NULL) { printf("Failed to open file: %s\n", file_name); return config; } while (fgets(line, sizeof(line), fp) != NULL) { // 去除行末换行符 if (line[strlen(line) - 1] == '\n') { line[strlen(line) - 1] = '\0'; } // 处理段落信息 if (line[0] == '[' && line[strlen(line) - 1] == ']') { strcpy(section, line + 1); section[strlen(section) - 1] = '\0'; } else { // 处理键值对信息 char* key = strtok(line, "="); char* value = strtok(NULL, "="); if (strcmp(section, "General") == 0) { if (strcmp(key, "Version") == 0) { config.general.version = atof(value); } else if (strcmp(key, "Name") == 0) { strncpy(config.general.name, value, sizeof(config.general.name) - 1); config.general.name[sizeof(config.general.name) - 1] = '\0'; } } else if (strcmp(section, "Parameters") == 0) { if (strcmp(key, "InputFile") == 0) { strncpy(config.parameters.input_file, value, sizeof(config.parameters.input_file) - 1); config.parameters.input_file[sizeof(config.parameters.input_file) - 1] = '\0'; } else if (strcmp(key, "OutputFile") == 0) { strncpy(config.parameters.output_file, value, sizeof(config.parameters.output_file) - 1); config.parameters.output_file[sizeof(config.parameters.output_file) - 1] = '\0'; } else if (strcmp(key, "FrameRate") == 0) { config.parameters.frame_rate = atoi(value); } } } } fclose(fp); return config; } ``` 上面的代码中,使用`fgets()`函数逐行读取`Edvr.cfg`文件的内容,然后根据行内容的不同,分别处理段落信息和键值对信息。具体来说: - 如果行内容以方括号开头和结尾,说明这是一个段落信息,需要将方括号中的内容作为当前段落的名称。 - 如果行内容中包含等号,说明这是一个键值对信息,需要将等号左边的字符串作为键,等号右边的字符串作为值。根据当前段落的名称和键的名称,将值存储到`Config`结构体的相应字段中。 3. 调用解析函数,读取`Edvr.cfg`文件并打印配置信息。 ```c int main() { Config config; config = parse_config_file("Edvr.cfg"); printf("General:\n"); printf("Version: %.1f\n", config.general.version); printf("Name: %s\n", config.general.name); printf("Parameters:\n"); printf("InputFile: %s\n", config.parameters.input_file); printf("OutputFile: %s\n", config.parameters.output_file); printf("FrameRate: %d\n", config.parameters.frame_rate); return 0; } ``` 上面的代码中,调用`parse_config_file()`函数解析`Edvr.cfg`文件,并将解析结果存储到`config`结构体中。然后,打印`config`结构体中的各个字段。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值