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

本文介绍了一种改进的摄像头线程设计,通过threading.Event()实现线程的暂停与恢复,旨在降低CPU资源占用,仅在需要时开启对应摄像头,提高程序效率。作者通过实例展示了如何在Python中使用Event对象来管理摄像头线程的生命周期。
摘要由CSDN通过智能技术生成

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

只待花开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值