在一个进程中通过队列的方式缓存opencv视频帧,并在另一个进程中读取

import _thread
import queue
import time

import cv2
from flask import Flask, Response

app = Flask(__name__)

max_size = 3
q1 = queue.Queue(maxsize=max_size)
q2 = queue.Queue(maxsize=max_size)

open_flag = 1


def open_and_show(ip_camera_url, title):
    global open_flag

    cap = cv2.VideoCapture(ip_camera_url)

    while open_flag == 1:
        ret, frame = cap.read()  # 读取视频帧
        if title == "1":
            if q1.full():
                q1.get()
            q1.put(frame)
        elif title == "2":
            if q2.full():
                q2.get()
            q2.put(frame)

    cap.release()


def gen_frames():
    # 在主函数中加入死循环,以防止程序退出

    fourcc = cv2.VideoWriter_fourcc(*"mp4v")
    out = cv2.VideoWriter(f'{int(time.time())}.mp4', fourcc, 20, (1080*2, 720))

    while True:
	#if q1.empty() or q2.empty() or q3.empty() or q4.empty():
        if q1.empty() or q2.empty():
            continue
        # 调整每个摄像头的分辨率和大小,使它们适合融合
        frame1 = q1.get()
        frame2 = q2.get()

        # 调整每个摄像头的分辨率和大小,使它们适合融合
        frame1 = cv2.resize(frame1, (1080, 720))
        frame2 = cv2.resize(frame2, (1080, 720))

        # print(frame1.shape, frame2.shape, frame3.shape,)
        # 在水平方向将三个帧连接起来

        frames = [frame1, frame2]
        combined_frame = cv2.hconcat(frames)

        out.write(combined_frame)

        # 显示融合的帧
        # cv2.imshow("Combined Frames", combined_frame)

        ret, buffer = cv2.imencode('.jpg', combined_frame)
        frame = buffer.tobytes()
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

        # 按下 'q' 键退出循环
        if cv2.waitKey(1) == ord('q'):
            break


@app.route("/")
def index():
    global open_flag

    open_flag = 0
    time.sleep(1)
    open_flag = 1
    try:
        _thread.start_new_thread(open_and_show, ("rtsp://admin:qwer1234!.@192.168.1.65:554", "1",))
        _thread.start_new_thread(open_and_show, ("rtsp://admin:qwer1234!.@192.168.1.66:554", "2",))

    except:
        print("Error: 无法启动线程")

    return Response(gen_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')


if __name__ == "__main__":
    app.run(
        port=5000,
        host="0.0.0.0"
    )

posted @ 2023-05-08 11:28  bitterteaer  阅读(159)  评论(0编辑  收藏  举报