python 多线程启动多个摄像头,同时可以暂停摄像头线程

由于比赛需要用到3个摄像头,程序是多线程架构,即主线程开三个子摄像头线程;在主线程(主循环内同时跑另外3个死循环),这样摄像头拍照非常吃cpu资源与内存,为了降低cpu的繁忙性,现考虑在需要使用某摄像头的时候开启,不使用的时候将对应摄像头线程暂停;

参考博客:https://blog.csdn.net/weixin_38650871/article/details/117625651?ops_request_misc=&request_id=&biz_id=102&utm_term=python%20threading%E6%9A%82%E5%81%9C%E7%BA%BF%E7%A8%8B&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-5-117625651.142^v33^pc_rank_34,185^v2^control&spm=1018.2226.3001.4187

 改进的摄像头线程对象代码:

由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)

猜你喜欢

转载自blog.csdn.net/m0_58644391/article/details/125940652