织梦CMS - 轻松建站从此开始!

罗索

MVC学习的第四周小结(2009.6.1-2009.6.7)-运动估计2

jackyhwei 发布于 2010-01-26 11:15 点击:次 
经过上周的努力,已经了解了基于块匹配的运动估计快速算法相关知识,无论是UMHexagonS【1】【2】还是EPZS【3】【4】,其实都基于同样的方法论
TAG:

 

1.块运动估计方法论

经过上周的努力,已经了解了基于块匹配的运动估计快速算法相关知识,无论是UMHexagonS【1】【2】还是EPZS【3】【4】,其实都基于同样的方法论:
    1. 利用各种预测器,确定初始的匹配点。比如常用的中值预测器【2】,用于预测一个候选的搜索起点,当然(0,0)位置也是初始起点之一,在这些候选点中用RDcost(见“MVC学习的第三周小结(2009.5.25-2009.5.31)-运动估计1” 公式1)求解最优点,然后把候选点按优先级(cost最小的最优)排序。
    2. 设计提前终止策略,在条件满足的情况下,结束运动估计,输出最优点,计算(0,0)和最优点间的运动矢量。

    3. 不能满足2则,从最优点开始进行匹配点搜索,一般是用复合匹配模式来适合不同的运动情况,避免陷入局部最优解,然后利用2作为退出条件。

2. 运动估计编解码间的互动

运动估计解码过程已经在H.264标准的8.4节罗列,由于当前的编码器的快速运动估计算法会采用不同的预测器,会造成对MVD的疑虑。码流当中的MVD=MV-MVPred,这个MVPred怎么定呢?经过对JM和JMVC相关部分代码考察,可以看到,在MVD被写进码流前都将重新计算其值,而这时候的MVPred采用中值预测(MVPRED_MEDIAN),JM可以在writeMotionVector8x8()中找到处理过程。在JMVC中的代码如下,比如xEstimateMb16x16()中

    cMvd    [0] = cMv       [0] - cMvPred[0][iRefIdx[0]];
    cMvd    [1] = cMv       [1] - cMvPred[1][iRefIdx[1]];

rpcMbTempData->getMbDataAccess().getMvPredictor()中用中值预测计算出来的预测,而cMv是被确定的相关参考帧最佳适配运动矢量。在解码端也将用共同的中值预测约定,把宏块相关运动矢量恢复出来。在解码端,只要按照中值预测约定,就可以计算出MVPred,加上传送的MVD求得MV。有个值得关注的重要细节是,对帧的首宏块,即没有上宏块也没有左宏块,实际上时不能预测的,所以MVPred=0,这时MVD=MV,传送的是实际的MV值。

3. skip模块和direct预测

在【5】中已经对skip模块和direct预测进行了说明,内容摘抄如下:

================其中内容来自【5】=====================================

B_Skip类型宏块(200503版标准,表7-14最后一行):          无像素残差,无运动矢量残差(MVD)。解码时,通过Direct预测模式(时间或空间)计算出前、后向MV后,直接利用前、后向MV得到像素预测值。像素重构值=像素预测值        

B_Direct_16*16类型宏块(200503版标准,表7-14第一行):有像素残差,无运动矢量残差(MVD)。解码时,通过Direct预测模式(时间或空间)计算出前、后向MV后,利用前、后向MV得到像素预测值。然后,像素重构值=像素预测值+像素残差解码值      

P_Skip类型宏块(200503版标准,表7-13最后一行):          也就是COPY宏块。无像素残差,无运动矢量残差(MVD)。直接利用预测MV得到像素预测值。像素重构值=像素预测值        

【特别说明】:

1、有残差就有CBP(表示残差编码状态,详见BBS中我的帖子“CBP详解”),反过来没有残差当然就没有CBP;      
2、请一定不要把 Direct 类型宏块、Skip 类型宏块、Direct 预测模式这三个混淆了。B_Skip 类型宏块(大小为 16*16)、B_Direct_8*8 类型块(大小为 8*8)和B_Direct 类型宏块(大小为 16*16)都采用的是 Direct 预测模式;
3、关于时间和空间的Direct 预测模式,请大家参考标准文档的8.4.1.2小节;
4、与本论坛另一篇帖子“请问Skipped Macroblock是什么意思? ”参照学习;
=====================================================================

可以看到两种skip类型既无残差也无运动矢量差值,B_Direct分为对16*16和8*8,都是无MVD但是带残差。解码时,通过预测计算MVPred,再依靠帧间运动补偿恢复宏块的亮度色度信息。编码的时候,是怎么确定模式使用direct预测的呢?在JM中相关代码比较琐碎,不过在JMVC中安排得不错。在JMVC的MbEncoder::encodeMacroblock()函数中,首先对对P帧进行xEstimateMbSkip()和对B帧进行了xEstimateMbDirect(),目的都是求出direct预测模式,最终返回RDCost。该RDCost将和16x16,16X8等的预测代价做比较,选出最小的率失真预测。

当然了,在这里即使得到direct预测模式模式的失真最小,也只是把宏块模式设为MODE_SKIP,具体是否能做为不编码的skip宏块,还要在MbDataAccess.h中判断,见下面函数

  Bool    isSkippedMb       ()                    const
  {
    ROTRS( m_rcSliceHeader.isIntra(), false );
    if( m_rcSliceHeader.isInterB() )
    {
      return (m_rcMbCurr.getMbMode() == MODE_SKIP) &&
             (m_rcMbCurr.getMbCbp () == 0)         &&
            !(m_rcMbCurr.getResidualPredFlag(PART_16x16));
    }
    return
  m_rcMbCurr.getMbMode() == MODE_SKIP;
  }

