Frame Interpolation


對於視頻網站、電視廠商以及進行視頻壓制的用戶來說,改變視頻的幀率算是一個比較常見的需求。視頻網站改變幀率主要是為了向不同級別的網站用戶提供差異化服務;電視廠商則是以提供更好的顯示效果作為電視的賣點;對視頻壓制有所研究的用戶會為了更好的顯示效果而追求更高的幀率,或者為了更高的壓縮率而選擇更低的幀率。

幀率的變化能分為兩種:低幀率變為高幀率;高幀率變為低幀率。雖然兩者出於不同的需求,但是采取的是同一實現方式。一般來說,視頻中相鄰的兩幀之間有相同的時間間隔,例如幀率為24的視頻的相鄰兩幀之間的間隔為1/24秒,幀率為60的視頻的相鄰兩幀之間的間隔為1/60秒。如果要把幀率為24的視頻轉換為60的幀率,則需要通過位於0,1/24,2/24,…秒上的幀來構造出位於0,1/60,2/60,…秒的幀;如果要把幀率為24的視頻轉換為10的幀率,那么則需要構造分別位於0,1/10,2/10,…秒的幀。本質上說,提高幀率以及降低幀率同樣都是構造出不存在於源視頻上的幀,兩者只存在構造的幀的數量上的差別。

image

構造不存在的幀,我們稱之為插幀(Frame Interpolation),插幀有三種實現方式:

  1. Duplication,復制相近的幀。
  2. Blend,用相鄰的兩幀進行混合。
  3. Motion Interpolation,結合圖像運動來構造中間幀。

下面對比了這三種不同的實現方式的插幀效果,把每秒15幀的視頻插幀成每秒30幀:

 normal

每秒播放1幀可以明顯看出采用不同實現方法的時不同表現

slow

下面分析三種不同實現方式的具體實現。

 

 

Duplication

輸出的時間節點上的幀,就是我們需要生成的幀,此處稱之為中間幀。在生成當前的中間幀的過程中涉及到兩個輸入幀,分別為小於輸出時間並且最接近該輸出時間的輸入幀(假設為第n幀),以及大於輸出時間並且最接近該輸出時間的輸入幀(假設為第n+1幀),我們可以稱它們為參考幀。從這兩個參考幀中選取時間上最接近中間幀輸出時間的一幀,對這一幀進行復制,作為當前的中間幀進行輸出。

image

 

 

Blend

與前面Dup的討論相同,中間幀也涉及到左右相鄰的兩個參考幀,不過blend的實現是把這兩個參考幀按照一定方式進行混合。混合方式就是分別為兩幀分配一個權重(或者稱之為透明度,不透明時權重為1,完全透明時權重為0),兩幀的各個像素在乘上各自的權重后進行相加,即可得到中間幀對應位置上的像素值。

這兩個權重應該滿足兩個條件:

  1. 兩個權重應該為[0,1]區間上的數值,並且兩者相加等於1。
  2. 距離中間幀遠的幀的透明度更高,即權重更小;距離中間幀幀近的幀的透明度更低,即權重更大。

如此一來,利用中間幀與其左右相鄰的參考幀在時間上的關系就能計算出這兩個參考幀的權重。假設中間幀與參考幀之間在時間上有以下關系

image

左邊的參考幀的權重應該為(L-α)/L,右邊的參考幀的透明度應該為α/L。兩個參考幀乘上各自的權重后相加即可得到中間幀。

image

 

 

Motion Interpolation

一般來說,視頻中相鄰兩幀的時間間隔很短,因此如果這兩幀中的內容的變化較小(在場景切換的時候,或者說兩幀中的內容變化較大時,直接復制前一幀進行輸出即可),我們可以把兩幀中內容的變化看作線性運動。如果能夠求出該線性運動的運動軌跡,就能根據該運動軌跡以及輸入輸出幀的時間關系來進行內容位置的調整,這種實現方法被稱為運動內插(Motion Interpolation)。這種利用物體的運動對視頻進行插幀的方法會使得插幀后的視頻顯得更為流暢。

當然,視頻中的內容復雜,並不能單純地認為一個運動的物體的所有部分都是朝一個方向做線性運動,但是如果把視頻分成小塊,那么就把運動的物體分解成了一塊塊運動的色塊,對於這些色塊,我們則可以認為它們是做線性運動的。(下圖為各個16x16大小的塊的運動向量)

mv

由於我們此處認為這些小塊是線性運動的,因此可以根據時間關系得到中間幀上的小塊與參考幀的對應小塊之間的運動關系(運動向量)。

image

通過運動向量可以定位到參考幀的兩個參考塊,以及中間幀上所需要生成的塊的位置,然后就采用類似於上述blend的方法對塊進行合成。當把幀內的所有塊都執行完合成操作后,就能得到所需的運動內插的幀。

image

 

運動向量搜索

