干貨 | 視頻插幀的方案實(shí)現(xiàn)與對(duì)比~~
對(duì)于視頻網(wǎng)站、電視廠商以及進(jìn)行視頻壓制的用戶來說,改變視頻的幀率算是一個(gè)比較常見的需求。
視頻網(wǎng)站改變幀率主要是為了向不同級(jí)別的網(wǎng)站用戶提供差異化服務(wù);電視廠商則是以提供更好的顯示效果作為電視的賣點(diǎn);
對(duì)視頻壓制有所研究的用戶會(huì)為了更好的顯示效果而追求更高的幀率,或者為了更高的壓縮率而選擇更低的幀率。
幀率的變化能分為兩種:低幀率變?yōu)楦邘?;高幀率變?yōu)榈蛶省km然兩者出于不同的需求,但是采取的是同一實(shí)現(xiàn)方式。
一般來說,視頻中相鄰的兩幀之間有相同的時(shí)間間隔,例如幀率為24的視頻的相鄰兩幀之間的間隔為1/24秒,幀率為60的視頻的相鄰兩幀之間的間隔為1/60秒。
如果要把幀率為24的視頻轉(zhuǎn)換為60的幀率,則需要通過位于0,1/24,2/24,…秒上的幀來構(gòu)造出位于0,1/60,2/60,…秒的幀;
如果要把幀率為24的視頻轉(zhuǎn)換為10的幀率,那么則需要構(gòu)造分別位于0,1/10,2/10,…秒的幀。
本質(zhì)上說,提高幀率以及降低幀率同樣都是構(gòu)造出不存在于源視頻上的幀,兩者只存在構(gòu)造的幀的數(shù)量上的差別。
構(gòu)造不存在的幀,我們稱之為插幀(Frame Interpolation),插幀有三種實(shí)現(xiàn)方式:
- Duplication,復(fù)制相近的幀。
- Blend,用相鄰的兩幀進(jìn)行混合。
- Motion Interpolation,結(jié)合圖像運(yùn)動(dòng)來構(gòu)造中間幀。
下面對(duì)比了這三種不同的實(shí)現(xiàn)方式的插幀效果,把每秒15幀的視頻插幀成每秒30幀:

每秒播放1幀可以明顯看出采用不同實(shí)現(xiàn)方法的時(shí)不同表現(xiàn)

下面分析三種不同實(shí)現(xiàn)方式的具體實(shí)現(xiàn)。
Duplication
輸出的時(shí)間節(jié)點(diǎn)上的幀,就是我們需要生成的幀,此處稱之為中間幀。
在生成當(dāng)前的中間幀的過程中涉及到兩個(gè)輸入幀,分別為小于輸出時(shí)間并且最接近該輸出時(shí)間的輸入幀(假設(shè)為第n幀),以及大于輸出時(shí)間并且最接近該輸出時(shí)間的輸入幀(假設(shè)為第n+1幀),我們可以稱它們?yōu)閰⒖紟?/p>
從這兩個(gè)參考幀中選取時(shí)間上最接近中間幀輸出時(shí)間的一幀,對(duì)這一幀進(jìn)行復(fù)制,作為當(dāng)前的中間幀進(jìn)行輸出。

Blend
與前面Dup的討論相同,中間幀也涉及到左右相鄰的兩個(gè)參考幀,不過blend的實(shí)現(xiàn)是把這兩個(gè)參考幀按照一定方式進(jìn)行混合。
混合方式就是分別為兩幀分配一個(gè)權(quán)重(或者稱之為透明度,不透明時(shí)權(quán)重為1,完全透明時(shí)權(quán)重為0),兩幀的各個(gè)像素在乘上各自的權(quán)重后進(jìn)行相加,即可得到中間幀對(duì)應(yīng)位置上的像素值。
這兩個(gè)權(quán)重應(yīng)該滿足兩個(gè)條件:
- 兩個(gè)權(quán)重應(yīng)該為[0,1]區(qū)間上的數(shù)值,并且兩者相加等于1。
- 距離中間幀遠(yuǎn)的幀的透明度更高,即權(quán)重更小;距離中間幀幀近的幀的透明度更低,即權(quán)重更大。
如此一來,利用中間幀與其左右相鄰的參考幀在時(shí)間上的關(guān)系就能計(jì)算出這兩個(gè)參考幀的權(quán)重。假設(shè)中間幀與參考幀之間在時(shí)間上有以下關(guān)系

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

