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

罗索

MVC学习的第六周小结(2009.6.15-2009.6.22)-运动估计4

jackyhwei 发布于 2010-01-28 19:59 点击:次 
一直谈了文献【1】那么久,并没有真正对双向预测进行学习,这里将要说明一下JMVC中的双向预测。这里就以16x16的模式进行说明,在xEstimateMb16x16()中,以下代码便开始了双向预测
TAG:

1. 双向预测

一直谈了文献【1】那么久,并没有真正对双向预测进行学习,这里将要说明一下JMVC中的双向预测。这里就以16x16的模式进行说明,在xEstimateMb16x16()中,以下代码便开始了双向预测,

//===== BI PREDICTION =====
  if( rcRefFrameList0.getActive() && rcRefFrameList1.getActive() )
除了一些设置的中间标志量,值得一提的就是cBSParams.pcAltRefPelData  = &cYuvMbBuffer[1-uiDir]; 这里cYuvMbBuffer是IntYuvMbBuffer类的对象,存放了宏块yuv数据。pcAltRefPelData首次被赋值时,是list1的最佳匹配宏块的IntYuvMbBuffer值,然后在叠代搜索过程中,被最佳匹配的宏块数据所更新(在m_pcMotionEstimation->compensateBlock( &cYuvMbBuffer[uiDir],PART_16x16, MODE_16x16 ) 中)。这个pcAltRefPelData的作用是在加权预测中被用于计算当前宏块数据的双向加权预测值。

以上内容虽然复杂,但是还不是重点,重点是B宏块是怎么和前后两个块匹配的,又如何叠代?

对于BI PREDICTION由于uiSearchRange非零,代码将进入xPelBlockSearch()进行范围从-8到8的整像素搜索。看看XDistSearchStruct的对象m_cXDSS,这个对像将存储用于运动估计宏块的的YUV原始值和预测值,还存储使用的RDCost函数指针。estimateBlockWithStart()中在完成加权预测后,有一段代码如下:

  m_pcXDistortion->getDistStruct( uiMode, m_cParams.getFullPelDFunc(), false, m_cXDSS );  ......语句1
  m_cXDSS.pYOrg = pcWeightedYuvBuffer->getLumBlk();
  m_cXDSS.pUOrg = pcWeightedYuvBuffer->getCbBlk ();
  m_cXDSS.pVOrg = pcWeightedYuvBuffer->getCrBlk ();

这里的代码就是分别进行RDCost函数指针初始化和经过加权预测的当前宏块的的YUV原始值赋值,语句1中第4个参数是false,正是这个参数控制了是够使用双向预测,从这里的代码看,JMVC没有真正的使用双向预测。代码调试试验显示,在xPelBlockSearch()进行整像素搜索时,使用的计算SAD的函数为单向的。因为代码实际使用的SAD计算公式是xGetSAD16x而非xGetBiSAD16x,后者使用的是前后两个参考帧相关宏块的Y平均值和当前宏块比较。

那么当前进入比较是谁呢?是进入叠代的单一参考帧,他们的初始化在xPelBlockSearch()中

      m_cXDSS.pYSearch  = pucYSearch + x;
      m_cXDSS.pUSearch  = pucURef + (y>>1)*iCStride + (x>>1);
      m_cXDSS.pVSearch  = pucVRef + (y>>1)*iCStride + (x>>1);

从调试试验,可以以比较下面的数据:

