前幾天做實驗的時候,用到了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()
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/243237.html
標籤:其他
上一篇:編碼去0的方法(C#)
下一篇:HaaS100復古街機來了!
