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幀能夠明顯看出採用不一樣實現方法的時不一樣表現3d

slow

下面分析三種不一樣實現方式的具體實現。orm

 

 

Duplication

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

image

 

 

Blend

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

這兩個權重應該知足兩個條件:get

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

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

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來調整重疊區域的權重。

爲了進行更精確的運動補償,咱們能夠對運動向量進行分類。咱們把相差不大的運動向量的塊歸爲一類,把一類看做一個內容,若是相鄰的塊的運動向量相差較大,則代表相鄰塊並不是位於同一個內容之中,而是處於兩個內容之間的邊界,對於這種狀況,能夠採用更小的塊來進行小範圍的搜索,以求得更準確的運動向量,從而在運動補償的時候也能生成更準確的塊。

相關文章
相關標籤/搜索