Python multithreading starts multiple cameras, and the camera thread can be suspended at the same time

Since the game needs to use 3 cameras, the program is a multi-threaded architecture, that is, the main thread opens three sub-camera threads; in the main thread (running another 3 dead loops at the same time in the main loop), this camera takes a lot of CPU resources and memory for taking pictures. In order to reduce the busyness of the CPU, it is now considered to enable a certain camera when it needs to be used, and to suspend the corresponding camera thread when not in use;

Reference blog: 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

 Improved camera thread object code:

The threading.Event() flag is used to suspend and restart the thread; for the specific code explanation, see the reference blog above.

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)

Guess you like

Origin blog.csdn.net/m0_58644391/article/details/125940652