# 将图像转换为bytes,以便通过HTTP传输
ret, buffer = cv2.imencode(
'
.jpg
'
, gray)
frame
=
buffer.tobytes()
# 发送帧
yield
(b
'
--frame\r\n
'
b
'
Content-Type: image/jpeg\r\n\r\n
'
+ frame + b
'
\r\n
'
)
cap.release()
@app.route(
'
/video_feed
'
)
def video_feed():
return
Response(gen_frames(), mimetype=
'
multipart/x-mixed-replace; boundary=frame
'
)
if
__name__ ==
'
__main__
'
:
app.run(debug
=False, threaded=True)
接着创建一个html文件,叫做
index.html
,并创建一个
templates
文件夹,将html文件放在此文件夹中,因为这是Flask默认的模板文件夹
<!DOCTYPE html>
<title>实时摄像头画面</title>
</head>
<h1>实时摄像头画面</h1>
<img src="{{ url_for('video_feed') }}" alt="Video Feed" />
</body>
</html>
最后运行Flask应用程序
python app.py
下面是它们是如何交互和结合在一起的详细说明:
Python代码
1.
导入Flask模块和OpenCV库:
from flask import Flask, render_template, Response
import cv2
这里导入了Flask Web框架和OpenCV图像处理库。
2.
创建Flask应用实例:
app = Flask(__name__)
创建一个Flask应用实例。
3.
定义路由和视图函数:
@app.route('/')
def index():
return render_template('index.html')
定义了一个根路由/,当访问此路由时,会渲染并返回index.html页面。
4.
生成视频帧的函数:
def gen_frames():
# ...
gen_frames函数用于从摄像头捕获视频帧,将其转换为灰度图像,并编码为JPEG格式,然后作为字节流yield出来。
5.
视频流路由:
@app.route('/video_feed')
def video_feed():
return Response(gen_frames(),
mimetype='multipart/x-mixed-replace; boundary=frame')
定义了一个/video_feed路由,返回一个实时视频流。视频流通过Response对象发送,其中mimetype设置为multipart/x-mixed-replace,这允许浏览器接收到连续的视频帧。
6.
运行Flask应用:
if __name__ == '__main__':
app.run(debug=False, threaded=True)
如果直接运行此脚本,则启动Flask服务器。
HTML代码 (前端)
1.
页面元数据和样式:
<meta charset=
"
UTF-8
"
>
<title>实时灰度摄像头画面</title>
<style>
#videoFeed {
width: 640px;
height: 480px;
</style>
</head>
设置页面的字符编码为UTF-8,定义网页标题,并在<style>标签内定义了视频显示区域的宽度和高度。
2.
页面内容:
<h1>实时灰度摄像头画面</h1>
<img id=
"
videoFeed
"
src=
""
onerror=
"
this.src='{{ url_for('video_feed') }}'
"
>
<script>
//
...
</script>
</body>
<body>标签包含页面的主要内容。<h1>标签显示页面标题。<img>标签用于显示视频流,其id为videoFeed,初始src为空,当加载失败时,会通过onerror事件设置其src为视频流URL。
3.
JavaScript定时刷新图像:
<script>
setInterval(function(){
document.getElementById('videoFeed').src = '{{ url_for("video_feed") }}';
}, 100);
</script>
<script>标签内定义了一个JavaScript定时器,每100毫秒刷新一次图像元素的src属性,指向视频流URL。
当用户访问根URL(
/
)时,Flask应用渲染并返回
index.html
页面。
index.html
页面中的
<img>
元素通过
onerror
事件和JavaScript定时器尝试加载视频流。
Flask应用中的
/video_feed
路由响应这些请求,提供实时的视频帧作为JPEG图像流。
用户的浏览器接收到这些帧,并在页面上显示为连续的视频流。