将高质量相机流式传输到同一个 Raspberry Pi 4 - 线程 OpenCV

问题描述

我正在使用 OpenCV2 处理从运行 Raspbian 的 RaspBerry Pi 流式传输的图像,该图像使用来自 https://github.com/ogra1/picamera-streaming-demo/blob/master/pistream 的 python 代码进行流式传输

我使用 picamera 流而不是 OpenCV 来捕获相机,因为帧速率要高得多(1280/720 时为 24 FPS),而且我可以从网络上的任何网络浏览器查看相机。

我的线程 Python OpenCV 帧捕获和显示代码在我的本地 Windows PC 上运行良好,以极低的延迟和高帧速率显示。太棒了!

但是,在流式 RaspBerry Pi 上运行时相同的代码(使用本地 IP 地址或 127.0.0.1:8000)不会捕获任何帧。它可以打开与本地流媒体的 http 连接,但从未获得要显示的帧。

计划是在 RaspBerry Pi 上运行代码流到自身,并以相对较高的帧速率线程处理它。

相机是高质量的相机,如果有帮助的话。

关于为什么这会打开一个与自身的 http 连接然后冻结的任何想法?我试图从命令行和 pi 上的远程桌面运行它。我认为使用线程运行两个 python 程序可能是问题所在,但如何判断呢?

from threading import Thread

import numpy as np
import cv2
import time


class VideoStreamWidget(object):
    def __init__(self,src=0):
        # Create a VideoCapture object
        self.capture = cv2.VideoCapture(src)

        # Start the thread to read frames from the video stream
        self.thread = Thread(target=self.update,args=())
        self.thread.daemon = True
        self.thread.start()

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

    def get_frame(self):
        if self.status:
            return self.frame
        else:
            return np.empty((720,1280,3),dtype=np.uint8) # Show hasn't started yet

    def show_frame(self):
        # display frames in main program
        if self.status:
            #self.frame = self.maintain_aspect_ratio_resize(self.frame,width=600)
            cv2.imshow('IP Camera Video Streaming',self.frame)

        # Press Q on keyboard to stop recording
        key = cv2.waitKey(1)
        if key == ord('q'):
            self.capture.release()
            cv2.destroyAllWindows()
            exit(1)

    # Resizes a image and maintains aspect ratio
    def maintain_aspect_ratio_resize(self,image,width=None,height=None,inter=cv2.INTER_AREA):
        # Grab the image size and initialize dimensions
        dim = None
        (h,w) = image.shape[:2]

        # Return original image if no need to resize
        if width is None and height is None:
            return image

        # We are resizing height if width is none
        if width is None:
            # Calculate the ratio of the height and construct the dimensions
            r = height / float(h)
            dim = (int(w * r),height)
        # We are resizing width if height is none
        else:
            # Calculate the ratio of the 0idth and construct the dimensions
            r = width / float(w)
            dim = (width,int(h * r))

        # Return the resized image
        return cv2.resize(image,dim,interpolation=inter)

if __name__ == '__main__':
    stream_link = 'http://127.0.0.1:8000/stream.mjpg'
    #stream_link = 'http://192.168.1.29:8000/stream.mjpg'
    video_stream_widget = VideoStreamWidget(stream_link)
    current_frame = np.empty((720,dtype=np.uint8)

    def similar(frame1,frame2):
        return (frame1.shape == frame2.shape and not (np.bitwise_xor(frame2,frame1).any()))

    start_time = time.time()
    frame_count = 0

    while True:
        try:
            #video_stream_widget.show_frame()
            time.sleep(.01)
            new_frame = video_stream_widget.get_frame()
            print (new_frame.shape)
            if not similar(current_frame,new_frame):
                cv2.imshow("Video Input",new_frame)
                current_frame = new_frame
                current_time = time.time()
                seconds = current_time - start_time
                frame_count += 1
                if seconds > 0:
                    fps = frame_count / seconds
                else:
                    fps = 0
                print("FPS: {}".format(fps))
                key = cv2.waitKey(1)
                if key == ord('q'):
                    cv2.destroyAllWindows()
                    exit(1)
        except AttributeError:
            pass

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)