===================pYOrg ====================================
85  85  83  92  91  89  86  88  88  84  81  78  79  83  83  80
86  83  81  86  83  83  86  88  84  83  78  73  74  74  78  82
87  90  86  91  86  86  83  85  77  80  81  78  75  79  83  85
83  86  86  85  82  84  87  83  77  77  77  74  73  83  83  81
80  83  85  84  83  87  88  82  80  77  76  73  76  83  81  83
78  83  89  86  85  85  84  82  82  77  76  75  78  79  77  81
74  80  94  91  86  84  81  83  83  80  79  79  76  73  69  74
77  83  89  88  85  85  85  83  81  81  80  77  77  80  76  82
83  87  91  92  93  89  83  79  81  83  81  71  69  72  72  78
86  90  90  82  87  87  85  79  83  83  82  76  71  74  78  78
85  90  90  78  83  87  83  81  87  85  81  80  78  77  77  77
85  87  88  82  83  81  81  81  89  87  82  82  85  83  79  77
85  85  81  84  84  88  90  90  82  84  80  82  85  79  75  79
81  81  83  85  88  92  96  96  80  80  84  82  81  71  67  71
85  85  89  89  92  90  92  90  76  76  84  83  78  72  72  76
85  89  93  91  94  90  88  90  80  80  84  83  78  72  74  80

===================pYSearch =================================
76  76  76  76  76  76  76  76  76  76  76  76  76  76  76  76
79  79  79  79  79  79  79  79  79  79  79  79  79  79  78  78
80  80  80  80  80  80  80  80  80  80  80  80  80  80  79  79
83  83  83  83  83  83  83  83  83  83  83  83  83  83  81  80
84  84  84  84  84  84  84  84  84  84  84  84  84  84  82  81
87  87  87  87  87  87  87  87  87  87  87  87  87  87  84  83
87  87  87  87  87  87  87  87  87  87  87  87  87  87  84  83
87  87  87  87  87  87  87  87  87  87  87  87  87  87  84  83
87  87  87  87  87  87  87  87  87  87  87  87  87  87  84  83
87  87  87  87  87  87  87  87  87  87  87  87  87  87  85  84
87  87  87  87  87  87  87  87  87  87  87  87  87  87  85  84
87  87  87  87  87  87  87  87  87  87  87  87  87  87  85  84
87  87  87  87  87  87  87  87  87  87  87  87  87  87  86  85
87  87  87  87  87  87  87  87  87  87  87  87  87  87  86  85
87  87  87  87  87  87  87  87  87  87  87  87  87  87  86  85
87  87  87  87  87  87  87  87  87  87  87  87  87  87  86  85

76  76  76  76  76  76  76  76  76  76  76  76  76  76  76  76
79  79  79  79  79  79  79  79  79  79  79  79  79  78  78  76
80  80  80  80  80  80  80  80  80  80  80  80  80  79  79  76
83  83  83  83  83  83  83  83  83  83  83  83  83  81  80  80
84  84  84  84  84  84  84  84  84  84  84  84  84  82  81  80
87  87  87  87  87  87  87  87  87  87  87  87  87  84  83  80
87  87  87  87  87  87  87  87  87  87  87  87  87  84  83  80
87  87  87  87  87  87  87  87  87  87  87  87  87  84  83  80
87  87  87  87  87  87  87  87  87  87  87  87  87  84  83  81
87  87  87  87  87  87  87  87  87  87  87  87  87  85  84  81
87  87  87  87  87  87  87  87  87  87  87  87  87  85  84  82
87  87  87  87  87  87  87  87  87  87  87  87  87  85  84  83
87  87  87  87  87  87  87  87  87  87  87  87  87  86  85  83
87  87  87  87  87  87  87  87  87  87  87  87  87  86  85  84
87  87  87  87  87  87  87  87  87  87  87  87  87  86  85  84
87  87  87  87  87  87  87  87  87  87  87  87  87  86  85  84

76  76  76  76  76  76  76  76  76  76  76  76  76  76  76  76
79  79  79  79  79  79  79  79  79  79  79  79  78  78  76  76
80  80  80  80  80  80  80  80  80  80  80  80  79  79  76  76
83  83  83  83  83  83  83  83  83  83  83  83  81  80  80  79
84  84  84  84  84  84  84  84  84  84  84  84  82  81  80  79
87  87  87  87  87  87  87  87  87  87  87  87  84  83  80  79
87  87  87  87  87  87  87  87  87  87  87  87  84  83  80  79
87  87  87  87  87  87  87  87  87  87  87  87  84  83  80  79
87  87  87  87  87  87  87  87  87  87  87  87  84  83  81  80
87  87  87  87  87  87  87  87  87  87  87  87  85  84  81  80
87  87  87  87  87  87  87  87  87  87  87  87  85  84  82  81
87  87  87  87  87  87  87  87  87  87  87  87  85  84  83  82
87  87  87  87  87  87  87  87  87  87  87  87  86  85  83  82
87  87  87  87  87  87  87  87  87  87  87  87  86  85  84  83
87  87  87  87  87  87  87  87  87  87  87  87  86  85  84  83
87  87  87  87  87  87  87  87  87  87  87  87  86  85  84  83