Motion Interpolation
一般來說,視頻中相鄰兩幀的時(shí)間間隔很短,因此如果這兩幀中的內(nèi)容的變化較?。ㄔ趫?chǎng)景切換的時(shí)候,或者說兩幀中的內(nèi)容變化較大時(shí),直接復(fù)制前一幀進(jìn)行輸出即可),我們可以把兩幀中內(nèi)容的變化看作線性運(yùn)動(dòng)。
如果能夠求出該線性運(yùn)動(dòng)的運(yùn)動(dòng)軌跡,就能根據(jù)該運(yùn)動(dòng)軌跡以及輸入輸出幀的時(shí)間關(guān)系來進(jìn)行內(nèi)容位置的調(diào)整,這種實(shí)現(xiàn)方法被稱為運(yùn)動(dòng)內(nèi)插(Motion Interpolation)。
這種利用物體的運(yùn)動(dòng)對(duì)視頻進(jìn)行插幀的方法會(huì)使得插幀后的視頻顯得更為流暢。
當(dāng)然,視頻中的內(nèi)容復(fù)雜,并不能單純地認(rèn)為一個(gè)運(yùn)動(dòng)的物體的所有部分都是朝一個(gè)方向做線性運(yùn)動(dòng),但是如果把視頻分成小塊,那么就把運(yùn)動(dòng)的物體分解成了一塊塊運(yùn)動(dòng)的色塊,對(duì)于這些色塊,我們則可以認(rèn)為它們是做線性運(yùn)動(dòng)的。(下圖為各個(gè)16x16大小的塊的運(yùn)動(dòng)向量)

由于我們此處認(rèn)為這些小塊是線性運(yùn)動(dòng)的,因此可以根據(jù)時(shí)間關(guān)系得到中間幀上的小塊與參考幀的對(duì)應(yīng)小塊之間的運(yùn)動(dòng)關(guān)系(運(yùn)動(dòng)向量)。

通過運(yùn)動(dòng)向量可以定位到參考幀的兩個(gè)參考?jí)K,以及中間幀上所需要生成的塊的位置,然后就采用類似于上述blend的方法對(duì)塊進(jìn)行合成。
當(dāng)把幀內(nèi)的所有塊都執(zhí)行完合成操作后,就能得到所需的運(yùn)動(dòng)內(nèi)插的幀。

運(yùn)動(dòng)向量搜索
按照前面的描述,在構(gòu)造中間幀之前,必須先求出兩個(gè)參考幀之間各個(gè)塊的運(yùn)動(dòng)向量,這需要把一個(gè)參考幀作為「當(dāng)前幀」,另一個(gè)參考幀作為「參考幀」。參考上圖,在求運(yùn)動(dòng)向量時(shí),我們把序號(hào)為n的幀當(dāng)作「當(dāng)前幀」,把序號(hào)為n+1的幀當(dāng)作「參考幀」。
運(yùn)動(dòng)向量搜索就是把「當(dāng)前幀」分割成小塊,并順次從「參考幀」中搜尋各個(gè)小塊的最優(yōu)匹配塊,這與視頻編碼時(shí)的運(yùn)動(dòng)向量搜索是基本一致的,在搜索時(shí)可以選擇各種各樣的搜索算法。

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

這種方案在計(jì)算運(yùn)動(dòng)向量上會(huì)增加額外的消耗,為了減少這種消耗,在實(shí)際實(shí)現(xiàn)的時(shí)候可能會(huì)假設(shè)中間幀位于兩個(gè)參考幀的正中間,并以此去求運(yùn)動(dòng)向量,求得的運(yùn)動(dòng)向量會(huì)被當(dāng)作穿過實(shí)際中間幀上的「當(dāng)前塊」的運(yùn)動(dòng)向量,該運(yùn)動(dòng)向量在進(jìn)行運(yùn)動(dòng)補(bǔ)償時(shí)會(huì)按照中間幀的實(shí)際位置分割運(yùn)動(dòng)向量。
如下圖,可見「當(dāng)前幀」(n)中的塊與「參考幀」(n+1)中的塊都存在了一定程度的偏移,即進(jìn)行運(yùn)動(dòng)向量搜索時(shí)采用的兩個(gè)塊并非后續(xù)進(jìn)行運(yùn)動(dòng)補(bǔ)償?shù)膬蓚€(gè)塊,這需要我們采取一些補(bǔ)救措施。

運(yùn)動(dòng)補(bǔ)償
我們把通過運(yùn)動(dòng)向量來得到源塊并生成目標(biāo)塊的這一過程稱為運(yùn)動(dòng)補(bǔ)償(motion compensation)。根據(jù)上方兩種不同的運(yùn)動(dòng)向量搜索方式,分別有兩種不同的運(yùn)動(dòng)補(bǔ)償方案。
如果采用上述第一種運(yùn)動(dòng)向量搜索方案,在運(yùn)動(dòng)補(bǔ)償時(shí)時(shí),會(huì)以這兩個(gè)參考幀以及中間幀之間的時(shí)間關(guān)系來對(duì)運(yùn)動(dòng)向量進(jìn)行分割,分割點(diǎn)就是插幀生成的塊的位置,如下圖

如果采用上述第二種運(yùn)動(dòng)向量搜索方案,在運(yùn)動(dòng)補(bǔ)償時(shí),是中間幀上的各個(gè)塊就是插幀生成的塊的位置,如下圖

