【问题标题】:Opencv recorded video is too slow and camera update is very slowopencv录制视频太慢,摄像头更新很慢
【发布时间】:2018-08-08 13:48:45
【问题描述】:

请帮助我理解为什么使用 Opencv 录制的视频如此缓慢。它不反映快速运动。 例如,如果我移动相机,则视频中的移动速度太慢。另外,虽然我在镜头前展示了一张照片大约 2 秒钟,但我并没有在录像中看到这张照片。

谁能解释一下这里发生了什么。 这是我的简单代码:

fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output2.avi',fourcc, 30.0, (640,480))

while (True):

    camera.capture(stream, use_video_port=True, format='jpeg') 
    stream.seek(0)
    imageData = np.fromstring(stream.getvalue(), dtype=np.uint8)
    npImage = cv2.imdecode(imageData, 1) 
    out.write(npImage)
    stream.close()

【问题讨论】:

  • 不确定它的作用,但你真的想要/必须使用 camera.capture(stream, use_video_port=True, format='jpeg') stream.seek(0) 和 stream.close()在循环的每次迭代中?
  • camera.capture() 是从相机获取帧的函数吗?尝试在单独的线程中捕获帧并将其放入队列中,以便在需要时随时访问。我猜这可能会对你有所帮助。
  • 感谢您的提示,您能解释一下您的想法吗?

标签: python numpy opencv video computer-vision


【解决方案1】:

我不确定这是否能解决您的问题。您可以定义一个单独的函数,从相机获取帧并将其放入队列中。您可以在单独的线程中运行此函数。有关线程的文档,请参阅此link。这加快了从相机获取帧的过程,因为 cap.read() 函数是一个阻塞函数(如果您使用 cap=cv2.VideoCapture())。

代码应该是这样的。

def getf(queue):
    cap = cv2.VideoCapture(0)    
    while(processing):
        fr = {}
        ret, a = cap.read()
        if ret:
            fr["imagecaptured"]=a
            queue.put(fr)
        else:
            #whatever you want to do when a frame is unable to be read from cam
    cap.release()

stream = threading.Thread(target=getf, args=queue)

请注意,上述代码示例中的“处理”是一个全局变量。现在,您可以定义一个函数将处理设置为 true,并使用“stream.start()”命令启动线程,或者直接将其放入程序中。

一旦线程启动,帧就会不断地放入队列中,供您在需要时阅读。使用下面的代码,你就有了框架。

if not queue.empty():
    capturedframe = queue.get()
    frame = capturedframe["imagecaptured"]

我使用这种方法从相机流式传输,同时做其他事情。参考 link 使用 pyqt 制作网络摄像头小部件。请注意,上面的代码 sn-ps 是一个示例,并不是为了运行而读取的。除了定义之外,我建议您还包括一个条件来保持检查队列大小。您现在可以修改它以用于您的应用程序,看看它是否能完成这项工作。您也可以参考此link 了解类似的示例。

【讨论】:

    【解决方案2】:

    在 python 中运行多个线程当然是一个很好的建议,但是你会发现大多数实时视频程序都是用 C++ 等编译语言编写的,可能会加入一些汇编程序/sse 印章......我赢了甚至不必费心解决 GPU 加速问题。 如果您在 python 中运行多个线程,您可能会将您的问题转换为另一种形式的“确定死亡”,因为队列将比您清空它的速度更快,并且如果视频不断流入,您最终将耗尽内存。 最好的方法是使用优化的包来获取、播放和录制视频——例如,在我在 github 上的公共项目中,我有 Dantalion,它是一个 C++ 客户端,用于处理实时采集和某些图像处理任务,例如校正和视差计算 - 它还将图像泵入 MQTT 服务器,其中 python DantalionClient 应用程序需要 TOO D**N LONG :-( 可以执行诸如搜索棋盘和计算内在和外在之类的事情。我还选择运行客户端在单独的机器上,因为 Dantalion 主机是 SoC (Beaglebone) 我强烈建议你加载你的武器库。 Python 是我最好的朋友之一,但如果我关心速度和比特流,而你不会让我做很多代数,C++ 是我的首选工具。 Python 不是简单地从 a 点到 b 点获取大量原始图像的正确工具。 不要误解我的意思——我不是在推荐我的东西——它太专业了——我只是用它作为你可能想要考虑替代语言/工具链的一个例子——它们存在是有原因的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多