请帮助我理解为什么使用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()
答案 0 :(得分:0)
我不确定这是否能解决您的问题。您可以定义一个单独的函数,从相机中获取帧并将其放入队列中。您可以在单独的线程中运行此函数。有关线程的文档,请参阅此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制作网络摄像头小部件。请注意,上面的代码片段仅作为示例,不会被读取运行。除了定义,我建议你还包括一个条件来检查队列大小。您现在可以修改它以用于您的应用程序,看看它是否能完成这项工作。您也可以参考此link获取类似示例。
答案 1 :(得分:0)
在python中运行多个线程当然是一个很好的建议,但你会发现大多数实时视频程序都是用C ++等编译语言编写的,可能还有一些汇编器/ sse chops .....我赢了甚至无法解决GPU加速问题。 如果你在python中运行多个线程,你可能会将你的问题转换为一种不同形式的特定死亡,因为队列填充的速度比你清空它的时间要快,如果视频保持流式传输,你最终会耗尽内存。 最好的方法是使用优化的包来获取,广播和录制视频 - 例如,在我在github上的公共项目中,我有Dantalion,它是一个C ++客户端,处理实时采集和某些图像处理任务,如整改和差异计算 - 它还将图像泵入MQTT服务器,其中python DantalionClient应用程序需要TOO D ** N LONG :-(可以执行诸如搜索棋盘和计算内在函数和外部函数之类的东西。我还选择运行客户端在一台单独的机器上,因为Dantalion主机是一个SoC(Beaglebone) 我强烈建议你加载你的武器库。 Python是我最好的朋友之一,但如果我关心速度和位流,你不会让我做很多代数,C ++是我的首选工具。 Python不是简单地从a点到b点获取大量原始图像的正确工具。 不要误会我的意思 - 我不推荐我的东西 - 它太专业了 - 我只是用它作为你为什么要考虑替代语言/工具链的一个例子 - 这是他们存在的原因。