Python 带有 RTSP 提要的 Opencv 多线程

Python Opencv Mulithreading with RTSP feeds

我正在做一个供个人使用的小项目,我想将家里的 CCTV 流加载到 Opencv 中。我做了很多研究并且明白我需要使用多线程来让它们正常工作。并使用以下代码,我让它在一台相机上完美运行!

from threading import Thread
import imutils
import cv2, time

camlink1 = "rtsp://xx.xx.xx.xx.:xxx/user=xxx&password=xxx&channel=1&stream=0./"


class VideoStreamWidget(object):
    def __init__(self, link, camname, src=0):
        self.capture = cv2.VideoCapture(link)
        # Start the thread to read frames from the video stream
        self.thread = Thread(target=self.update, args=())
        self.thread.daemon = True
        self.thread.start()
        self.camname = camname
        self.link = link
        print(camname)
        print(link)

    def update(self):
        # Read the next frame from the stream in a different thread
        while True:
            if self.capture.isOpened():
                (self.status, self.frame) = self.capture.read()
            time.sleep(.01)

    def show_frame(self):

        # Display frames in main program
        frame = imutils.resize(self.frame, width=400)
        cv2.imshow('Frame ' + self.camname, frame)
        key = cv2.waitKey(1)
        if key == ord('q'):
            self.capture.release()
            cv2.destroyAllWindows()
            exit(1)

if __name__ == '__main__':
    video_stream_widget = VideoStreamWidget(camlink1,"Cam1")

    while True:
        try:
            video_stream_widget.show_frame()
        except AttributeError:
            pass

但现在我想要 运行 另一个摄像头(并行),但我不确定我需要如何更改代码以启动另一个线程并 运行 它并排边。我想我是通过使用以下方法做到的:

from threading import Thread
import imutils
import cv2, time

camlink1 = "rtsp://xx.xx.xx.xx.:xxx/user=xxx&password=xxx&channel=1&stream=0./"
camlink2 = "rtsp://xx.xx.xx.xx.:xxx/user=xxx&password=xxx&channel=2&stream=0./"

class VideoStreamWidget(object):
    def __init__(self, link, camname, src=0):
        self.capture = cv2.VideoCapture(link)
        # Start the thread to read frames from the video stream
        self.thread = Thread(target=self.update, args=())
        self.thread.daemon = True
        self.thread.start()
        self.camname = camname
        self.link = link
        print(camname)
        print(link)

    def update(self):
        # Read the next frame from the stream in a different thread
        while True:
            if self.capture.isOpened():
                (self.status, self.frame) = self.capture.read()
            time.sleep(.01)

    def show_frame(self):

        # Display frames in main program
        frame = imutils.resize(self.frame, width=400)
        cv2.imshow('Frame ' + self.camname, frame)
        key = cv2.waitKey(1)
        if key == ord('q'):
            self.capture.release()
            cv2.destroyAllWindows()
            exit(1)

if __name__ == '__main__':
    video_stream_widget = VideoStreamWidget(camlink1,"Cam1")
    video_stream_widget = VideoStreamWidget(camlink2,"Cam2")

    while True:
        try:
            video_stream_widget.show_frame()
        except AttributeError:
            pass

但这只显示了第二个摄像头,覆盖了第一个。我知道在某个地方我遗漏了一些简单的东西,但是在看了几个小时之后我无法弄清楚。感谢任何帮助

干杯 克里斯

问题出在这些代码行中:

if __name__ == '__main__':
    video_stream_widget = VideoStreamWidget(camlink1,"Cam1")
    video_stream_widget = VideoStreamWidget(camlink2,"Cam2")

    while True:
        try:
            video_stream_widget.show_frame()
        except AttributeError:
            pass

准确地说,你覆盖了变量 video_stream_widget 然后调用一次 video_stream_widget.show_frame() 这只会在最后一次调用(即使捕获图像的线程仍在工作), 因此只会显示最后一个,即 "Cam2".


解决方案

为每个添加不同的名称并在两者上调用 show_frame() 函数,如下所示:

if __name__ == '__main__':
    video_stream_widget = VideoStreamWidget(camlink1,"Cam1")
    video_stream_widget2 = VideoStreamWidget(camlink2,"Cam2")

    while True:
        try:
            video_stream_widget.show_frame()
            video_stream_widget2.show_frame()
        except AttributeError:
            pass