运动估计与运动补偿

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

运动估计与运动补偿
运动补偿是通过先前的局部图像来预测、补偿当前的局部图像,它是减少
帧序列冗余信息的有效方法。

运动估计是从视频序列中抽取运动信息的一整套
技术。

运动估计与运动补偿技术
MPEG-4采用I-VOP、P-VOP、B-VOP三种帧格式来表征不同的运动补偿类型。

它采用了H.263中的半像素搜索(half pixel searching)技术和重叠运动补偿(overlapped motion compensation)技术,同时又引入重复填充(repetitive padding)技术和修改的块(多边形)匹配(modified block(polygon)matching)技术以支持任意形状的VOP区域。

此外,为提高运动估计算法精度,MPEG-4采用了MVFAST(Motion Vector Field Adaptive Search Technique)和改进的PMVFAST(Predictive MVFAST)方
法用于运动估计。

对于全局运动估计,则采用了基于特征的快速顽健的FFRGMET(Feature-based Fast and Robust Global Motion Estimation Technique)方法。

编解码器用来减少视频序列中的空域冗余。

它也可以用来进行去交织(deinterlacing)的操作。

定义
运动补偿是通过先前的局部图像来预测、补偿当前的局部图像,它是减少
帧序列冗余信息的有效方法。

分类
包括全局运动补偿和分块运动补偿两类。

运动补偿是一种描述相邻帧(相邻在这里表示在编码关系上相邻,在播放顺序上两帧未必相邻)差别的方法,具体来说是描述前面一帧(相邻在这里表示在编码关系上的前面,在播放顺序上未必在当前帧前面)的每个小块怎样移动到当前帧中的某个位置去。

这种方法经常被
视频压缩/视频编解码器用来减少视频序列中的空域冗余。

它也可以用来进行去交织(deinterlacing)的操作。

一个视频序列包含一定数量的图片--通常称为帧。

相邻的图片通常很相似,也就是说,包含了很多冗余。

使用运动补偿的目的是
通过消除这种冗余,来提高压缩比。

最早的运动补偿
早期解析
最早的运动补偿的设计只是简单的从当前帧中减去参考帧,从而得到通常
含有较少能量(或者成为信息)的"残差",从而可以用较低的码率进行编码。


码器可以通过简单的加法完全恢复编码帧。

一个稍微复杂一点的设计是估计一
下整帧场景的移动和场景中物体的移动,并将这些运动通过一定的参数编码到
码流中去。

这样预测帧上的像素值就是由参考帧上具有一定位移的相应像素值
而生成的。

这样的方法比简单的相减可以获得能量更小的残差,从而获得更好
的压缩比--当然,用来描述运动的参数不能在码流中占据太大的部分,否则就
会抵消复杂的运动估计带来的好处。

通常,图像帧是一组一组进行处理的。


组的第一帧(通常是第一帧)在编码的时候不使用运动估计的办法,这种帧称为
帧内编码帧(Intra frame)或者I帧。

该组中的其它帧使用帧间编码帧(Inter frame),通常是P帧。

这种编码方式通常被称为IPPPP,表示编码的时候第一
帧是I帧,其它帧是P帧。

在进行预测的时候,不仅仅可以从过去的帧来预测
当前帧,还可以使用未来的帧来预测当前帧。

当然在编码的时候,未来的帧必
须比当前帧更早的编码,也就是说,编码的顺序和播放的顺序是不同的。

通常
这样的当前帧是使用过去和未来的I帧或者P帧同时进行预测,被称为双向预
测帧,即B帧。

这种编码方式的编码顺序的一个例子为IBBPBBPBBPBB。

全局运动补偿
运动模型基本上就是反映摄像机的各种运动,包括平移,旋转,变焦等等。

这种模型特别适合对没有运动物体的静止场景的编码。

全局运动补偿有下面的
一些优点:该模型仅仅使用少数的参数对全局的运行进行描述,参数所占用的
码率基本上可以忽略不计。

该方法不对帧进行分区编码,这避免了分区造成的
块效应。

