本文来自CVPR 2019论文《DVC: An End-to-end Deep Video Compression Framework》
官方开源代码地址:https://github.com/GuoLusjtu/DVC
DVC是一个端到端的视频编码模型,之前也有过一些基于DNN的视频编码方法,但是通常是使用DNN模型替换视频编码的某个模块,整体的训练流程不是端到端的。
DVC将传统的基于块的编码框架的所有模块都使用神经网络替换,图1(a)是传统的视频编码框架,图1(b)是DVC框架。

图1
表示视频序列,
是第t帧,
是对应的预测帧,
是重建/解码帧。
表示残差,
是残差的重建/解码值。
是运动向量,
是对应的重建值。由于编码过程中还会进行变换量化,
变换的结果为
,
变换结果是
。
使用CNN进行光流估计,得到的结果作为运动信息 。其中运动信息还会经过MV编解码网络进行压缩。如图1(b)中Optical Flow Net、MV Encoder Net、MV Decoder Net。
运动补偿网络motion compensation network主要根据前面获得的光流计算预测帧 。
和传统的DCT、DST变换不同,这里使用残差编解码网络进行非线性变换。残差 非线性变换的为
,
量化为
。
通过残差解码网络可以得到重建的残差值
。
量化的运动信息 和残差
要编码为比特流,为了估计比特数,使用Bit rate estimation net获取
和
的分布。
帧重建过程和传统编码框架一样。

图2 MV编解码网络
图2是MV的编解码网络,Conv(3,128,2)表示卷积操作,卷积核为3x3,输出128通道,步长2。GDN/IGDN是非线性变换函数。
如果输入光流 的尺寸是MxNx2,MV编码网络的输出
的尺寸则为M/16 x N/16 x 128,
量化为
。MV解码网络将
解码为
。此外,
还要用于熵编码过程。
给定前一帧的重建帧 和
,运动补偿网络可以生成当前帧的重建帧
,如图3。

图3 运动补偿网络
这里的运动补偿是像素级的,所以可以提供更精准的时域信息,避免了传统的基于块的运动补偿的块效应等,所以不需要环路滤波。网络详细情况请参考论文。
残差信息通过图1中的残差编解码网络进行编码,这个网络是高度非线性的,和传统的DCT等相比可以更充分的挖掘非线性变换的能力。
训练的目标是减小失真的同时降低码率。其他d(.)计算失真的函数,用MSE计算失真,H(.)表示估计码率。如图1所示,重建帧、原始帧和估计的码率都会输入损失函数。
残差和运动向量都需要量化后才能进行熵编码,但是量化本身是不可微的,所以论文在训练阶段通过加一个均匀噪声来代替量化。
其中alpha是均匀噪声。
在推理阶段直接使用取整操作,
为了平衡码率和失真,需要在编码过程中估计残差和运动向量的码率,估计码率需要求得数据的熵,即要获取数据的分布,论文通过一个CNN实现。
由于在运动估计和运动补偿中需要用到参考帧,参考帧是网络输出的前一帧的重建帧,即第t帧需要第t-1帧的重建帧,第t-1帧需要第t-2帧的重建帧,以此类推需要在GPU中保存所有帧,当t非常大时这是不可能的。论文提出在线更新策略,每个迭代更新一帧。
数据集:
论文使用Vimeo-90K数据集进行训练,它包含89800个视频序列。使用UVG数据集和HEVC标准序列进行验证。
评价指标:
使用PSNR和MS-SSIM评价失真,使用bpp衡量码率。
实现细节:
使用4个lambda(256、512、1024、2048)分别训练了4个模型,每个模型使用Adam优化器训练,初始学习率设为0.0001,beta1设为0.9,β2设为0.999。当loss稳定后学习率除以10,mini-batch设为4。训练图像分辨率是256x256。使用tensorflow框架训练,在两张Titan X GPU上耗时7天完成训练。

图4 部分实验结果
图4是部分实验结果,可以看见在大部分数据集上论文方法比H264在PSNR和MS-SSIM上都更优。和H265相比,中MS-SSIM指标上性能相近。论文使用MSE计算失真,如果MS-SSIM则质量会进一步提高。
论文使用DNN模型将传统视频编码框架的每个部分都进行了替换实现了端到端的编码,从而可以整体进行训练。关于各个模型的具体信息可以参考论文和开源实现https://github.com/GuoLusjtu/DVC
感兴趣的请关注微信公众号Video Coding

我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功
查看Ruby代码,它具有以下proc_arity:staticVALUEproc_arity(VALUEself){intarity=rb_proc_arity(self);returnINT2FIX(arity);}更多的是C编码风格问题,但为什么staticVALUE在单独的一行而不是像这样的:staticVALUEproc_arity(VALUEself) 最佳答案 它来自UNIX世界,因为它有助于轻松grep函数的定义:$grep-n'^proc_arity'*.c或使用vim:/^proc_arity
我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。
我在使用Ruby1.9.2p290更改文本文件的编码时遇到问题。我收到错误消息invalidbytesequenceinUTF-8(ArgumentError)。问题(我认为)在于字符集似乎是未知的。如果我执行以下操作,则从命令行:$filetest.txt我得到:Non-ISOextended-ASCIIEnglishtext,withCRLFlineterminators或者,或者,如果我这样做:$file-itest.txt我得到:test.txt:text/plain;charset=unknown但是,如果我这样做,在Ruby中:data=File.open("test.tx