使用opencv-python快速讀取視頻——進階版

前幾天做實驗的時候,用到了opencv-python讀視頻並進行檢測。

用的就是傳統的一樣的方法,cv2.VideoCapture(video_path),read()方法讀取一幀,然後再把讀到幀送入檢測器,此處貼一部分代碼上去。

import cv2

video_path = "F:/1/1.mp4"
capture = cv2.VideoCapture(video_path)

while True:
	ret, frame = capture.read()
	if not ret:
		break
	results = detector.predict(frame)
cv2.waiiKey(-1)

但是這樣存在一些問題, 在特定的應用上每幀都檢測的話,時間效率上很差。
於是我對代碼進行了一些改進,設定每秒檢測一次。

import cv2

video_path = "F:/1/1.mp4"
capture = cv2.VideoCapture(video_path)
fps = capture.get(cv2.CAP_PROP_FPS)		# 視頻的幀率FPS
total_frame = capture.get(cv2.CAP_PROP_FRAME_COUNT)	# 視頻的總幀數

for i in range(int(total_frame)):
	ret, frame = capture.read()
	if not ret:
		break
	if i % fps == 0:
		results = detector.predict(frame)
cv2.waitKey(-1)

這樣修改之後,每秒會選取一幀進行檢測,速度明顯快了許多。但是呢,自己又測試了一下,這樣大部分的時間都會浪費在讀視頻幀的過程中。
例如:我的視頻是30FPS,也就是說每30幀取出來1幀進行檢測,這就浪費了29幀的讀取時間。

還樣的方式還是太耗時,於是再次進行了一波改進:
read函數其實是grab和retrieve函數的結合
–grab函數 捕獲下一幀
–retrieve函數 對該幀進行解碼
思路就是:只捕獲,但是不解碼,對於需要的幀再進行解碼。



附上我參考的博客:
read、grab、retrieve函數詳細解釋

import cv2

video_path = "F:/1/1.mp4"
capture = cv2.VideoCapture(video_path)
fps = capture.get(cv2.CAP_PROP_FPS)		# 視頻的幀率FPS
total_frame = capture.get(cv2.CAP_PROP_FRAME_COUNT)	# 視頻的總幀數

for i in range(int(total_frame)):
	ret = capture.grab()
	if not ret:
		print("Error grabbing frame from movie!")
		break
	if i % fps == 0:
		ret, frame = capture.retrieve()
		if ret:
			results = detector.predict(frame)
		else:
			print("Error retrieving frame from movie!")
			break
cv2.waitKey(-1)

這樣,速度就更快了。

此外,還有一個方法是人爲設定讀取的幀數,利用set函數,但是在測試中,有的視頻無法讀取幀。就只簡單附在後面,供大家參考吧。

i = 100			# 人爲設定要讀取的視頻幀,從0開始計數
capture.set(cv2.CAP_PROP_POS_FRAMES, i)
ret, frame = capture.read()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章