在时间方向的一条直线的点如果在空间方向具有相等的间隔,就对应
了在实际空间中连续移动的点。

其它的运动估计算法通常会在时间方向引入非
连续性。

但是,缺点是,如果场景中有运动物体的话,全局运动补偿就不足以
表示了。

这时候应该选用其它的方法。

分块运动补偿
每帧被分为若干像素块(在大多数视频编码标准,如MPEG中,是分为
16x16的像素块)。

从参考帧的某个位置的等大小的块对当前块进行预测,预测
的过程中只有平移,平移的大小被称为运动矢量。

对分块运动补偿来说,运动
矢量是模型的必要参数,必须一起编码加入码流中。

由于运动矢量之间并不是
独立的(例如属于同一个运动物体的相邻两块通常运动的相关性很大),通常使
用差分编码来降低码率。

这意味着在相邻的运动矢量编码之前对它们作差,只
对差分的部分进行编码。

使用熵编码对运动矢量的成分进行编码可以进一步消
除运动矢量的统计冗余(通常运动矢量的差分集中于0矢量附近)。

运动矢量的
值可以是非整数的,此时的运动补偿被称为亚像素精度的运动补偿。

这是通过
对参考帧像素值进行亚像素级插值,而后进行运动补偿做到的。

最简单的亚像
素精度运动补偿使用半像素精度,也有使用1/4像素和1/8像素精度的运动补
偿算法。

更高的亚像素精度可以提高运动补偿的精确度,但是大量的插值操作
大大增加了计算复杂度。

缺点
分块运动补偿的一个大缺点在于在块之间引入的非连续性,通常称为块效应。

当块效应严重时,解码图像看起来会有像马赛克一样的效果,严重影响视
觉质量。

另外一个缺点是,当高频分量较大时,会引起振铃效应。

关于高频分量,请参见对运动补偿后的残差进行变换的方法:变换编码。

在MPEG-4视频编码中,运动估计相当耗时,对编码的实时性影响很大。

因此这里特别强调快速算法。

运动估计方法主要有像素递归法和块匹配法两大类,前者复杂度很高,实际中应用较少,后者则在H.263和MPEG中广泛采用。

在块匹配法中,重点研究块匹配准则及搜索方法。

目前有三种常用的匹配准则:
(1)绝对误差和(SAD,Sum of Absolute Difference)准则;
(2)均方误差(MSE,Mean Square Error)准则;
(3)归一化互相关函数(NCCF,Normalized Cross Correlation Function)准则。

在上述三种准则中,SAD准则具有不需乘法运算、实现简单方便的优点而
使用最多,但应清楚匹配准则的选用对匹配结果影响不大。

在选取匹配准则后就应进行寻找最优匹配点的搜索工作。

最简单、最可靠
的方法是全搜索法(FS,Full Search),但计算量太大,不便于实时实现。

因此
快速搜索法应运而生,主要有交叉搜索法、二维对数法和钻石搜索法,其中钻
石搜索法被MPEG-4校验模型(VM,Verification Model)所采纳,下面详细介绍。

钻石搜索(DS,Diamond Search)法以搜索模板形状而得名,具有简单、鲁棒、高效的特点,是现有性能最优的快速搜索算法之一。

其基本思想是利用搜索模
板的形状和大小对运动估计算法速度及精度产生重要影响的特性。

在搜索最优
匹配点时,选择小的搜索模板可能会陷入局部最优,选择大的搜索模板则可能
无法找到最优点。

因此DS算法针对视频图像中运动矢量的基本规律,选用了两种形状大小的搜索模板。

·大钻石搜索模板(LDSP,Large Diamond Search Pattern),包含9个候选位置;
·小钻石搜索模板(SDSP,Small Diamond Search Pattern),包含5个候选位置。

DS算法搜索过程如下:开始阶段先重复使用大钻石搜索模板,直到最佳匹
配块落在大钻石中心。

