在线程之间共享相机帧
Sharing camera frames between threads
我正在尝试构建一个脚本来管理本应 运行 并行的多个线程,并在它们之间交换数据。
作为起点,我有两个线程......第一个应该从 USB 相机读取帧并将它们发送到队列,而第二个应该读取它们并显示它们。
我试过了:
import json
import queue, threading
from queue import Queue
import cv2
class system_manager():
def __init__(self, source):
## camera reader
self.camera_queue = queue.Queue()
self.camera_reader = threading.Thread(target=camera_reader, args=(source, self.camera_queue))
self.camera_reader.daemon = True
self.camera_reader.run()
self.camera_display = threading.Thread(target=camera_display, args=(self.camera_queue))
self.camera_display.daemon = True
self.camera_display.run()
def camera_reader(source, camera_queue):
print("Cam Loading...")
cap = cv2.VideoCapture(source)
print("Cam Loaded...")
while(True):
ret, frame = cap.read()
camera_queue.put(frame)
def camera_display(camera_queue):
print("doing something")
while(True):
frame = camera_queue.get()
key = cv2.waitKey(1)
if (key == ord('q')):
break
cv2.imshow("frame", frame)
if __name__ == "__main__":
SM = system_manager(source=0)
但这并没有真正起作用。第一个线程,应该读取帧的线程,实际上正在这样做,但第二个线程没有显示任何内容(开头有一个打印语句,但没有显示)。另外,在 运行 几分钟后,我的电脑完全卡住了,所以我假设我不小心连续占用了内存。
我是 multiprocessing/multithreading 的新手,所以我可能在某个地方犯了一些非常基本的错误。
编辑
好的,使用以下方法解决了内存问题:
self.camera_queue = queue.Queue(maxsize=5)
但是第二个线程还没有工作
使用 thread.start() 代替 thread.run() ,修复线程目标方法并在参数后添加逗号。这行得通。
import json
import queue, threading
from queue import Queue
import cv2
class system_manager():
def __init__(self, source):
## camera reader
self.camera_queue = queue.Queue(maxsize=5)
self.camera_reader = threading.Thread(target=camera_reader, args=(source, self.camera_queue))
self.camera_reader.daemon = True
self.camera_reader.start()
self.camera_display = threading.Thread(target=camera_display, args=(self.camera_queue,))
self.camera_display.daemon = True
self.camera_display.start()
def camera_reader(source, camera_queue):
print("Cam Loading...")
cap = cv2.VideoCapture(source)
print("Cam Loaded...")
while(True):
ret, frame = cap.read()
camera_queue.put(frame)
def camera_display(camera_queue):
print("doing something")
while(True):
frame = camera_queue.get()
key = cv2.waitKey(1)
if (key == ord('q')):
break
cv2.imshow("frame", frame)
if __name__ == "__main__":
SM = system_manager(source=0)
我正在尝试构建一个脚本来管理本应 运行 并行的多个线程,并在它们之间交换数据。 作为起点,我有两个线程......第一个应该从 USB 相机读取帧并将它们发送到队列,而第二个应该读取它们并显示它们。
我试过了:
import json
import queue, threading
from queue import Queue
import cv2
class system_manager():
def __init__(self, source):
## camera reader
self.camera_queue = queue.Queue()
self.camera_reader = threading.Thread(target=camera_reader, args=(source, self.camera_queue))
self.camera_reader.daemon = True
self.camera_reader.run()
self.camera_display = threading.Thread(target=camera_display, args=(self.camera_queue))
self.camera_display.daemon = True
self.camera_display.run()
def camera_reader(source, camera_queue):
print("Cam Loading...")
cap = cv2.VideoCapture(source)
print("Cam Loaded...")
while(True):
ret, frame = cap.read()
camera_queue.put(frame)
def camera_display(camera_queue):
print("doing something")
while(True):
frame = camera_queue.get()
key = cv2.waitKey(1)
if (key == ord('q')):
break
cv2.imshow("frame", frame)
if __name__ == "__main__":
SM = system_manager(source=0)
但这并没有真正起作用。第一个线程,应该读取帧的线程,实际上正在这样做,但第二个线程没有显示任何内容(开头有一个打印语句,但没有显示)。另外,在 运行 几分钟后,我的电脑完全卡住了,所以我假设我不小心连续占用了内存。 我是 multiprocessing/multithreading 的新手,所以我可能在某个地方犯了一些非常基本的错误。
编辑 好的,使用以下方法解决了内存问题:
self.camera_queue = queue.Queue(maxsize=5)
但是第二个线程还没有工作
使用 thread.start() 代替 thread.run() ,修复线程目标方法并在参数后添加逗号。这行得通。
import json
import queue, threading
from queue import Queue
import cv2
class system_manager():
def __init__(self, source):
## camera reader
self.camera_queue = queue.Queue(maxsize=5)
self.camera_reader = threading.Thread(target=camera_reader, args=(source, self.camera_queue))
self.camera_reader.daemon = True
self.camera_reader.start()
self.camera_display = threading.Thread(target=camera_display, args=(self.camera_queue,))
self.camera_display.daemon = True
self.camera_display.start()
def camera_reader(source, camera_queue):
print("Cam Loading...")
cap = cv2.VideoCapture(source)
print("Cam Loaded...")
while(True):
ret, frame = cap.read()
camera_queue.put(frame)
def camera_display(camera_queue):
print("doing something")
while(True):
frame = camera_queue.get()
key = cv2.waitKey(1)
if (key == ord('q')):
break
cv2.imshow("frame", frame)
if __name__ == "__main__":
SM = system_manager(source=0)