我们可以将Flask流式响应与OpenCV FPS同步吗

2024-09-24 00:21:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个模块,使用Flask将OpenCV框架流式传输到web服务器。当我在本地测试脚本时,OpenCV的帧速率和flask响应是同步的

当我在云服务器中部署脚本时,问题开始出现。OpenCV FPS和烧瓶响应速率不同步。因此,我失去了一些帧之间

在调试代码一段时间后,我发现如果我将图像大小减小到1280*720,flask会在1秒后响应。如果,我将大小减小到640*360,响应率增加。但它仍然不同步。我试图将FPS限制为12,但无法使其同步

是否有任何方法可以使flask响应与OpenCV帧速率同步,使用图像大小1280*720和FPS 12-15

import cv2
import time
import threading
from flask import Flask, Response

app = Flask(__name__)

@app.route("/")
def index():
    """Video streaming home page."""
    return "Hello World"


def run_video():
    # grab global references to the video stream, output frame, and
    # lock variables
    global cap, outputFrame, lock
    total = 0
    fpsLimit = 0.8  # Restricting the FPS.
    startTime = time.time()
    # loop over frames from the video stream
    while True:
        cap = cv2.VideoCapture('input_video/camera_1.mp4')
        while (cap.isOpened()):
            nowTime = time.time()
            if (nowTime - startTime) > fpsLimit:
                ret, img = cap.read()
                print("FPS rate : ", int(1 / (nowTime - startTime)))
                startTime = time.time()
                if ret == True:
                    total += 1
                    with lock:
                        outputFrame = img.copy()


def generate():
    global outputFrame, lock, prev_response_time
    while True:
        with lock:
            if outputFrame is None:
                continue
            (flag, encodedImage) = cv2.imencode(".jpg", outputFrame)
            # ensure the frame was successfully encoded
            if not flag:
                continue
        
        current_time = time.time()
        response_time = current_time - prev_response_time
        print("display_response_time", int(1 / (response_time)))
        prev_response_time = current_time
        
        # yield the output frame in the byte format
        yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' +
               bytearray(encodedImage) + b'\r\n')


@app.route("/video_feed")
def video_feed():
    return Response(generate(),
                    mimetype="multipart/x-mixed-replace; boundary=frame")


# check to see if this is the main thread of execution
lock = threading.Lock()
prev_response_time = 0
if __name__ == '__main__':
    thread = threading.Thread(target=run_video)
    thread.daemon = True
    thread.start()
    # start the flask app
    app.run(host='0.0.0.0', threaded=True, port=5000)
# release the video stream pointer
# cap.stop()

Tags: theimporttruelockappflaskiftime