1.块运动估计方法论 经过上周的努力,已经了解了基于块匹配的运动估计快速算法相关知识,无论是UMHexagonS【1】【2】还是EPZS【3】【4】,其实都基于同样的方法论: 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]]; 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得到像素预测值。像素重构值=像素预测值 可以看到两种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 就是说,对B帧还必须判断没有残差值。为什么对P帧不用判断残差情况呢?我还不是很清楚,只能猜测:在hierarchical B结构中,所有的P帧都来自inter-vier视差估计。对于视差估计的P帧,是不是不存一旦确定为MODE_SKIP,就不做残差预测了呢?在函数xSetRdCostInterMb()中找到了确切的证据。 //===== encode residual and get rate for coefficients ===== ... } 这段处理残差的代码在P帧的MODE_SKIP状态是不起作用的。这意味着该状态一旦被选为最佳模式,将忽略残差,这样是否会带来PSNR损失?会有多少损失?在运动估计阶段为残差编码而不是在确定估计模式后再进行残差编码是否会造成编码速度损失,留待以后学习残差编码的时候解答。(todo:解答残差编码的如上问题) 4.关于SATD SATD是在亚像素运动搜索中被用于代替SAD计算RDCost的值,它的应用价值可以参看【6】 ================其中内容来自【6】===================================== SAD即绝对误差和,仅反映残差时域差异,影响PSNR值,不能有效反映码流的大小。SATD即将残差经哈德曼变换的4×4块的预测残差绝对值总和,可以将其看作简单的时频变换,其值在一定程度上可以反映生成码流的大小。因此,不用率失真最优化时,可将其作为模式选择的依据。 ===================================================================== 上图显示了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中现有的估计方法,包括整数像素的和亚像素的,同时继续学习一些计算机视觉的知识。
【参考文献】
|