由于LDSP步长大,因而搜索范围广,可实现粗定位,使搜索不会陷于局部最小,当粗定位结束后,可认为最优点就在LDSP周围8个点所围菱形区域中。

然后再使用小钻石搜索模板来实现最佳匹配块的准确定位,
以不产生较大起伏,从而提高运动估计精度。

此外Sprite视频编码技术也在MPEG-4中应用广泛,作为其核心技术之一。

Sprite又称镶嵌图或背景全景图,是指一个视频对象在视频序列中所有出现部
分经拼接而成的一幅图像。

利用Sprite可以直接重构该视频对象或对其进行预测补偿编码。

Sprite视频编码可视为一种更为先进的运动估计和补偿技术,它能够克服基于固定分块的传统运动估计和补偿技术的不足,MPEG-4正是采用了将传统分块编码技术与Sprite编码技术相结合的策略。

运动估计
两帧之间的物体运动是平移运动,位移量不是很很大,所以会以块作为单位分配运动矢量,在运动估计中采用了大量的参考帧预测来提高精度,当前的待编码块可以在缓存内的所有重建帧中寻找最优的匹配块进行运动补偿,以便很好的去除时间域的冗余度。

为每一个块寻求一个运动矢量MV,并进行运动补偿预测编码。

在每个分割区域中都有其对应的运动矢量,并对运动矢量以及块的选择方式进行编码和传输。

运动估计ME所表达的运动矢量MV,其研究的内容就是如何加速,有效的获得足够精确的mv,并且把前一帧所得的运动信息通过运动补偿MC来进行变换,量化编码,最后输出。

缩写含义:me得到的是mV
预测得到的是mvp
差值是mvd MV:运动向量,参考帧中相对于当前帧的偏移
MVp:参考运动向量
MVD:两个向量间的差别
提高运动估计算法的效率的主要技术有:初始搜索点的选择,匹配准则,和运动搜索策略。

1.运动估计初始点的搜索:
1)直接选择参考帧对应块的中心位置,这种方法简单,但容易陷入局部最优点,如果初始的步长太大,而原点(指待搜索块的中心点在参考帧中的相同位置的对应点)不是最优点时候,可能使快速搜索跳出原点周围的区域,而去搜索较远的点,导致搜索方向的不确定性,陷入局部最优。

2)选择预测的起点,以预测点作为搜索的起点,
x264采用的将运动估计矢量和参考帧的左边,上边和右上边的MB的中值
MV作为起点进行ME。

2.匹配准则,
x264中所采用的匹配准则是SAD,SATD.SAD即绝对误差和,仅反映残差时
域差异,影响PSNR值,不能有效反映码流的大小。

SATD即将残差经哈德曼变
换的4×4块的预测残差绝对值总和,可以将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。

因此,不用率失真最优化时,可将其作为
模式选择的依据。

一般帧内要对所有的模式进行检测,帧内预测选用SATD.在做运动估计时,一般而言,离最优匹配点越远,匹配误差值SAD越大,这就是有名的单一平面
假设,现有的运动估计快速算法大都利用该特性。

但是,转换后SATD值并不满足该条件,如果在整象素中运用SATD搜索,容易陷入局部最优点。

而在亚象素中,待搜索点不多,各点处的SAD差异相对不大,可以用SATD选择码流较少的匹配位置。

3.运动搜索策略
x264所采用的运动搜索策略(对应的最后面的程序中有描述):
#define X264_ME_DIA 0//钻石搜索
#define X264_ME_HEX 1//六边形所搜
#define X264_ME_UMH 2//非对称十字六边形网络搜索
#define X264_ME_ESA 3//全搜索
#define X264_ME_TESA 4//hadamard全搜索法,这个算法和ESA相比主要
是在搜索范围上的变化
下面就在x264中的运动估计所涉及的函数进行跟踪:
ME的分析在函数x264_slice_write(x264_t*h)中的
x264_macroblock_analyse(h);中:进入这个函数:由于对于I帧类型采用的
帧内编码,这部分没有采用ME,所以对于I帧的分析略。