對(duì)比兩個(gè)中不同方案:
- 在進(jìn)行運(yùn)動(dòng)向量搜索時(shí),方案一相對(duì)于方案二節(jié)省了運(yùn)動(dòng)向量的計(jì)算的消耗。
- 在進(jìn)行運(yùn)動(dòng)補(bǔ)償時(shí)方案一無法保證完全填充中間幀,因此總會(huì)出現(xiàn)未填充區(qū)域,而方案二則可以完全覆蓋整個(gè)中間幀。
- 方案一如果為了節(jié)省運(yùn)動(dòng)向量搜索時(shí)的消耗而采取我們前面所說的優(yōu)化處理,則會(huì)導(dǎo)致執(zhí)行運(yùn)動(dòng)補(bǔ)償?shù)膲K并非運(yùn)動(dòng)向量搜索時(shí)得到的塊。
為了提高方案二對(duì)中間幀的覆蓋率,以及提高方案一中運(yùn)動(dòng)向量搜索所得的塊與運(yùn)動(dòng)補(bǔ)償?shù)膲K之間的相關(guān)性,我們?cè)诒3謮K位置不變的情況下把塊的寬高提升為兩倍。
例如,原本各個(gè)塊的大小為16x16,原本各個(gè)塊的位置位于(0, 0), (0, 16), (0, 32),…,(16, 0), (16, 16), (16, 32), … 提升后的各個(gè)塊的大小為32x32,即在運(yùn)動(dòng)向量搜索以及運(yùn)動(dòng)補(bǔ)償?shù)臅r(shí)候塊的大小都是32x32,但是各個(gè)塊的位置不變。

此時(shí)無論是方案一還是方案二,在執(zhí)行運(yùn)動(dòng)補(bǔ)償?shù)臅r(shí)候都會(huì)出現(xiàn)生成的塊之間相互覆蓋的情況,但是這并非我們需要的效果,我們可以為一個(gè)塊中的各個(gè)像素分配一個(gè)權(quán)重,在進(jìn)行運(yùn)動(dòng)補(bǔ)償?shù)臅r(shí)候就可以按照這個(gè)權(quán)重對(duì)相互覆蓋的塊的像素進(jìn)行混合。
通常為了更好的顯示效果,混合的像素應(yīng)該平滑地過渡,因此越靠近塊的邊緣的像素應(yīng)該權(quán)重更小,越靠近塊的中心的像素的權(quán)重更大。
最后,對(duì)于方案一,即使提高了中間幀的覆蓋率,但是還是很有可能出現(xiàn)無法覆蓋的區(qū)域,對(duì)于這種區(qū)域,只能用兩個(gè)參考幀的對(duì)應(yīng)位置上的像素來進(jìn)行混合。
其它優(yōu)化措施
對(duì)于方案一,上面的描述只采用了單向運(yùn)動(dòng)預(yù)測(cè),采用雙向運(yùn)動(dòng)預(yù)測(cè)可以有更高的中間幀覆蓋率,在實(shí)現(xiàn)的時(shí)候只需要把序號(hào)為n+1幀作為「當(dāng)前幀」,序號(hào)為n的幀作為「參考幀」。
對(duì)于方案二,在運(yùn)動(dòng)補(bǔ)償?shù)臅r(shí)候由于各個(gè)塊之間的重疊區(qū)域是固定的,因此我們可以去比較重疊區(qū)域之間的cost來調(diào)整重疊區(qū)域的權(quán)重。
為了進(jìn)行更精確的運(yùn)動(dòng)補(bǔ)償,我們可以對(duì)運(yùn)動(dòng)向量進(jìn)行分類。
我們把相差不大的運(yùn)動(dòng)向量的塊歸為一類,把一類看作一個(gè)內(nèi)容,如果相鄰的塊的運(yùn)動(dòng)向量相差較大,則表明相鄰塊并非位于同一個(gè)內(nèi)容之中,而是處于兩個(gè)內(nèi)容之間的邊界,對(duì)于這種情況,可以采用更小的塊來進(jìn)行小范圍的搜索,以求得更準(zhǔn)確的運(yùn)動(dòng)向量,從而在運(yùn)動(dòng)補(bǔ)償?shù)臅r(shí)候也能生成更準(zhǔn)確的塊。
來源:https://www.cnblogs.com/TaigaCon/p/10612354.html

技術(shù)交流,歡迎加我微信:ezglumes ,拉你入技術(shù)交流群。
私信領(lǐng)取相關(guān)資料
推薦閱讀:
音視頻開發(fā)工作經(jīng)驗(yàn)分享 || 視頻版
開通專輯 | 細(xì)數(shù)那些年寫過的技術(shù)文章專輯
Android NDK 免費(fèi)視頻在線學(xué)習(xí)?。?!
推薦幾個(gè)堪稱教科書級(jí)別的 Android 音視頻入門項(xiàng)目
覺得不錯(cuò),點(diǎn)個(gè)在看唄~