按照前面的描述,在構造中間幀之前,必須先求出兩個參考幀之間各個塊的運動向量,這需要把一個參考幀作為「當前幀」,另一個參考幀作為「參考幀」。參考上圖,在求運動向量時,我們把序號為n的幀當作「當前幀」,把序號為n+1的幀當作「參考幀」。

運動向量搜索就是把「當前幀」分割成小塊,並順次從「參考幀」中搜尋各個小塊的最優匹配塊,這與視頻編碼時的運動向量搜索是基本一致的,在搜索時可以選擇各種各樣的搜索算法。

image

 

此外還有一種運動向量搜索方案,該方案以中間幀為基准,把中間幀分割成小塊,順次地把這些小塊當作「當前塊」進行運動向量搜索。這種搜索方案要求:對「當前塊」求的所有運動向量都需要通過「當前塊」,即以「當前塊」為中心。具體是把「當前塊」作為中心點(0,0),如果運動向量為(x, y),那么「當前幀」上的塊的相對位置為(-xα/L, -yα/L),「參考幀」上的塊的相對位置為(x(L-α)/L, -y(L-α)/L)。

image

這種方案在計算運動向量上會增加額外的消耗,為了減少這種消耗,在實際實現的時候可能會假設中間幀位於兩個參考幀的正中間,並以此去求運動向量,求得的運動向量會被當作穿過實際中間幀上的「當前塊」的運動向量,該運動向量在進行運動補償時會按照中間幀的實際位置分割運動向量。如下圖,可見「當前幀」(n)中的塊與「參考幀」(n+1)中的塊都存在了一定程度的偏移,即進行運動向量搜索時采用的兩個塊並非后續進行運動補償的兩個塊,這需要我們采取一些補救措施。

image

 

運動補償

我們把通過運動向量來得到源塊並生成目標塊的這一過程稱為運動補償(motion compensation)。根據上方兩種不同的運動向量搜索方式,分別有兩種不同的運動補償方案。

如果采用上述第一種運動向量搜索方案,在運動補償時時,會以這兩個參考幀以及中間幀之間的時間關系來對運動向量進行分割,分割點就是插幀生成的塊的位置,如下圖

image

如果采用上述第二種運動向量搜索方案,在運動補償時,是中間幀上的各個塊就是插幀生成的塊的位置,如下圖

image

 

對比兩個中不同方案:

  • 在進行運動向量搜索時,方案一相對於方案二節省了運動向量的計算的消耗。
  • 在進行運動補償時方案一無法保證完全填充中間幀,因此總會出現未填充區域,而方案二則可以完全覆蓋整個中間幀。
  • 方案一如果為了節省運動向量搜索時的消耗而采取我們前面所說的優化處理,則會導致執行運動補償的塊並非運動向量搜索時得到的塊。

為了提高方案二對中間幀的覆蓋率,以及提高方案一中運動向量搜索所得的塊與運動補償的塊之間的相關性,我們在保持塊位置不變的情況下把塊的寬高提升為兩倍。例如,原本各個塊的大小為16x16,原本各個塊的位置位於(0, 0), (0, 16), (0, 32),…,(16, 0), (16, 16), (16, 32), … 提升后的各個塊的大小為32x32,即在運動向量搜索以及運動補償的時候塊的大小都是32x32,但是各個塊的位置不變。

image

此時無論是方案一還是方案二,在執行運動補償的時候都會出現生成的塊之間相互覆蓋的情況,但是這並非我們需要的效果,我們可以為一個塊中的各個像素分配一個權重,在進行運動補償的時候就可以按照這個權重對相互覆蓋的塊的像素進行混合。通常為了更好的顯示效果,混合的像素應該平滑地過渡,因此越靠近塊的邊緣的像素應該權重更小,越靠近塊的中心的像素的權重更大。

最后,對於方案一,即使提高了中間幀的覆蓋率,但是還是很有可能出現無法覆蓋的區域,對於這種區域,只能用兩個參考幀的對應位置上的像素來進行混合。

 

其它優化措施

對於方案一,上面的描述只采用了單向運動預測,采用雙向運動預測可以有更高的中間幀覆蓋率,在實現的時候只需要把序號為n+1幀作為「當前幀」,序號為n的幀作為「參考幀」。

對於方案二,在運動補償的時候由於各個塊之間的重疊區域是固定的,因此我們可以去比較重疊區域之間的cost來調整重疊區域的權重。

為了進行更精確的運動補償,我們可以對運動向量進行分類。我們把相差不大的運動向量的塊歸為一類,把一類看作一個內容,如果相鄰的塊的運動向量相差較大,則表明相鄰塊並非位於同一個內容之中,而是處於兩個內容之間的邊界,對於這種情況,可以采用更小的塊來進行小范圍的搜索,以求得更准確的運動向量,從而在運動補償的時候也能生成更准確的塊。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM