幀間預測:運動估計和運動補償

運動補償是通過先前的局部圖像來預測、補償當前的局部圖像,它是減少幀序列冗餘信息的有效方法。運動估計是從視頻序列中抽取運動信息的一整套技術。


運動估計與運動補償技術
    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 △ ) ,即可得到當前幀的運動矢量。

  

 

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 像素

  精度的運動矢量模型。

  

 

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

  Mode if Mode Mode Mode

  Mode if Mode Mode

  == ⎧

  ⎪

  == ⎪ ⎪

  === ⎨

  ⎪ ==

  ⎪

  ⎪ == ⎩

  (3.32)

  利用空間域上層搜索模式的搜索所得的最小 SAD 值作爲當前模式下的預測 SAD 值的方法如圖

  3.24 所示:

  SADpred_up = SADuplayer/2 (3.33)

  2)匹配函數在時間域預測方式

  a、前幀對應塊的預測(Corresponding-block Prediction)

  利用前一幀的與當前塊相同座標位置的塊在幀 t’-1 中搜索得到的最小 SAD,作爲當前搜索塊在

  幀 t’中進行搜索的 SAD的預測值,如圖所示。

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

  如圖 3.26 所示,假設當前塊所在幀的時間爲 t,則當在前面的參考幀 t’中搜索時,可以利用當前

  塊在參考幀t’+1中搜索得到的最小SAD值SADNR作爲當前塊在幀t’搜索的SAD預測值,即SADpred_NRP

  =SADNR。

  以上所述的匹配誤差的四種預測方式中,時間域的預測更爲準確,其中鄰近參考幀預測方式性

  能最優,這是由於在這種預測方式下當前塊相同,鄰近參考幀預測方式中,鄰近的參考幀之間具有

  比較強的相關性。但是它的性能受量化參數影響比較大,這是由於量化參數大的時候圖象細節模糊,

  相鄰參考幀圖象內容之間的相似度增加,因而用鄰近參考幀預測的方式會更爲準確一些。

運動估計準則分類

  運動搜索的目的就是在搜索窗內尋找與當前塊最匹配的數據塊,這樣就存在着如何判斷兩個塊

  是否匹配的問題,即如何定義一個匹配準則。而匹配準則的定義與運算複雜度和編碼效率都是直接

  相關的,通常有如下幾類比較常用的匹配函數的定義:

  設當前幀 f2,參考幀 f1,

  (1)最小均方差函數(MSE)

  MSE (MV) =Σ|f2(x,MV)-f1(x)|

  2

  (3.34)

  (2)最小平均絕對值誤差(MAD)等效於常用的絕對差值和(SAD)準則,性能很好,而且相對簡單

  的硬件需求,因而得到了最廣泛的應用。

  MAD (MV) =Σ|f2(x,MV)-f1(x)| (3.35)

  (3)閾值差別計數(NTD)

  NTD(MV)=ΣG(f2(x,MV)-f1(x)) (3.36)

  其中:

  當 | α-β | >T0 時,G(α,β)=1;

  當 | α-β | <T0 時,G(α,β)=0 (3.37)

  由於在用塊匹配算法進行運動估計的過程中,利用匹配準則函數進行匹配誤差的計算是最主要

  的計算量,因此,我們可以從這方面進一步減少計算量。由於圖象的幀內也具有相關性,在計算誤

  差匹配函數時,可以只讓圖象塊中的部分像素參與運算,將塊中的所有像素組成一個集合,那麼參

  與計算的這部分像素集合就是它的子集,這種誤差匹配的方法被稱爲子集匹配法。實驗結果表明,

  在匹配誤差無明顯增加的情況下,採用子集匹配可以大大減少每幀圖象的平均搜索時間。

運動搜索算法

  匹配誤差函數,可以用各種優化方法進行最小化,這就需要我們開發出高效的運動搜索算法,

  主要的幾種算法歸納如下:

6.1 全局搜索算法

  爲當前幀的一個給定塊確定最優位移矢量的全局搜索算法方法是:在一個預先定義的搜索區域

  內,把它與參考幀中所有的候選塊進行比較,並且尋找具有最小匹配誤差的一個。這兩個塊之間的

  位移就是所估計的 MV,這樣做帶來的結果必然導致極大的計算量。

  選擇搜索區域一般是關於當前塊對稱的,左邊和右邊各有 Rx 個像素,上邊和下邊各有 Ry個像

  素,如圖 3.27 所示。

  如果已知在水平和垂直方向運動的動態範圍是相同的,那麼 Rx=Ry=R。估計的精度是由搜索的

  步長決定的,步長是相鄰兩個候選塊在水平或者垂直方向上的距離。通常,沿着兩個方向使用相同

  的步長。在最簡單的情況下,步長是一個像素,稱爲整數像素精度搜索,該種算法也稱爲無損搜索

  算法。

6.2 分數精度搜索算法

  由於在窮盡塊匹配算法中搜索相應塊的步長不一定是整數,一般來說,爲了實現 1/K像素步長,

  對參考幀必須進行 K倍內插。圖 3.28 給出了 K=2 的例子,它被稱爲半像素精度搜索。根據實驗證

  明,與整像素精度搜索相比,半像素精度搜索在估計精度上有很大提高,特別是對於低清晰度視頻。

  但是,應用分數像素步長,搜索算法的複雜性大大增加,例如,使用半像素搜索,搜索點的總

  數比整數像素精度搜索大四倍以上。

  那麼,如何確定適合運動估計的搜索步長,對於視頻編碼的幀間編碼來說,即使得預測誤差最

  小化。預測誤差和搜索精度之間的關係的統計分析如圖 3.29 所示:

6.3 快速搜索算法

  快速搜索算法和全局搜索算法相比,雖然只能得到次最佳的匹配結果,但在減少運算量方面效

  果顯著。

  1)二維對數搜索法

  這種算法的基本思路是採用大菱形搜索模式和小菱形搜索模式,步驟如圖 6.4.20 所示,從相應

  於零位移的位置開始搜索,每一步試驗菱形排列的五個搜索點。下一步,把中心移到前一步找到的

  最佳匹配點並重復菱形搜索。當最佳匹配點是中心點或是在最大搜索區域的邊界上時,就減小搜索

  步長(菱形的半徑)。否則步長保持不變。當步長減小到一個像素時就到達了最後一步,並且在這最

  後一步檢驗九個搜索點。初始搜索步長一般設爲最大搜索區域的一半。

  其後這類算法在搜索模式上又做了比較多的改進,在搜索模式上採用了矩形模式,還有六

  邊形模式、十字形模式等等。

  2)三步搜索法

  如圖 3.31 所示,這種搜索的步長從等於或者略大於最大搜索範圍的一半開始。第一步,在起始

  點和周圍八個 “1”標出的點上計算匹配誤差,如果最小匹配誤差在起始點出現,則認爲沒有運動;

  第二步,以第一步中匹配誤差最小的點(圖中起始點箭頭指向的“1”)爲中心,計算以“2”標出的 8

  個點處的匹配誤差。注意,在每一步中搜索步長搜都比上一步長減少一半,以得到更準確的估計;

  在第三步以後就能得到最終的估計結果,這時從搜索點到中心點的距離爲一個像素。

  但是,上述一些快速算法更適合用於估計運動幅度比較大的場合,對於部分運動幅度小的場

  合,它們容易落入局部最小值而導致匹配精度很差,已經有很多各種各樣的視頻流證明了這一點。

  現在,針對這一缺點,國內外諸多專家學者也提出了相應的應對措施,特別是針對H.264編

  碼標準要求的一些快速算法的改進,並取得卓越的效果。例如[7]中提到的基於全局最小值具有自

  適應性的快速算法,這種算法通過在每一搜索步驟選擇多個搜索結果,基於這些搜索結果之間的

  匹配誤差的不同得到的最佳搜索點,因而可以很好地解決落入局部最小值的問題。

  [8]中提到一種適用於H.264的基於自適應搜索範圍的快速運動估計算法,經過實驗證明對於

  如salesman等中小運動序列,其速度可接近全局搜索算法的400倍,接近三步搜索算法的4倍;而對於

  大運動序列,如table tennis,該算法則會自動調節搜索點數以適應複雜的運動。當從總體上考察速度

  方面的性能時,可以看到,該算法平均速度是全局搜索算法的287.4倍,三步搜索的2.8倍。

6.4 分級搜索範圍(DSR)算法

  分級搜索算法的基本思想是從最低分辨率開始逐級精度的進行不斷優化的運動搜索策略,如圖

  3.32 所示,首先取得兩個原始圖象幀的金子塔表示,從上到下分辨率逐級變細,從頂端開始,選擇

  一個尺寸比較大的數據塊進行一個比較粗略的運動搜索過程,對在此基礎上進行亞抽樣(即通過降

  低數據塊尺寸(或提高抽樣分辨率)和減少搜索範圍的辦法)進行到下一個較細的級來細化運動矢

  量,而一個新的搜索過程可以在上一級搜索到的最優運動矢量周圍進行。在亞抽樣的過程中也有着

  不同的抽樣方式和抽樣濾波器。這種方法的優點是運算量的下降比例比較大,而且搜索的比較全面。

  缺點是由於亞抽樣或者濾波器的採用而使內存的需求增加,另外如果場景細節過多可能會容易落入

  局部最小點。

6.5 混合搜索算法

  由於物體的運動千變萬化,很難用一種簡單的模型去描述,也很難用一種單一的算法來搜索最

  佳運動矢量,因此實際上大多采用多種搜索算法相組合的辦法,可以在很大程度上提高預測的有效

  性和魯棒性。

  事實上,在運動估計時也並不是單一使用上述某一類搜索算法,而是根據各類算法的優點靈活

  組合採納。在運動幅度比較大的情況下可以採用自適應的菱形搜索法和六邊形搜索法,這樣可以大

  大節省碼率而圖象質量並未有所下降。在運動圖象非常複雜的情況下,採用全局搜索法在比特數相

  對來說增加不多的情況下使得圖象質量得到保證。 H.264 編碼標準草案推薦使用 1/4分數像素精度搜

  索。[6]中提到在整像素搜索時採用非對稱十字型多層次六邊形格點運動搜索算法,然後採用鑽石搜

  索模型來進行分數像素精度運動估計。

  解碼器要求傳送的比特數最小化,而複雜的模型需要更多的比特數來傳輸運動矢量,而且易受

  噪聲影響。因此,在提高視頻的編碼效率的技術中,運動補償精度的提高和比特數最小化是相互矛

  盾的,這就需要我們在運動估計的準確性和表示運動所用的比特數之間作出折中的選擇。它的效果

  與選用的運動模型是密切相關的。

其他資料

  三常見的運動估計匹配準則有三種:MAD、MSE和NCCF,由於MAD沒有乘除操作,不需做乘法運算,實現簡單方便,所以使用較多。通常使用求和絕對誤差(SAD)代替MAD 。

  運動估計和運動補償是AVS 中去除時間冗餘的主要方法,它採用多種宏塊劃分方式,1P4 像素插值、雙向估計和多參考幀等技術大大提高了編碼效率,但同時也給編解碼器增加了一定的複雜度。

  運動估計和運動補償作爲視頻壓縮編碼系統的核心算法,佔整個系統運算量的60%-80%。研究運動估計算法的DSP實現對整個H.264系統的嵌入式應用具有重要的指導意義。

  運動估計算法

  運動估計算法是視頻壓縮編碼的核心算法之一。高質量的運動估計算法是高效視頻編碼的前提和基礎。其中塊匹配法(BMA, Block Match Algorithm)由於算法簡單和易於硬件實現,被廣泛應用於各視頻編碼標準中。塊匹配法的基本思想是先將圖像劃分爲許多子塊,然後對當前幀中的每一塊根據一定的匹配準則在相鄰幀中找出當前塊的匹配塊,由此得到兩者的相對位移,即當前塊的運動矢量。在H.264標準的搜索算法中,圖像序列的當前幀被劃分成互不重疊16×16大小的子塊,而每個子塊又可劃分成更小的子塊,當前子塊按一定的塊匹配準則在參考幀中對應位置的一定搜索範圍內尋找最佳匹配塊,由此得到運動矢量和匹配誤差。運動估計的估計精度和運算複雜度取決於搜索策略和塊匹配準則。這裏使用H.264推薦算法UMHexagonS(Unsymmetrical-cross Multi-Hexagon-grid Search)作爲DSP實現的算法參考,與FS算法比較,它在保證可靠搜索精度的前提下大幅降低搜索複雜度。同時使用絕對差和(SAD, the Sum of Absolute Difference)標準作爲匹配準則,它具有便於硬件實現的優點。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章