使用 OpevCV VideoWriter 实时录制视频
recording video in real-time with OpevCV VideoWriter
我有几个通过 USB 分析视频的 OpenCV 项目,在某些情况下必须将视频流记录到文件中。使用我的软件的人抱怨说,10 分钟以上的录音产生的视频文件比应有的时间长了大约 20 秒。
我正在使用 openCV 的 VideoWriter。我试过将 CV2_CAP_PROP_FPS 设置为非常低的设置,我试过在几秒钟内获得平均帧速率,以便为我的输出文件的帧速率找到一个好的设置。仍然不够接近实时满足我的需求。
有谁知道确保我的视频录制接近实时的好方法吗?我应该使用 time.sleep(在 python 中)之类的东西来限制我的帧率吗?或者有更好的方法吗?
我写了一个实时跟踪器(用于神经生物学研究),我将其与许多网络摄像头一起使用,并注意到我的一些摄像头并没有非常精确地遵守帧速率;它们可能有点快或慢。为了保存 "reasonably correct" 个视频,从网络摄像头捕获帧的代码调用了我的 VideoWriter
的 write(frame)
方法,该方法将帧放入队列中,然后通过单独的 "writer" 以恒定速率写入帧的线程。如果编写器线程在要写入下一帧时发现队列为空,则它会重复上一帧。如果写入线程在队列中发现不止一帧,它会写入最新的一帧并丢弃其他帧。 (可以在没有单独线程的情况下实现这一点,但对于实时跟踪器来说,快速 write(frame)
return 是很好的。)
以下是我的代码摘录。他们将 而不是 运行 逐字逐句地显示我刚才描述的内容。 (我计划在接下来的几周内将实时跟踪器放在 GitHub 上。)
class VideoWriter:
def __init__(self, fn=None, fcc='MJPG', fps=7.5):
...
self.fcc, self.fps, self.dt = fcc, fps, 1./fps
self.q, self._stop, self.n = Queue.Queue(), False, 0
self.wrtr = threading.Thread(target=self._writer)
self.wrtr.start()
def _writer(self):
frm = firstTime = vw = None
while True:
if self._stop:
break
# get most recent frame
while not self.q.empty():
frm = self.q.get_nowait()
if frm is not None:
if vw is None:
vw = cv2.VideoWriter(self.fn+self._EXT, cvFourcc(self.fcc),
self.fps, imgSize(frm), isColor=numChannels(frm)>1)
firstTime = time.time()
vw.write(frm)
self.n += 1
dt = self.dt if firstTime is None else max(0,
firstTime + self.n*self.dt - time.time())
time.sleep(dt)
# write frame; can be called at rate different from fps
def write(self, frm):
self.q.put(frm)
我有几个通过 USB 分析视频的 OpenCV 项目,在某些情况下必须将视频流记录到文件中。使用我的软件的人抱怨说,10 分钟以上的录音产生的视频文件比应有的时间长了大约 20 秒。
我正在使用 openCV 的 VideoWriter。我试过将 CV2_CAP_PROP_FPS 设置为非常低的设置,我试过在几秒钟内获得平均帧速率,以便为我的输出文件的帧速率找到一个好的设置。仍然不够接近实时满足我的需求。
有谁知道确保我的视频录制接近实时的好方法吗?我应该使用 time.sleep(在 python 中)之类的东西来限制我的帧率吗?或者有更好的方法吗?
我写了一个实时跟踪器(用于神经生物学研究),我将其与许多网络摄像头一起使用,并注意到我的一些摄像头并没有非常精确地遵守帧速率;它们可能有点快或慢。为了保存 "reasonably correct" 个视频,从网络摄像头捕获帧的代码调用了我的 VideoWriter
的 write(frame)
方法,该方法将帧放入队列中,然后通过单独的 "writer" 以恒定速率写入帧的线程。如果编写器线程在要写入下一帧时发现队列为空,则它会重复上一帧。如果写入线程在队列中发现不止一帧,它会写入最新的一帧并丢弃其他帧。 (可以在没有单独线程的情况下实现这一点,但对于实时跟踪器来说,快速 write(frame)
return 是很好的。)
以下是我的代码摘录。他们将 而不是 运行 逐字逐句地显示我刚才描述的内容。 (我计划在接下来的几周内将实时跟踪器放在 GitHub 上。)
class VideoWriter:
def __init__(self, fn=None, fcc='MJPG', fps=7.5):
...
self.fcc, self.fps, self.dt = fcc, fps, 1./fps
self.q, self._stop, self.n = Queue.Queue(), False, 0
self.wrtr = threading.Thread(target=self._writer)
self.wrtr.start()
def _writer(self):
frm = firstTime = vw = None
while True:
if self._stop:
break
# get most recent frame
while not self.q.empty():
frm = self.q.get_nowait()
if frm is not None:
if vw is None:
vw = cv2.VideoWriter(self.fn+self._EXT, cvFourcc(self.fcc),
self.fps, imgSize(frm), isColor=numChannels(frm)>1)
firstTime = time.time()
vw.write(frm)
self.n += 1
dt = self.dt if firstTime is None else max(0,
firstTime + self.n*self.dt - time.time())
time.sleep(dt)
# write frame; can be called at rate different from fps
def write(self, frm):
self.q.put(frm)