进入帧间类型(P/B)的分析中:以P帧的16*16MB为例进行跟踪:进入函数:x264_mb_analyse_inter_p16x16(x264_t*h,x264_mb_analysis_t*a)
{//对参考帧中的所有16*16块进行分析
for(i_ref=0;i_ref h-mb.pic.i_fref[0];i_ref++)
{
.
LOAD_HPELS(&m,h-mb.pic.p_fref[0][i_ref],0,i_ref,0,0);
x264_mb_predict_mv_16x16(h,0,i_ref,m.mvp);//下面的有详细的注释1 x264_mb_predict_mv_ref16x16(h,0,i_ref,mvc,&i_mvc);//注释2
x264_me_search_ref(h,&m,mvc,i_mvc,p_halfpel_thresh);//注释3 .
}
}
//注释1:进行16*16的块的mv预测,得到运动估计的起始方向,并将获
得的MV赋值给MVP,在下一步中使用
x264_mb_predict_mv_16x16(h,0,i_ref,m.mvp);
void x264_mb_predict_mv_16x16(x264_t*h,int i_list,int
i_ref,int16_t mvp[2])
{
int i_refa=h-mb.cache.ref[i_list][X264_SCAN8_0-1];//亮度左边块
int16_t*mv_a=h-mb.cache.mv[i_list][X264_SCAN8_0-1];
int i_refb=h-mb.cache.ref[i_list][X264_SCAN8_0-8];//亮度上边块
int16_t*mv_b=h-mb.cache.mv[i_list][X264_SCAN8_0-8];
int i_refc=h-mb.cache.ref[i_list][X264_SCAN8_0-8+4];//亮度的右上边块
int16_t*mv_c=h-mb.cache.mv[i_list][X264_SCAN8_0-8+4];
//当i_refc不存在时,就将i_refc赋值为左上边的块
if(i_refc==-2)
{
i_refc=h-mb.cache.ref[i_list][X264_SCAN8_0-8-1];
mv_c=h-mb.cache.mv[i_list][X264_SCAN8_0-8-1];
}
//看i_refa/b/c是否是在参考帧所对应中的那一块,若是i_count++,
i_count是用来进行Mvp预测选择何种方式的一种标志
if(i_refa==i_ref)i_count++;
if(i_refb==i_ref)i_count++;
if(i_refc==i_ref)i_count++;
if(i_count 1)
{
median:
x264_median_mv(mvp,mv_a,mv_b,mv_c);
}
else if(i_count==1)
{
if(i_refa==i_ref)
*(uint32_t*)mvp=*(uint32_t*)mv_a;
else if(i_refb==i_ref)
*(uint32_t*)mvp=*(uint32_t*)mv_b;
else
*(uint32_t*)mvp=*(uint32_t*)mv_c;
}
else if(i_refb==-2&&i_refc==-2&&i_refa!=-2)
*(uint32_t*)mvp=*(uint32_t*)mv_a;
else goto median;
}
}
//注释2:细化16*16块mv预测
x264_mb_predict_mv_ref16x16(h,0,i_ref,mvc,&i_mvc);
void x264_mb_predict_mv_ref16x16(x264_t*h,int i_list,int
i_ref,int16_t mvc[9][2],int*i_mvc)
{
//设运动补偿
#define SET_MVP(mvp){\
*(uint32_t*)mvc[i]=*(uint32_t*)mvp;\
i++;\
}
.
//空间预测:获取左边,上边和左上的mb的mvc[i],得到不同的类型的MVC,获得i个mvc if(h-mb.i_neighbour&MB_LEFT)
{
int i_mb_l=h-mb.i_mb_xy-1;
if(!IS_SKIP(h-mb.type[i_mb_l]))
SET_MVP(mvr[i_mb_l]);
}
if(h-mb.i_neighbour&MB_TOP)
{
int i_mb_t=h-mb.i_mb_top_xy;
if(!IS_SKIP(h-mb.type[i_mb_t]))
SET_MVP(mvr[i_mb_t]);
if(h-mb.i_neighbour&MB_TOPLEFT&&!IS_SKIP(h-mb.type[i_mb_t-1]))
SET_MVP(mvr[i_mb_t-1]);
if(h-mb.i_mb_x h-mb.i_mb_stride-1&&!IS_SKIP(h-mb.type[i_mb_t+1])) SET_MVP(mvr[i_mb_t+1]);
}
//时间预测
//dx,dy表示在时间差上的参考帧上对应点的坐标差
#define SET_TMVP(dx,dy){\
int i_b4=h-mb.i_b4_xy+dx*4+dy*4*h-mb.i_b4_stride;\
int i_b8=h-mb.i_b8_xy+dx*2+dy*2*h-mb.i_b8_stride;\
int ref_col=l0-ref[0][i_b8];\
if(ref_col=0)\
{\
int scale=(h-fdec-i_poc-h-fdec-ref_poc[0][i_ref])*l0-
inv_ref_poc[ref_col];\
mvc[i][0]=(l0-mv[0][i_b4][0]*scale+128)8;\
mvc[i][1]=(l0-mv[0][i_b4][1]*scale+128)8;\
i++;\
}\
}
}
//注释3 x264_me_search_ref(h,&m,mvc,i_mvc,p_halfpel_thresh);
void x264_me_search_ref(x264_t*h,x264_me_t*m,int16_t(*mvc)[2],int i_mvc,int*p_halfpel_thresh)
{
//初始化
.
bmx=x264_clip3(m-mvp[0],mv_x_min*4,mv_x_max*4);
bmy=x264_clip3(m-mvp[1],mv_y_min*4,mv_y_max*4);
//这些变量*4,或者左移2位,是因为要得到分数像素(1/4像素)
pmx=(bmx+2)2;
pmy=(bmy+2)2;
bcost=COST_MAX;
if(h-mb.i_subpel_refine=3)
{
uint32_t bmv=pack16to32_mask(bmx,bmy);
COST_MV_HPEL(bmx,bmy);//对COST_MV_HPEL目的:获得最佳cost的坐标
for(i=0;i i_mvc;i++)
{
if(*(uint32_t*)mvc[i]&&(bmv-*(uint32_t*)mvc[i])) {
int mx=x264_clip3(mvc[i][0],mv_x_min*4,mv_x_max*4);int my=x264_clip3(mvc[i][1],mv_y_min*4,mv_y_max*4);COST_MV_HPEL(mx,my);
}
}
bmx=(bpred_mx+2)2;
bmy=(bpred_my+2)2;
COST_MV(bmx,bmy);
}
else
{
COST_MV(pmx,pmy);
bcost-=BITS_MVD(pmx,pmy);
for(i=0;i i_mvc;i++)
{
int mx=(mvc[i][0]+2)2;
int my=(mvc[i][1]+2)2;
if((mx|my)&&((mx-bmx)|(my-bmy)))
{
mx=x264_clip3(mx,mv_x_min,mv_x_max);
my=x264_clip3(my,mv_y_min,mv_y_max);
COST_MV(mx,my);
}
}
}
COST_MV(0,0);
//下面是对me方式的选择switch语句:#define X264_ME_DIA 0
#define X264_ME_HEX 1
#define X264_ME_UMH 2
#define X264_ME_ESA 3
#define X264_ME_TESA 4
//switch(h-mb.i_me_method)中的参数h-mb.i_me_method=h-
param.analyse.i_me_method;
//根据用户的命令输入决定运动矢量的精度程度,根据空间相关性,用求出的左,上,左上的编码的宏块的//MV得到当前mb的mv的预测值mvp,以预测向量mvp的为初始原点,进行整数像素的搜索
case X264_ME_DIA:
//钻石形搜索:在do_while循环中,总是以一个菱形的形式进行搜索,只是原点发生变化,这个变化时有//bcost带来的,而坐标
//原点是有bmx,bmy的变化来获得:
//bmx,bmy的定义:bmx=x264_clip3(m-mvp[0],mv_x_min*4,mv_x_max*4);
bmy=x264_clip3(m-mvp[1],mv_y_min*4,mv_y_max*4);
bcost=4;//这里的左移是为了和(costs[0]4)+N对应
do
{
//以bmx,bmy为基点在周围进行其四点的mv cost计算
COST_MV_X4_DIR(0,-1,0,1,-1,0,1,0,costs);
COPY1_IF_LT(bcost,(costs[0]4)+1);//cost左移了,还要再加N了,加N 时为了区别是哪个点
COPY1_IF_LT(bcost,(costs[1]4)+3);
COPY1_IF_LT(bcost,(costs[2]4)+4);
COPY1_IF_LT(bcost,(costs[3]4)+12);
if(!(bcost&15))//后4位进行检测,如果后4位是0,就是证明所进行
比较的4点都是比原点要大,所以不需要继续搜索了
break;
bmx-=(bcost 28)30;//为什么要这么麻烦的同时左移和右移了,何不直接除以4 bmy-=(bcost 30)30;
bcost&=~15;
if(!CHECK_MVRANGE(bmx,bmy))
break;
}while(++i i_me_range);
.
case X264_ME_HEX:六边形搜索+正方形细化,先进行六边形搜索,计算六个方向的矢量的cost,以最小者为起点,再进行正方形细化,
搜索当前的最佳的mv的头的8个连结点的向量的cost,比较大小得到mv,过程和钻石形类似
case X264_ME_UMH:非对称十字多六边形网格搜索,
具体的搜索步骤引用()
JM中快速整像素运动估计算法(Unsymmetrical-cross Muti-Hexagon-grid Search)即UMHexagonS,该算法高效的起始点预测和搜索策略,
该算法用四个步骤完成。

第一步:用多种预测模式进行初始搜索点预测。

主要对以下运动矢量所指
向的点进行搜索,获得当前最优预测起点。

A,中值预测;
B,原点预测;
C,上层块预测;
D,前帧同位置块预测;
E,相邻(多)参考帧预测。

第二步:进行混合搜索,包括如下:
A,非对称十字搜索。

B,5×5全搜索。

C,扩展的多层次六边形(六角形)格点搜索。

第三步:以当前最优点为中心,用六边形(六角形)进行搜索,直至最优点在六边型的中点为止。

第四步:以当前最优点为中心,用小菱形进行搜索,直至最优点在小菱形的中点为止。

在x264中,对于初始索引点的位置是在x264_mb_predict_mv_16x16中已经获得,在case X264_ME_UMH中主要是进行后面的三步。

部分函数解释如下:
.
DIA1_ITER(pmx,pmy);//在1/4像素出进行小菱形的搜索,并获得最小值
.
//若为i_piexl为4*4时,直接进行六边形细化,因为其预测矢量的精度较高,可以跳过十字形搜索和多级六边形搜索,
if(i_pixel==PIXEL_4x4)
goto me_hex2;
.
//将获得的1/4像素的cost(ucost2)和整像素的cost进行比较,若果相等就赋值cross_start=3,此时的Bcost//为整像素的cost,ucost1为初始的cost if(bcost==ucost2)
cross_start=3;
.
//cross函数主要是在进行十字搜索,在垂直和水平方向进行搜索最小的cost CROSS(3,range,range);
.
case X264_ME_ESA:穷尽搜索法,x264已经取消了这种古老的全搜索法,而是采用下面改进的搜索法
case X264_ME_TESA:hadamard全搜索法,这个算法和ESA相比主要是在搜索范围上的变化
//在完成了上面的整像素搜索后,由参数设置来进行1/2,1/4像素的搜索
if(bpred_cost bcost)
{
m-mv[0]=bpred_mx;
m-mv[1]=bpred_my;
m-cost=bpred_cost;
}
else
{
m-mv[0]=bmx 2;
m-mv[1]=bmy 2;
m-cost=bcost;
}
m-cost_mv=p_cost_mvx[m-mv[0]]+p_cost_mvy[m-mv[1]];
if(bmx==pmx&&bmy==pmy&&h-mb.i_subpel_refine 3)
m-cost+=m-cost_mv;
if(h-mb.i_subpel_refine=2)
{
int hpel=subpel_iterations[h-mb.i_subpel_refine][2];
int qpel=subpel_iterations[h-mb.i_subpel_refine][3];
refine_subpel(h,m,hpel,qpel,p_halfpel_thresh,0);
}
}
以上只是针对16*16帧间的MB的运动估计的跟踪,其他MB类型的ME类似
运动估计
一概述运动估计的基本思想是将图像序列的每一帧分成许多互不重叠的宏块,并认为宏块内所有象素的位移量都相同,然后对每个宏块到参考帧某一给定特定搜索范围内根据一定的匹配准则找出与当前块最相似的块,即匹配块,匹配块与当前块的相对位移即为运动矢量。