它们分别是当前宏块的Y值和list0的预测块的Y值,可以看见预测块在做全像素搜索的水平偏移关系。这些预测块的值来自estimateBlockWithStart()函数

pcRefPelData[0] = const_cast<IntFrame&>(rcRefFrame).getFullPelYuvBuffer();

叠代搜索是以单一参考帧的最优预测值为起点,进行范围为8的全像素搜索的,它的可以在RDCost得不到持续减小时提前终止(用bChanged控制),否则完成配置定义的搜索次数。

完成代码的查看,来讨论一下当前代码的叠代搜索增益,为什么在叠代搜索中不用快速搜索算法呢?我认为,对list0,list1的估计过程中使用快速搜索,例如xTZSearch,叠代搜索的增益来自其对最优点附近的(小范围)全像素搜索。如果对之前估计过程已经使用全像素搜索,当前代码的叠代搜索将没有增益。从我的一组实验中可以看看如果在叠代搜索中使用xTZSearch会取得怎样的效果。下图展示了叠代预测中把JMVC代码默认的xPelBlockSearch替换成xTZSearch的比较效果,帧是取自ballroom2.yuv的前9帧,GOPSize=8,统计图中是GOP中的6个B帧按编码顺序排列。如图所示,在使用快速搜索后,每帧编码时间下降了1/4,编码质量下降在0.015DB之内。

***************************实验数据*************************

xPelBlockSearch: 9 frames encoded:  Y 32.3391 dB  U 37.8961 dB  V 37.7462 dB

xTZSearch: 9 frames encoded:  Y 32.3356 dB  U 37.8913 dB  V 37.7326 dB

******************************************************************************

可以考虑修改代码实现xGetBiSAD16x来进行双向搜索,并优化实现双向搜索。(todo:留着作学生毕设课题 微笑 

2.亚像素搜索

在完成了整像素搜索后,MotionEstimationQuarterPel::xSubPelSearch()将被调用作亚像素搜索。如同代码的其他部分,bQPelOnly被设置为不起作用,可以跳过所有bQPelOnly的作用区域。亚像素是先围绕最佳整像素点进行1/2像素搜索,然后在最佳点周围再进行1/4,逐步求精。如下图:

再来分析一下具体程序,rcMv传进来整数搜索的最佳点,函数MotionEstimationQuarterPel::xCompensateBlocksHalf()的作用就是从具体的内存单元中取得1/2像素的Y值信息,辗转找了半天,这些1/2像素点值是在QuarterPelFilter::filterFrame()被设进来的,而1/4像素点则在这里的m_pcQuarterPelFilter->filterBlock()里具体计算。这些点采用不同的插值滤波器由整像素点生成,具体的数学过程可以参考文献【2】。

陆续花了四周时间,总算把运动估计部分弄清楚了,具体的视差估计还没有在代码中实现,这应该是立体视频最精彩的部分,参考模型给我们预留了很多空间,等以后计算机视觉的学习有一些积累后再进行探讨。下周(2009.6.22-2009.6.28)将探讨一些参考帧管理和数据IO之类的琐事,为以后的继续深入学习打好基础。

【参考文献】
1. Siu-Wai Wu and Allen Gersho, "Joint Estimation of Forward and Backward Motion
Vectors for Interpolative Prediction of Video"
2. 毕厚杰, “新一代视频压缩编码标准:H.264/AVC”

(jacky)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201001/8431.html]
本文出处:网络博客 作者:jacky
顶一下
(1)
100%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容