对于我的项目,我想为 opencv VideoCapture 创建一个子类,它看起来像这样:
import cv2
class VideoOperator(cv2.VideoCapture):
def __init__(self, video_path):
super().__init__(video_path)
self.current_frame_index = 0
self.last_frame_index = int(self.get(cv2.CAP_PROP_FRAME_COUNT) - 1)
def move_to_frame(self, frame_index):
if frame_index > self.last_frame_index:
self.set(cv2.CAP_PROP_POS_FRAMES, self.last_frame_index)
self.current_frame_index = self.last_frame_index
elif frame_index < 0:
self.set(cv2.CAP_PROP_POS_FRAMES, 0)
self.current_frame_index = 0
else:
self.set(cv2.CAP_PROP_POS_FRAMES, frame_index)
self.current_frame_index = frame_index
def move_x_frames(self, x):
self.move_to_frame(self.current_frame_index + x)
def get_current_frame(self):
_, image = self.read()
self.move_to_frame(self.current_frame_index)
return image
然后我使用 unittest 编写了一些测试。因为我想要我的子类的新实例,所以我决定在 setUp()
函数中创建它。测试(不完整)如下所示:
import unittest, time
import video_operator
class TestVideoOperator(unittest.TestCase):
def setUp(self):
self.vid_op = video_operator.VideoOperator(r'E:\PythonProjects\video_cutter\vid1.mp4')
def tearDown(self):
self.vid_op.release()
def test_init(self):
self.assertEqual(self.vid_op.current_frame_index, 0)
self.assertEqual(self.vid_op.last_frame_index, 430653)
def test_move_to_existing_frame(self):
self.vid_op.move_to_frame(100)
self.assertEqual(self.vid_op.current_frame_index, 100)
def test_move_to_negative_frame(self):
self.vid_op.move_to_frame(-100)
self.assertEqual(self.vid_op.current_frame_index, 0)
def test_move_to_non_existing_frame(self):
self.vid_op.move_to_frame(self.vid_op.last_frame_index + 100)
self.assertEqual(self.vid_op.current_frame_index, self.vid_op.last_frame_index)
if __name__ == '__main__':
unittest.main()
但即使有 4 个测试,也只执行了 1 个,并且它总是以有关某些退出代码的信息结束,例如:
当我只是将 vid_op 定义为类字段而不是尝试在每次测试开始时对其进行初始化时,一切正常。是否不可能创建 VideoCapture 类的多个实例,即使我在创建另一个实例之前释放了每个实例?或者是其他地方的问题?
最佳答案
您是否给了 VideoCapture 足够的时间进行初始化? 我正在使用 cv2 并行读取 16 个 RTSP 摄像机。初始化需要将近/超过 1 分钟。 在我的例子中,我不能使用 VideoCapture.read() 因为它需要处理太多的工作。我正在处理一些帧并通过在高速循环中运行 cap.grab() 来抓取一些帧,我打算展示的帧我使用 cap.retrieve() 这样我只解码我感兴趣的帧并增加应用性能。例如。要以 3FPS 为基础显示 30FPS 相机的相机,您应该以 10 帧的间隔拍摄 1 帧。 另一点要提到的是,Linux 已经证明可以比 Windows 10 更好地处理这些 VideoCapture 对象。 即使是 Raspberry pi 也可以在初始化几分钟后并行运行多个 VideoCaptures。 希望这些信息有所帮助。
https://stackoverflow.com/questions/54334552/
相关文章:
python - Tensorflow-gpu获取卷积算法失败
asp.net - 为什么要用 aspnet_regiis.exe 加密
java - 如何通过本地主机将 SSL 与 ActiveMQ 一起使用
pytorch - 如何将 .txt 文件(语料库)读入 pytorch 中的 torchtext?
unit-testing - 如何在 Xcode 中为 Apple Watch 添加单元测试?
java - 如何在 Micronaut 中使用@Parameter?
user-interface - 在 Tkinter GUI 中嵌入 Bokeh 和大数据