1. 程式人生 > >運動估計與運動補償

運動估計與運動補償

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

運動估計與運動補償

轉載自: http://blog.sina.com.cn/s/blog_4b700c4c0100nhgo.html

運動補償是通過先前的區域性影象來預測、補償當前的區域性影象,它是減少幀序列冗餘資訊的有效方法。運動估計是從視訊序列中抽取運動資訊的一整套技術。


運動估計與運動補償技術
    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)的操作。

 

http://wenku.baidu.com/view/10db3c0a79563c1ec5da7164.html

 

定義
  運動補償是通過先前的區域性影象來預測、補償當前的區域性影象,它是減少幀序列冗餘資訊的有效方法。
分類
  包括 全域性運動補償 和 分塊運動補償兩類。  運動補償是一種描述相鄰幀(相鄰在這裡表示在編碼關係上相鄰,在播放順序上兩幀未必相鄰) 差別的方法,具體來說是描述前面一幀(相鄰在這裡表示在編碼關係上的前面,在播放順序上未必在當前幀前面)的每個小塊怎樣移動到當前幀中的某個位置去。這種方法經常被視訊壓縮/視訊編解碼器用來減少視訊序列中的空域冗餘。它也可以用來進行去交織(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:非對稱十字多六邊形網格搜尋,
具體的搜尋步驟引用(
http://bbs.chinavideo.org/viewthread.php?tid=7204&highlight=�˶����
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 畫素

  精度的運動向量模型。

  

   運動估計與運動補償(改正!!!)

2

4.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) 運動向量在時間域預測方式

  a、前幀對應塊運動向量預測(Corresponding-block Prediction)

  利用前一幀的與當前塊相同座標位置的塊的運動向量來作為當前塊的預測運動向量,如圖 3.21

  所示。

  b、時間域的鄰近參考幀運動運動向量預測(Neighboring Reference-frame Prediction)

  由於視訊序列的連續性,當前塊在不同的參考幀中的運動向量也是有一定的的相干性的。如圖

  3.22 所示,假設當前塊所在幀的時間為 t,則當在前面的參考幀 t’中搜索當前塊的最優匹配塊時,可

  以利用當前塊在參考幀 t’+1 中的運動向量來估測出當前塊在幀他 t’的運動向量:

  在上述運動向量的四種預測方式中,經過實驗證明,空間域的預測更為準確,其中上層塊預測

  的效能最優,因為其充分利用了不同預測塊模式運動向量之間的相關性。而中值預測效能隨著預測

  塊尺寸的減小而增加,這是因為當前塊尺寸越小,相關性越強。

4.4匹配誤差在時空域的預測方式

  H.264 中定義的匹配誤差函式如下:

  J(MV,λMOTION)=SAD(s, c (MV))+λMOTION×R(MV-PMV) (3.28)

  其中 SAD(絕對差值和)計算公式如下:

  ,

  1, 1

  (, ( )) | [, ] [ , ]|, , 16,8 4

  xy BB

  xyxy

  xy

  SAD s c MV s x y c x MV y MV B B or

  ==

  =−−− = ∑ (3.29)

  其中 s 是當前進行編碼的原始資料,而 c 是已經編碼重建的用於進行運動補償的參考幀的資料。

  MV為候選的運動向量,λMOTION為拉格朗日常數,PMV 為中值預測向量,R(MV-PMV)代表了運動矢

  量差分編碼可能耗費的位元數,由於在接下來的四種匹配誤差預測方式中匹配誤差中的

  λMOTION×R(MV-PMV)部分通常很接近而抵消,SAD 部分的預測特性基本上可以反映整個匹配函式的

  預測特性,因此 J(MV,λMOTION)用 SAD來表示。

  匹配誤差在時空域的預測方式和運動向量類似,具體分為:

  1)匹配誤差在空間域預測方式

  a、中值預測(Median Prediction)

  與當前塊 E相鄰的左邊塊 A,上邊塊 B 和右上方的塊 C 搜尋得到的最小 SAD值分別為 SADA,

  SADB,SADC,取當前塊的預測 SAD值為:

  SADpred_MD = min (SADx_median,SADy_median) (3.30)

  SADx_median是相鄰塊中對應運動向量橫座標為

  x_median=Median(MVA(x),MVB(x)MVC(x) ) (3.31)

  的相鄰塊的最小 SAD值,SADy_median也同理。如圖 3.23 所示

  b、上層預測(Uplayer Prediction)

  H.264 標準中提供的塊尺寸有 16×16,8×16,16×8,8×8,8×4,4×8,4×4,它們的圖象分割區

  域分別定義為搜尋模式 Mode1-Mode7。假設當前分割區域的預測模式為 Modecurr,上層模式 Modeup

  定義為

  ,1

  1, 2, 3

  2, 4

  4, 5, 6

  5, 7

  curr

  curr

  Up curr

  curr

  curr

  unavailable if Mode Mode

  Mode if Mode Mode Mode

  Mode Mode if Mode Mode