视频压缩的时候,只需保存运动矢量和残差数据就可以完全恢复出当前块。

基本概念在帧间预测编码中,由于活动图像邻近帧中的景物存在着一定的相关性。

因此,可将活动图像分成若干块或宏块,并设法搜索出每个块或宏块在邻近帧图像中的位置,并得出两者之间的空间位置的相对偏移量,得到的相对偏移量就是通常所指的运动矢量,得到运动矢量的过程被称为运动估计。

运动矢量和经过运动匹配后得到的预测误差共同发送到解码端,在解码端按照运动矢量指明的位置,从已经解码的邻近参考帧图像中找到相应的块或宏块,和预测误差相加后就得到了块或宏块在当前帧中的位置。

通过运动估计可以去除帧间冗余度,使得视频传输的比特数大为减少,因此,运动估计是视频压缩处理系统中的一个重要组成部分。

本节先从运动估计的一般方法入手,重点讨论了运动估计的三个关键问题:将运动场参数化、最优化匹配函数定义以及如何寻找到最优化匹配。

运动估计的方法
一般的运动估计方法如下:设t时刻的帧图像为当前帧f(x,y),t'时刻的帧图像为参考帧f'(x,y),参考帧在时间上可以超前或者滞后于当前帧,如图1所示,当t't时,称之为后向运动估计,
当t't时,称之为前向运动估计。

