由于比赛需要用到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)