Javascript 如何将python OpenCV输出流式传输到HTML画布?

Javascript 如何将python OpenCV输出流式传输到HTML画布?,javascript,python,html,opencv,flask,Javascript,Python,Html,Opencv,Flask,我正在尝试使用Flask为我的python OpenCV代码创建一个web界面,目的是使用canvas HTML元素绘制一个“裁剪区域”,以从帧流中提取细节。下面是我在Stackoverflow上找到的一些示例,我能够将OpenCV代码的输出流到img元素,但不适用于画布或视频元素。 Python代码:(最小) HTML代码: <html> <head> <title>Video Streaming </title> </head&g

我正在尝试使用Flask为我的python OpenCV代码创建一个web界面,目的是使用canvas HTML元素绘制一个“裁剪区域”,以从帧流中提取细节。下面是我在Stackoverflow上找到的一些示例,我能够将OpenCV代码的输出流到img元素,但不适用于画布或视频元素。 Python代码:(最小)

HTML代码:

<html>
<head>
    <title>Video Streaming </title>
</head>
<body>
    <div>
        <h1>Live Video Streaming </h1>
        <img id="img" src = "{{ url_for('video_feed') }}">
    </div>
</body>
</html>

视频流
实时视频流

此带有JavaScript的HTML同时在画布上和
中显示流

对于单个静态映像,它需要运行
onload()
。对于流
MJPEG
,它需要使用
setInterval()
定期重画图像

它在
Chrome
上对我有效,但我的
Firefox
只在
画布上显示第一帧。我想我以前有过这个问题。也许它需要更多的东西才能正常工作,但我不记得是什么了


对于以后遇到这个问题的任何人,尽管@furas提供的答案按预期工作,但我发现对于我的用例,也可以使用CSS将输出帧分配到画布背景,只允许显示视频,并在其上自由绘制

HTML代码

视频流
.我的画布{
背景图片:url({{url\u for('video\u feed')}});
}
实时视频流

为此,您必须学习JavaScript。此问题表明,它可能不支持
mjpeg
格式,因此这将不适用于
谢谢您的回答,简单明了!
<html>
<head>
    <title>Video Streaming </title>
</head>
<body>
    <div>
        <h1>Live Video Streaming </h1>
        <img id="img" src = "{{ url_for('video_feed') }}">
    </div>
</body>
</html>
<html>
<head>
    <title>Video Streaming </title>
</head>
<body>

    <div width="640px" height="480px" style="display:inline-block">
        <h1>Image</h1>
        <img id="img" src="{{ url_for('video_feed') }}">
    </div>

    <div width="640px" height="480px" style="display:inline-block">
        <h1>Canvas</h1>
        <canvas id="canvas" width="640px" height="480px"></canvas>
    </div>

<script >

    var ctx = document.getElementById("canvas").getContext('2d');
    var img = new Image();
    img.src = "{{ url_for('video_feed') }}";

    // need only for static image
    //img.onload = function(){   
    //    ctx.drawImage(img, 0, 0);
    //};

    // need only for animated image
    function refreshCanvas(){
        ctx.drawImage(img, 0, 0);
    };
    window.setInterval("refreshCanvas()", 50);

</script>

</body>
</html>
import cv2
from flask import Flask, render_template, render_template_string, Response

app = Flask(__name__)
video_capture = cv2.VideoCapture(0)

def gen():    
    while True:
        ret, image = video_capture.read()
        cv2.imwrite('t.jpg', image)
        yield (b'--frame\r\n'
           b'Content-Type: image/jpeg\r\n\r\n' + open('t.jpg', 'rb').read() + b'\r\n')
    video_capture.release()


@app.route('/')
def index():
    """Video streaming"""
    #return render_template('index.html')
    return render_template_string('''<html>
<head>
    <title>Video Streaming </title>
</head>
<body>
    <div>
        <h1>Image</h1>
        <img id="img" src="{{ url_for('video_feed') }}">
    </div>
    <div>
        <h1>Canvas</h1>
        <canvas id="canvas" width="640px" height="480px"></canvas>
    </div>

<script >
    var ctx = document.getElementById("canvas").getContext('2d');
    var img = new Image();
    img.src = "{{ url_for('video_feed') }}";

    // need only for static image
    //img.onload = function(){   
    //    ctx.drawImage(img, 0, 0);
    //};

    // need only for animated image
    function refreshCanvas(){
        ctx.drawImage(img, 0, 0);
    };
    window.setInterval("refreshCanvas()", 50);

</script>

</body>
</html>''')

@app.route('/video_feed')
def video_feed():
    """Video streaming route. Put this in the src attribute of an img tag."""
    return Response(gen(),
                mimetype='multipart/x-mixed-replace; boundary=frame')


if __name__ == '__main__':
    app.run()
<html>
<head>
    <title>Video Streaming </title>
</head>
<style>
    .myCanvas{
       background-image: url("{{ url_for('video_feed') }}"); 
    }
</style>
<body>
    <div>
        <h1>Live Video Streaming </h1>
        <img id="img" src = "{{ url_for('video_feed') }}">
        <canvas class="myCanvas" height="600" width="480">
    </div>
</body>
</html>