分享

HEVC编码 | Embracing Dreams

 gljin_cn 2016-10-10

个人博客,如需转载,请注明来自DDingDreams的个人博客:http://www./wordpress/
HEVC中帧间预测算法是从前后的参考帧中选取近似块,编码运动矢量,同时会搜索出多个运动矢量再经过率失真代价计算选出最优的Motion Vector进行编码。而3D-HEVC不仅用到了MCP(Motion-compensated Prediction),还用到了DCP(Disparity-compensated Prediction),这是视点间的预测,将找到的Disparity Vector加入到原来Motion Vector候选列表中,一起进行率失真代价计算。
视点间运动预测算法
随机接入单元中,独立视点的第一帧的块编码都采用帧内编码,其它视点的块可采用帧间和视点间编码,当前也可以用帧内编码。所以此视点间运动预测算法适用于依赖视点和非随机接入单元的独立视点。下面是其具体算法,如图Figure8:
块运动参数生成基本算法
Figure8:基于已编码视点中对应块的运动参数生成当前块的运动参数
1.假设当前帧的深度图已知(下文的四种方法会介绍如何生成当前帧图像的深度图);
2.假设当前是为依赖视点某一帧的块(如图的位置为x)生成候选运动参数;
3.这个块对应的深度块中最大深度值d转成视差矢量,通过当前视点x位置对应到参考视点中的x位置,并且进行偏移,偏移大小为得到的视差矢量,得到xR位置为当前视点x位置对应的实际位置,若是xR对应的块为MCP编码方式,则x位置块继承其Motion Vector,同时得到的视差矢量即为Disparity Vector;
4.得到的MV和DV都可加入候选列表待选。
p.s.其实在编码当前帧的时候是可以没有深度图的,没有深度图参与编码则可以独立解码。后面将会介绍当前帧编码前如何生成当前帧的深度图。
1.生成视差矢量
从上述的视点间运动预测算法可知,视差矢量存在两大作用,首先,用于定位当前块在不同视点图像中相应的位置,可较为精确的继承运动矢量(MCP,前后帧间),其次的作用是确定了视差矢量对应的DCP(视点帧间)。视差矢量是通过深度图的深度值来确定的,那么深度图的生成至关重要。
此处介绍草案中给出的4种生成方式,方案1的方法是根据当前视点之前已经编码视点的深度图映射到当前视点;方案2生成低分辨率的深度图,但是不利用任何已经编码的深度图;方案3;方案4;
1.1深度估计方案1
由于当前视点的参考视点的深度图先编码,那么可以通过将参考视点的深度图重建图像进行映射到当前帧,生成当前帧的深度图。下图Figure9图中,用方形前景和背景构成的图,对于这样一张深度图,将每一个深度值都转成全像素精度的视差矢量,相应的每一个像素都偏移相应的视差矢量,生成图中的中间图,若是两个或者更多像素偏移到同一个位置,那么选择depth value最大的(即选择距离摄像机位置最近的),而呈现的黑色区域为空洞,由于摄像机位置变动这部分的背景区域暴露出来,采用空洞填补算法进行修复:对映射后的深度图逐行处理,然后用该行的左右两边临近像素中较小深度值给空洞的像素值(其实是用相对距离摄像机远的背景像素填补空洞)。
p.s.此处用于计算当前块的视点间运动预测和残差预测的视差矢量是利用相应深度块中的最大深度值计算得来的。
深度图映射到其他视点
Figure9:深度图映射到其他视点
1.2深度估计方案2
方案1的算法只适用于多视点+深度图的数据,而对于多视点无深度图的数据则不适用了,而且其视频解码器还要依赖深度图的解码,不能独立进行解码。此处介绍的方案2则不需要数据源有深度图存在,利用已编码视频的重建帧则可以进行深度图估计。这种方法,一个深度像素代表一个4*4块亮度像素,所以估计的深度图在水平和垂直方向的分辨率都为对应视频帧的1/4。
p.s.此处用于计算当前块的视点间运动预测和残差预测的视差矢量是利用相应深度块中的最大深度值计算得来的。
1.在一个随机接入单元中,独立视点帧的所有编码块都采用帧内编码,而所有的依赖视点的PU基本上采用DCP,剩下的块采用帧内编码,所以在没有深度图的情况下,编码第一个依赖视点帧是没有深度信息或者视差矢量信息的,所以第一个依赖视点帧的视差矢量是通过传统的Motion Vector预测得来的,即通过在参考帧对应位置的临近的局部区域寻找Motion Vector来得到视差矢量。
2.在编码第一个依赖视点的第一帧之后,其编码的Disparity Vector可以用来估计深度图,如Figure10中所示。所以DCP方式对应的Disparity Vector转成对应的深度值,且该Disparity Vector对应的整个块的深度值都为相同的深度值。
3.而视频帧采用帧内编码的块对应的深度像素采用周围相邻像素确定,算法即空间帧内预测算法(Spatial Intra Prediction)。
4.若是编码视点数>2,则利用上面介绍的方案1的映射方法得到其他视点的深度图。
p.s.在映射过程中,视差矢量的计算要考虑到深度图的水平和垂直分辨率为视频帧亮度信号的1/4。
随机接入单元中第一个依赖视点深度图生成算法
Figure10:随机接入单元中第一个依赖视点深度图生成算法
随机接入单元的第一个依赖视点的深度图估计可以用来生成第一个依赖视点的下一帧图像的深度图,基本算法如下图Figure11所示。
利用同一个接入单元已编码视点的运动参数估计当前帧的深度图
Figure11:利用同一个接入单元已编码视点的运动参数估计当前帧的深度图
1.编码随机接入单元的第一个依赖视点之后,生成的深度图映射到独立视点生成基视点第一帧的深度图,且深度图和重建视频帧一起存储。
2.独立视点的下一帧编码基本采用帧间编码MCP,其对应的Motion Vector用来估计深度图,也就是第二帧以第一帧为参考帧,那么第二帧深度图可以继承视频帧的Motion Vector,以第一帧深度图为参考帧得到当前第二帧深度图。
p.s.记住,计算要考虑到深度图的水平和垂直分辨率为视频帧亮度信号的1/4。为了简化运动补偿以及避免引入新的深度值,深度块的MCP不采用插值方式。运动矢量的像素精度为深度像素精度depth-sample-precision(1/4亮度像素精度)。
3.视频帧帧内编码块对应的深度块的像素值同样采用周围深度像素确定。
4.将独立视点的第二帧深度图采用方案1映射到第一个依赖视点。
此时,第一个依赖视点的第二帧图像还没有编码,但已经得到了它的深度图,深度图估计不是最终目的,只是用来在视频帧编码时利用视差矢量获得运动参数。