当在参考帧t'中搜索到当前帧t中的块的最佳匹配时,可以得到相
应的运动场d(x;t,t+t△),即可得到当前帧的运动矢量。

图1前向或后向运动估计H.264编码标准和以往采用的视频压缩标准很大的不同在于,在运动估计过程中采用了多参考
帧预测来提高预测精度,多参考帧预测就是在编解码端建一个存储M个重建帧的缓存,当前的待编
码块可以在缓存内的所有重建帧中寻找最优的匹配块进行运动补偿,以便更好地去除时间域的冗余
度。

由于视频序列的连续性,当前块在不同的参考帧中的运动矢量也是有一定的相关性的。

假定当
前块所在帧的时间为t,则对应前面的多个参考帧的时间分别为:t-1,t-2,…。

则当在帧t-2中搜索
当前块的最优匹配块时,可以利用当前块在帧t-1中的运动矢量MVNR来估测出当前块在帧t-2的运
动矢量。

运动表示法
由于在成象的场景中一般有多个物体作不同的运动,如果直接按照不同类型的运动将图像分割成复杂的区域是比较困难的。

最直接和不受约束的方法是在每个像素都指定运动矢量,这就是所谓基于像素表示法。

这种表示法是对任何类型图像都是适用的,但是它需要估计大量的未知量,并且它的解时常在物理上是不正确,除非在估计过程中施加适当的物理约束。

