視頻關鍵幀抽取終結篇——關鍵幀是什麼?

在之前的博文中都拋出了問題,而沒有解決,這裏做最後的解決!!!

視頻關鍵幀分爲I幀,P幀,B幀,這裏介紹下區別,也是我搜索得到的,僅供參考。

I幀纔是關鍵幀,P,B算不上關鍵幀。

I幀是幀內壓縮編碼得到的,通常是每個GOP組的第一幀/基礎幀,在一組中只有一個I幀,I幀所佔信息量大,解碼時僅有I幀即可完整重構圖像,所以才叫關鍵幀。

P幀與B幀是幀間壓縮,P幀沒有完整圖像數據,只有與前一幀的差別信息,因此也叫預測幀,B幀則是考慮前後幀的差別(故而也叫雙向預測幀),因此B幀解碼時間最長,壓縮比最大。

參考上面博文,又找到了一個方法,感謝幫助我的大佬。cv2解碼,當然其他解碼也可,我看看是否結果一樣。

我看了下,這個方法是找到關鍵幀的index,然後再次讀視頻(耗時問題也算差強人意吧),我在上面博文中也提及了。

下面是用ffprobe得到的幀:以baby.mp4爲例

'pict_type=I\r\npict_type=P\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=P\r\npict_type=I\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\npict_type=B\r\npict_type=P\r\n'

可見,I,P,B幀都有。這樣就得到了index。

cv2中獲取指定index的幀,與cv2.CAP_PROP_POS_FRAMES有關,後來得到cv2保存的圖片比直接用ffmpeg的內存大,圖像是一樣的。可以認爲無差別吧。我試試另一個解碼器,看看耗時上有沒有差別,仍舊以baby.mp4(1.1M)和baby2.mp4(1.4M),較大的視頻vLaugh199.mp4 (19M)爲例。

比較方法是隻讀取數據,鑑於圖像解碼可能有差別,恢復的圖像大小不一樣,所以第一步,先保存爲圖,如果圖像一樣的話,那麼只看讀取數據的時間。

中間遇到一個問題,讓我矇蔽了,cv2指定的某個index得到的frame爲空,這就尷尬了。

因爲下面的ret爲False,其實這就說明cv2的解碼與ffmpeg是不一樣的,加個判斷,避免報錯。

ret, frame = cap.read()

cv2解碼得到的關鍵幀只有15個,而ffmpeg有16個,儘管後者得到圖有些小,質量可能不清晰。

整體上相差不大,可以忽略這個15還是16的問題吧。

其中又遇到了一個問題,另一個解碼器得到的圖到底是什麼格式?RGB or BGR ?我直接用imwrite保存得到的圖反而沒有錯??

鑑於此,又新開一個博文。等待官方答覆中。。

下面進入正文:測試解碼時間,其實我絕對就是看PyDecoder的耗時,因爲這個我之前測試過,的確比較快一點。

【PyDecoder採用GPU時可能會出現問題,卡死,我有點矇蔽】

time: 24.900450 PyDecoder

time: 4.887592   cv2  可見有index時抽幀還是cv2快

中間又遇到一個問題,用time.clock()計算時間得到的結果不對(可能是版本問題,有提示升級了,反正啥幺蛾子都有,奇怪的問題不糾結,能避免就好),於是換成了time.time()

DeprecationWarning: time.clock has been deprecated in Python 3.3 and will be removed from Python 3.8: use time.perf_counter or time.process_time instead
  start=time.clock()



>>> start=time.clock()
>>> end=time.clock()
>>> end-start

#服務器上這種計算方法出現問題

另外有相關問題可以加入QQ羣討論,不設微信羣

QQ羣:868373192 

語音圖像視頻深度-學習羣

 

 

 

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