在队列中发送和接收图像,用于 Flask 中的视频流,高延迟。蟒蛇

问题描述 投票:0回答:1

我正在开发基于机器学习的应用程序的演示器。

为了简单起见,我们假设:

我正在使用两个文件,run_ml.py 和 video_stream_flask.py。

run_ml.py 文件基本上从相机捕获图像,进行所有处理,并在原始图像上绘制内容。然后,最终图像放入队列中。

此队列与其他参数一起传递给运行 video_stream_flask.py 的 main() 的子进程。

这里的目标是从队列中获取图像,并将其显示在网页上。事实上,最初的目标只是能够在网页上显示最终的图像。

这基本上是 video_stream_flask.py 的代码:

import subprocess
from subprocess import PIPE
from flask import Flask, Response, render_template
import cv2
import multiprocessing
import logging

VERBOSE_DEBUG = 0

if not VERBOSE_DEBUG:
    log = logging.getLogger('werkzeug')
    log.setLevel(logging.ERROR)

TARGET = None
queue=multiprocessing.Queue()
global image
image=cv2.imread("output.jpg")

def get_queue(queue):
    try:
        data = queue.get(block=False)
        print("Data retrieved from queue")
        return data
    except Exception as e:
        # print("except : ",e)
        # print("Queue is empty, no data to retrieve.")
        return None

def get_current_ip():
    """
  Get current IP Address by testing IP route
  """
    process_get_ip = subprocess.Popen(["ip route get 1.2.3.4 | awk '{print $7}'"], shell=True, stdout=PIPE)
    output = process_get_ip.communicate()[0].decode("utf-8")
    return output


app = Flask(__name__)



@app.route('/')
def index():
    return render_template("index.html")


def gen():
    while True:
        global image
        global queue
        # image = cv2.imread("output.jpg")
        image=get_queue(queue)
        if image is not None:
            image = cv2.flip(image, 1)
            ret, jpeg = cv2.imencode('.jpg', image)
            frame = jpeg.tobytes()
            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
            print("Frame sent")


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


def main(lan, target,QUEUE):
    global TARGET
    TARGET = target
    global queue
    queue=QUEUE
    
    if bool(lan):
        subprocess.Popen(["ifconfig eth0 10.0.0.20 netmask 255.255.255.0 up"], shell=True, stdout=PIPE)
        print("\nCONNECT TO : 10.0.0.20:5000")
        app.run(host="10.0.0.20", port=5000, threaded=True)
    else:
        if TARGET:
            ip_address = get_current_ip()[:-2]
            print("\nCONNECT TO : " + repr(ip_address)[1:-1] + ":5000")
            app.run(host=ip_address, port=5000, threaded=True)
        else:
            print("\nCONNECT TO : localhost:5000")
            app.run(host="localhost", port=5000, threaded=True) #, use_reloader=False

我面临的问题是延迟。在我的网页上查看结果时,我立即遇到了近十秒的延迟。

我不明白为什么。

我正在运行一个基本示例,其中图像是从相机捕获的,直接在同一文件和同一进程中,并且它运行完美。

但是在这里,当我尝试从主进程中检索图像时,它会滞后。

我尝试了其他方法,例如将图像保存在文件系统中并再次读取它,使用互斥体来确保不存在冲突。

当我运行我的应用程序时,我可以在输出中看到图像一旦准备好就生成了:

Data retrieved from queue
Frame sent

Model Inference time: 926.544ms
Data put into queue successfully.

Data retrieved from queue
Frame sent

Model Inference time: 923.772ms
Data put into queue successfully.

Data retrieved from queue
Frame sent

Model Inference time: 914.210ms
Data put into queue successfully.

Data retrieved from queue
Frame sent

您知道问题出在哪里吗?或者如何做我想做的事情,这意味着如何流式传输在另一个脚本中生成的图像,并在准备好时仅流式传输一次?

非常感谢,

python flask multiprocessing queue
1个回答
0
投票

我意识到问题不是来自flask,而是来自OpenCV捕获。

有关根本原因的说明可在此处找到:由于捕获缓冲区导致 OpenCV VideoCapture 滞后

© www.soinside.com 2019 - 2024. All rights reserved.