这在具体实现时是不可能的,通常采用基于块的物体运动表示法。

4.1基于块的运动表示法
一般对于包含多个运动物体的景物,实际中普遍采用的方法是把一个图像帧分成多个块,使得在每个区域中的运动可以很好地用一个参数化模型表征,这被称为块匹配法,即将图像分成若干个n×n块(典型值:16×16宏块),为每一个块寻找一个运动矢量MV,并进行运动补偿预测编码。

每一个帧间宏块或块都是根据先前已编码的数据预测出的,根据已编码的宏块、块预测的值和当前宏块、块作差值,结果被压缩传送给解码器,与解码器所需要的其他信息如(运动矢量、预测模型等)一起用来重复预测过程。

每个分割区域都有其对应的运动矢量,并必须对运动矢量以及块的选择方式进行编码和传输。

在细节比较多的帧中如果选择较大的块尺寸,意味着用于表明运动矢量和分割区域类型的比特数会少些,但是运动压缩的冗余度要多一些;如果选择小一点的块尺寸,那么运动压缩后冗余度要少一些,但是所需比特数要比较多。

因此必须要权衡块尺寸选择上对压缩效果的影响,一般对于细节比较少、比较平坦的区域选择块尺寸大一些,对于图像中细节比较多的区域选择块尺寸小一些。