就是说,对B帧还必须判断没有残差值。为什么对P帧不用判断残差情况呢?我还不是很清楚,只能猜测:在hierarchical B结构中,所有的P帧都来自inter-vier视差估计。对于视差估计的P帧,是不是不存一旦确定为MODE_SKIP,就不做残差预测了呢?在函数xSetRdCostInterMb()中找到了确切的证据。

  //===== encode residual and get rate for coefficients =====
  UInt  uiCoeffCost = 0;
  UInt  uiExtCbp    = 0;
  Bool  bSkipMode   = ( eMbMode == MODE_SKIP && rcMbDataAccess.getSH().isInterP() );
 
  if( ! bSkipMode )
  {

   ...

  }

这段处理残差的代码在P帧的MODE_SKIP状态是不起作用的。这意味着该状态一旦被选为最佳模式,将忽略残差,这样是否会带来PSNR损失?会有多少损失?在运动估计阶段为残差编码而不是在确定估计模式后再进行残差编码是否会造成编码速度损失,留待以后学习残差编码的时候解答。(todo:解答残差编码的如上问题

4.关于SATD

SATD是在亚像素运动搜索中被用于代替SAD计算RDCost的值,它的应用价值可以参看【6】

================其中内容来自【6】=====================================

   SAD即绝对误差和,仅反映残差时域差异,影响PSNR值,不能有效反映码流的大小。SATD即将残差经哈德曼变换的4×4块的预测残差绝对值总和,可以将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。因此,不用率失真最优化时,可将其作为模式选择的依据。
   一般帧内要对所有的模式进行检测,帧内预测选用SATD的原因同上。
   在做运动估计时,一般而言,离最优匹配点越远,匹配误差值SAD越大,这就是有名的单一平面假设,现有的运动估计快速算法大都利用该特性。但是,转换后SATD值并不满足该条件,如果在整象素中运用SATD搜索,容易陷入局部最优点。而在亚象素中,待搜索点不多,各点处的SAD差异相对不大,可以用SATD选择码流较少的匹配位置。

=====================================================================

上图显示了SATD的定义,T表示HADAMARD。

5.UMHexagonS和EPZS

经过上面关于运动估计基本分析,现在回头再看看快速搜索算法。 上周小结(“MVC学习的第三周小结(2009.5.25-2009.5.31)-运动估计1”)中,列了关于UMHexagonS和EPZS的比较表,此表并不完全准确,还是从本文开头提出的方法论的三个方向来衡量:

(1)预测器:根据【2】的描述,UMHexagonS除了提供中值预测,还有上层,相关块和邻帧预测。而EPZS理论上还是比较表中的5种预测。实际的JM15.1中不一定能够一一对应,而且代码可读性未必很好。我觉得没有必要详细看代码,自己按照堆算法理解,或自己的idea来写代码到相关部分作实验就好了。

(2)提前终止策略:【2】中针对UMHexagonS提出了根据sad预测值来确定提前终止的策略。SAD也可以根据和MV相似的算法预测,然后把SAD预测值和相关阈值比较,根据不同的搜索法选择不同的阈值,阈值的设计基础是假设输入DCT的残差符合零均值拉普拉斯分布,通过协方差方程建立残差和量化值Q之间的数学模型来推导阈值。EPZS和比较表中描述一致,建立分级的自适应阈值来控制提前终止,这意味着在阈值和计算的RDCost间建立反馈。

(3)搜索:如果预测点不能满足提前终止要求,要以最优点为起点进行按一些pattern进行搜索。只到满足提前终止条件,或所有点搜索完毕。

6. JMVC的运动估计

在MotionEstimation::estimateBlockWithStart中有一个变量bQPelRefinementOnly控制着进入整数像素估计的各算法(xPelBlockSearch,xTZSearch等),这个变量在JMVC当前的代码(4.0和5.0)中总是变赋值为0。查看代码得到它的基本意义是只直接进行1/4像素搜索,不是在整数搜索后进行。在X264的运动估计中,也有类似的配置选择。至于直接进行1/4的结果比较我没有相应的资料,只能定性猜想这样的情况应该比先进行整数像素估计能得到更准确的匹配情况,但是也可能花费更多时间成本。在JMVC调试中可以先不关心这样的case。

按照当前代码,在xTZSearch中实际被调用的只有xTZ8PointDiamondSearch,raster search和后面的star refinement过程。这个过程怎么联系起来的呢?下周再来解决这个问题。(todo:解析详细的xTZSearch)

本周对运动估计的理解加深了许多,还看了一些视差估计的论文,下周((2009.6.8-2009.6.14)还要继续学习运动估计和视差估计,弄清楚JMVC中现有的估计方法,包括整数像素的和亚像素的,同时继续学习一些计算机视觉的知识。

 

 

【参考文献】
1. Zhibo Chen, Peng Zhou, Yun He “jvt-F017”
2. Zhibo Chen, Peng Zhou, Yun He “jvt-G016”
3. Hye-Yeon Cheong Tourapis, Alexis Michael Tourapis “FAST MOTION ESTIMATION WITHIN THE H.264 CODEC”
4. Hye-Yeon Cheong Tourapis, Pankaj Topiwala "jvt-E023"
5. firstime "Skip宏块与Direct预测模式浅析", http://bbs.chinavideo.org/viewthread.php?tid=994
6. 蓝风车, "RDO、SAD、SATD、λ?",http://zmshy2128.blog.163.com/blog/static/2544637200658104210/

 

(mvbdser)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201001/8386.html]
本文出处: 作者:mvbdser
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
发布者资料
mvbdser 查看详细资料 发送留言 加为好友 用户等级:开放浏览 注册时间:2010-01-26 10:01 最后登录:2010-01-26 10:01
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容