在之前的博文中都拋出了問題,而沒有解決,這裏做最後的解決!!!
視頻關鍵幀分爲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
語音圖像視頻深度-學習羣