宏块中的每个色度块(Cb和Cr)尺寸宽高都是亮度块的一半,色度块的分割方法和亮度块同样,只是尺寸上宽高都是亮度块一半(如亮度块是8×16块尺寸大小,那么色度块就是4×8,如果亮度块尺寸为8×4,那么色度块便是4×2等等)。

每个色度块的运动矢量的水平和垂直坐标都是亮度块的一半。

4.2亚像素位置的内插
帧间编码宏块中的每个块或亚宏块分割区域都是根据参考帧中的同尺寸的区域预测得到的,它
们之间的关系用运动矢量来表示。

由于自然物体运动的连续性,相邻两帧之间的块的运动矢量不是以整像素
为基本单位的,可能
真正的运动位移量是以1/4像素或者甚至1/8像素等亚像素作为为单位的。

图3.17给出了一个视频序列当采用1/2像素精度、1/4像素精度和1/8像
素精度时编码效率的情
况,从图中可以看到1/4像素精度相对于1/2像素精度的编码效率有很明
显的提高,但是1/8像素精
度相对于1/4像素精度的编码效率除了在高码率情况下并没有明显的提高,而且1/8像素的内插公式
更为复杂,因此在H.264的制定过程中1/8像素精度的运动矢量模型逐渐
被取消而只采用了1/4像素
精度的运动矢量模型。

图24.3运动矢量在时空域的预测方式
如果对每个块的运动矢量进行编码,那么将花费相当数目的比特数,特别
是如果选择小尺寸的
块的时候。

由于一个运动物体会覆盖多个分块,所以空间域相邻块的运动
矢量具有很强的相关性,
因此,每个运动矢量可以根据邻近先前已编码的块进行预测,预测得到的
运动矢量用MVp表示,当
前矢量和预测矢量之间的差值用MVD表示。

同时由于物体运动的连续性,
运动矢量在时间域也存
在一定相关性,因此也可以用邻近参考帧的运动矢量来预测。

1)运动矢量空间域预测方式
a、运动矢量中值预测(Median Prediction)
利用与当前块E相邻的左边块A,上边块B和右上方的块C的运动矢量,
取其中值来作为当前
块的预测运动矢量。

设E为当前宏块、宏块分割或者亚宏块分割,A在E的左侧,B在E的上方、C在E的右上
方,如果E的左侧多于一个块,那么选择最上方的块作为A,在E的上方
选择最左侧的块作为B。

图3.18表示所有的块尺寸相同,图3.19表示邻近块尺寸不同时作为预测
E的运动矢量的块的选择。

在预测E的过程中遵守以下准则:
1、对于除了块尺寸为16×8和8×16的块来说,MVp是块A、B和C的运
动矢量的中值;
2、对于16×8块来说,上方的16×8块的MVp根据B预测得到,下方的
16×8块的MVp根据A
得到;
3、对于8×16块来说,左侧的16×8块的MVp根据A预测得到,右侧的
16×8块的MVp根据C
得到;
4、对于不用编码的可跳过去的宏块,16×16矢量MVp如第一种情况得到。

2)运动矢量在时间域预测方式。

相关文档
最新文档