opencv:視頻去黑暗(增強)

         之前一篇博客寫過一個關於圖像去黑暗的算法(點擊打開 圖像去黑暗 ),它是一個去霧算法的延伸。最近學習了一些視頻的基本知識,想把這個繼續延伸到視頻鄰域。思路基本一樣,先對視頻解碼爲幀,然後在對每一幀圖像進行去黑暗,最後在編碼輸出到文件夾。

    1、使用opencv對視頻編解碼

      正版視頻編解碼處理是使用ffmpeg處理完成,由於對ffmpeg掌握不熟悉,在對opencv進一步瞭解之後(見 參考文獻 1、2、3),發現opencv提供了VideoCapture和VideoWriter來完成一個簡單的視頻編解碼過程,雖然 相比於ffmpeg叫不上專業,但是對一些簡單應用也能夠滿足要求。PSopencv提供的VideoWriter只能夠輸出avi格式,且編碼器樣式也很少,只有H264等幾種常見的。所以用opencv處理視頻確實算不上專業。

   

   2、針對視頻的算法優化

        由於是處理視頻,如果想要實時輸出結果(爲了實現連續性,幀率必須要在20fps或更高),必須要加快單幀處理速度。整個圖像去黑暗算法中最爲熬時間的步驟是求取透射率T的值。這裏主要從兩方面來優化算法:1、簡化原有算法  2、增加新的加速運算的算法。

       1)原有算法簡化

            爲了平衡速度與效果,首先把圖像去黑暗算法中關於導向濾波的算法砍掉,只使用暗原色先驗來求透射率t(x),在求解暗原色圖像的一個公式如下:


由公式可以看到 這裏面除了求取R G B三通道最小值,還有一部區域最小值濾波,爲了加速算法,這裏經過實驗省去最小值濾波步驟,直接用R G B三通道最小值作爲暗原色圖。


      2)算法加速

        因爲在時間軸上相鄰視頻幀之間是具有極大的相關性的,沒有必要去求取每一幀的透射率,所以這裏借鑑的視頻中基於塊的幀間預測編碼的相關知識。首先將視頻劃分爲多個GOP(group of picture),每個GOP有一個關鍵幀(I幀),該幀是通過暗原色圖來求取t值。而GOP的其他幀(稱爲P幀)的透射率則以關鍵幀的透射率來預測估計得到。投射率的預估準則是比較I幀和P幀對應像素點的差值,如果插值小於給定閾值 則直接沿用I幀的透射率,如果大於給定閾值,則重新計算對應位置的透射率。爲了加快這一預估速度,將每一幀又化爲爲若干個大小爲M*N(一般 M=N=16)的宏塊.計算I幀和P幀對應宏塊的SAD(Sum of Absolute Differences ).。 

        如果計算SAD時候每個宏塊的每個像素點都用到,將也是一個很大的計算量,爲了加快SAD的計算速度,對每一個宏塊進行採樣,由採樣值來計算SAD值。採樣方式如下圖所示:


   只將宏塊中標爲藍色區域的像素拿來計算SAD值。該過程被稱爲fast SAD算法。


  3、問題

       1、經過簡化後的算法,確實處理速度加快,例如 處理一張 540*360的圖像,從原來的1秒左右變爲0.06秒左右。但是這個速度是任然達不到每秒20幀的水平。PS:個人感覺已經不可以在簡化了,這裏猜測可能用純c的代碼來寫,速度纔可能有進一步提升吧。

       2、增加的加速算法沒有起到很好的加速效果,在測試過程中 一張540*360的圖像有600多個宏塊,在經過SAD過濾之後,需要重新計算投射率的宏塊平均下來,降低到200~300個,減少一半多,但是由於計算SAD也需要消耗一部分時間,最後綜合起來P幀的處理速度基本沒太大變化。


      參考文獻:

1、opencv3 讀取視頻

2、VideoCapture類

3、videoWroter類



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