[英]How do I stream python OpenCV output to HTML canvas?
我正在尝试使用 Flask 为我的 python OpenCV 代码制作一个 Web 界面,目的是使用画布 HTML 元素绘制“裁剪区域”以从帧流中提取细节。以下是我在此处找到的一些示例Stackoverflow 我能够将 OpenCV 代码的输出流式传输到 img 元素,但不能流式传输到画布或视频元素。 Python代码:(最小)
import cv2
from flask import Flask, render_template,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')
@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代码:
<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>
为了将来对遇到此问题的任何人的参考,尽管@furas 提供的答案按预期工作,但我发现对于我的用例,也可以使用 CSS 将输出帧分配给画布背景,从而允许显示仅视频,并在其上自由绘制。
<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>
这个带有 JavaScript 的 HTML 同时在 Canvas 和<img>
中显示流。
对于单个静态图像,它需要运行onload()
。 对于流MJPEG
它需要使用setInterval()
定期重绘图像。
它在Chrome
上对我Chrome
但我的Firefox
在Canvas
上只显示第一帧。 我想我以前遇到过这个问题。 可能它需要更多的东西才能正常工作,但我不记得是什么了。
<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>
我发现旧的信息mjpeg HTML5 视频不能与流一起传输,而且<video>
似乎不支持mjpeg
格式,因此它可能不适用于此流。
完整的工作代码。
我使用render_template_string
而不是render_template
这样每个人都可以将所有代码放在一个文件中并进行测试。
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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.