到此,其实第一个依赖视点的第二帧深度图其实并不准确,而它还要用来生成其它视点的或者同视点其它帧的深度图,若不进行像素更新会有错误传递。而在第二帧编码之后利用视频帧编码采用的Motion Vector和Disparity Vector对其深度图更新,正如Figure12所示。对于第二帧采用DCP编码方式的,可以用Disparity Vector转换成深度值,而利用MCP编码方式的块,深度图可以继承该Motion Vector,以第一帧深度图为参考获得相应深度值。更新后的深度图映射回独立视点更新独立视点第二帧深度图。
基于运动矢量和视差矢量更新当前依赖视点的深度图
Figure12:基于运动矢量和视差矢量更新当前依赖视点的深度图
可选配置:通过增加一种深度更正来确定新的深度值。这种深度更正是把当前块运动矢量和其对应参考块的运动矢量的差转换成深度的差,以此校正深度值。此外帧内编码块对应的深度块仍是采用(Spatial Prediction)得到。其他如上,将更新后的深度图映射回独立视点,得到独立视点第二帧深度图,重建的视频帧和相应的深度图一起存储。同一个接入单元的其他视点的深度图同样采用这种方式得到。

对于剩下的图像,上面描述的过程会不断重复。独立视点视频帧编码后,通过MCP的Motion Parameters得到估计的深度图,将深度图映射到第一个依赖视点,得到依赖视点当前帧的深度图,此帧编码时会利用得到的深度图进行视点间预测。第一个依赖视点的视频帧编码完毕后,根据视频帧的MV和DV对深度图进行更新。下一个随机接入单元到来时,视点间的运动参数预测又不能使用了,直到第一个依赖视点视频帧重建后,深度图再度开始上述操作。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多