是否可以并行读取网络摄像头帧?
Is it possible to read webcam frames in parallel?
我有一个简单的 Python script that captures a webcam using OpenCV. My webcam has the potential to stream 30 FPS, but since my Raspberry Pi 不够强大,我只能读取 ~ 20 FPS。当 运行 运行脚本时,我的 CPU 的一个核心被最大化到 100%,但其余核心未受影响,所以我试图将阅读分成尽可能多的线程为了发挥我的 CPU 的最大潜力并轻松达到 30 FPS。
那么是否可以并行读取网络摄像头帧?
这是我的尝试:
import numpy as np
import cv2
import time
from threading import Thread
CV_CAP_PROP_FPS = 5
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output.avi', fourcc, cap.get(CV_CAP_PROP_FPS), (640, 480))
threads = []
class MyThread(Thread):
def run(self):
ret, frame = cap.read()
if __name__ == '__main__':
try:
while(cap.isOpened()):
thread = MyThread()
thread.start()
threads.append(thread)
time.sleep(0.035)
except KeyboardInterrupt:
for thread in threads:
thread.join()
cap.release()
out.release()
当 运行 运行这个脚本时,我在我的终端中得到几个 VIDIOC_QBUF: Invalid argument
(通常是 4 次)。睡眠值越大,我得到的错误信息就越少。因此,例如,如果我 time.sleep(0.1)
,我可能会收到 2-3 条错误消息,而不是 4 条。
这是有问题的,因为在我的脚本的第二部分(未在此处发布)中生成的最终视频文件已损坏。此错误仅在并行读取网络摄像头提要时发生。依次执行所有内容时,视频文件很好,我可以毫无问题地阅读它。
非常感谢任何见解。干杯!
编辑:
我认为同样重要的是要注意 VIDIOC_QBUF: Invalid argument
错误消息是在读取前几帧之后发生的。例如,我可以启动我的脚本,这几乎会立即触发这些错误,但随后我的脚本可以 运行 正常 "infinite" 一段时间而没有任何错误消息。
在启动大量线程之前等待第一帧被完全读取时,VIDIOC_QBUF: Invalid argument
消失了!
...
try:
ret, frame = cap.read()
while(cap.isOpened()):
thread = MyThread()
thread.start()
threads.append(thread)
time.sleep(0.035)
...
请注意,即使所有 CPU 个内核都用于此算法,我能够达到的最大 FPS 是 24。
我有一个简单的 Python script that captures a webcam using OpenCV. My webcam has the potential to stream 30 FPS, but since my Raspberry Pi 不够强大,我只能读取 ~ 20 FPS。当 运行 运行脚本时,我的 CPU 的一个核心被最大化到 100%,但其余核心未受影响,所以我试图将阅读分成尽可能多的线程为了发挥我的 CPU 的最大潜力并轻松达到 30 FPS。
那么是否可以并行读取网络摄像头帧?
这是我的尝试:
import numpy as np
import cv2
import time
from threading import Thread
CV_CAP_PROP_FPS = 5
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output.avi', fourcc, cap.get(CV_CAP_PROP_FPS), (640, 480))
threads = []
class MyThread(Thread):
def run(self):
ret, frame = cap.read()
if __name__ == '__main__':
try:
while(cap.isOpened()):
thread = MyThread()
thread.start()
threads.append(thread)
time.sleep(0.035)
except KeyboardInterrupt:
for thread in threads:
thread.join()
cap.release()
out.release()
当 运行 运行这个脚本时,我在我的终端中得到几个 VIDIOC_QBUF: Invalid argument
(通常是 4 次)。睡眠值越大,我得到的错误信息就越少。因此,例如,如果我 time.sleep(0.1)
,我可能会收到 2-3 条错误消息,而不是 4 条。
这是有问题的,因为在我的脚本的第二部分(未在此处发布)中生成的最终视频文件已损坏。此错误仅在并行读取网络摄像头提要时发生。依次执行所有内容时,视频文件很好,我可以毫无问题地阅读它。
非常感谢任何见解。干杯!
编辑:
我认为同样重要的是要注意 VIDIOC_QBUF: Invalid argument
错误消息是在读取前几帧之后发生的。例如,我可以启动我的脚本,这几乎会立即触发这些错误,但随后我的脚本可以 运行 正常 "infinite" 一段时间而没有任何错误消息。
在启动大量线程之前等待第一帧被完全读取时,VIDIOC_QBUF: Invalid argument
消失了!
...
try:
ret, frame = cap.read()
while(cap.isOpened()):
thread = MyThread()
thread.start()
threads.append(thread)
time.sleep(0.035)
...
请注意,即使所有 CPU 个内核都用于此算法,我能够达到的最大 FPS 是 24。