由于比赛需要用到3个摄像头,程序是多线程架构,即主线程开三个子摄像头线程;在主线程(主循环内同时跑另外3个死循环),这样摄像头拍照非常吃cpu为了减少资源和内存cpu忙碌,现在考虑在需要使用摄像头时打开,不使用时暂停相应的摄像头线程;
相机线程对象代码的改进:
由threading.Event()此标志位暂停并重新启动线程;具体代码解释见上述参考博客。
import cv2 import threading import time class Camera: def __init__(self, src=0, shape=[640, 480]): self.__flag = threading.Event() self.__flag.set() # 设置为True # 用于停止线程的标识 self.__running = threading.Event() self.__running.set() # 将running设置为True self.src = src self.stream = cv2.VideoCapture(src) # self.stream.release() if self.stream.isOpened(): self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, 640) self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) else: self.stream = cv2.VideoCapture(self.src 1) self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, 640) self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # self.stream.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter::fourcc('M', 'J', 'P', 'G')); # self.stream.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('Y', 'U', 'Y', 'V')); self.stopped = False for _ in range(20): # warm up the camera (self.grabbed, self.frame) = self.stream.read() def start(self): threading.Thread(target=self.update, args=()).start() def update(self): count = 0 while self.__running.isSet(): if self.stream.isOpened(): self.__flag.wait() # 为True立即返回, 为False阻塞直到内部标志位置为True后返回 if self.stopped: return (self.grabbed, self.frame) = self.stream.read() else: self.__flag.wait() # 为True立即返回, 为False阻塞直到内部标志位置为True后返回 print("The video{} is not open!!".format(self.src)) self.stream = cv2.VideoCapture(self.src 1) self.stream.set(cv2.CAP_PROP_FRAME_WIDTH, 640) self.stream.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) def read(self): return self.frame def pause(self): self.__flag.clear() # 设置为False, 让线程阻塞 def resume(self): self.__flag.set() # 设置为True, 阻止线程 def stop(self): # self.__flag.set() # 将线程从暂停状态恢复, 若已暂停 self.__running.clear() # 设置为False self.stream.release() self.stopped = True time.sleep(0.1) if __name__ == "__main__": camera = Camera(0) camera1 = Camera(1) camera2 = Camera(2) camera.start() camera1.start() camera2.start() start = end = time.time() begin = endd = False try: while True: end = time.time() img = camera.read() img1 = camera1.read() img2 = camera2.read() if end - start > 10 and begin == False: camera.pause() begin = True if end - start > 20 and endd == False: endd = True camera.resume() finally: camera.stop() camera1.stop() camera2.stop() # cv2.imshow("img", img) # cv2.waitKey(1)