admin 管理员组

文章数量: 1087709

使用opencv

前几天做实验的时候,用到了opencv-python读视频并进行检测。

用的就是传统的一样的方法,cv2.VideoCapture(video_path),read()方法读取一帧,然后再把读到帧送入检测器,此处贴一部分代码上去。

import cv2video_path = "F:/1/1.mp4"
capture = cv2.VideoCapture(video_path)while True:ret, frame = capture.read()if not ret:breakresults = detector.predict(frame)
cv2.waiiKey(-1)

但是这样存在一些问题, 在特定的应用上每帧都检测的话,时间效率上很差。
于是我对代码进行了一些改进,设定每秒检测一次。

import cv2video_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:breakif i % fps == 0:results = detector.predict(frame)
cv2.waitKey(-1)

这样修改之后,每秒会选取一帧进行检测,速度明显快了许多。但是呢,自己又测试了一下,这样大部分的时间都会浪费在读视频帧的过程中。
例如:我的视频是30FPS,也就是说每30帧取出来1帧进行检测,这就浪费了29帧的读取时间。

还样的方式还是太耗时,于是再次进行了一波改进:
read函数其实是grab和retrieve函数的结合
–grab函数 捕获下一帧
–retrieve函数 对该帧进行解码
思路就是:只捕获,但是不解码,对于需要的帧再进行解码。

附上我参考的博客:
read、grab、retrieve函数详细解释

import cv2video_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!")breakif 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()

本文标签: 使用opencv