一、外!路由函数外的前后端数据传输
Flask后端
↓
首先导入包,需要使用
- 后端:flask_socketio来进行路由外的数据传输,
from flask_socketio import SocketIO, emit
- 前端:还有HTML头文件的设置。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<link rel="stylesheet" type="text/css" href="/static/css/cljc.css">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
↓
下面是一个函数演示,注意socketio.emit调用。
def generate_frames():
frame_Num = 1 #用于记录第几幅图像(即第几帧),初始为1(即第一幅)
max_cars = 0
video_path = './static/Videos/视频1.mp4'
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS) #获取视频文件的帧速率
carsCascade = cv2.CascadeClassifier("car_rear.xml") ##检测算法
while cap.isOpened():
success, frame = cap.read()
if not success:
break
cv2.putText(frame,"second:"+str(round(frame_Num/fps,2))+"s",
(0,100),cv2.FONT_HERSHEY_SIMPLEX,1,(255,0,255),1)
cars = carsCascade.detectMultiScale(frame[700:1280,0:720], 1.2,minSize=(10,10)) # 识别出所有汽车
car_number = len(cars)
max_cars = max(car_number,max_cars)
# 获取当前北京时间
beijing_time = datetime.now(timezone('Asia/Shanghai')).strftime('%Y-%m-%d %H:%M:%S')
# 在每次更新数据后,通过SocketIO发送数据到前端
if car_number > 6:
waringInfo = "车辆过多注意减速!"
socketio.emit('update_data', {'max_cars': max_cars, 'car_number': car_number, 'frame_Num': frame_Num, "safetyWarning": waringInfo, "timeShow": beijing_time})
else:
waringInfo = "未告警!"
socketio.emit('update_data', {'max_cars': max_cars, 'car_number': car_number, 'frame_Num': frame_Num, "safetyWarning": waringInfo, "timeShow": beijing_time})
↓
传输变量信息、
socketio.emit('update_data', {'max_cars': max_cars, 'car_number': car_number, 'frame_Num': frame_Num, "safetyWarning": waringInfo, "timeShow": beijing_time})
↓
需要注意的是JavaScript,处data.变量需要和上边一一对应的同时,getElementById又需要和<body>里面的<input>id名字一一对应。便可以实现:后端信息->JavaScript中转->前端展示.
<script src="https://cdn.socket.io/4.0.1/socket.io.min.js"></script>
<script>
var socket = io();
socket.on('update_data', function(data) {
document.getElementById('frameNumber').value = data.frame_Num;
document.getElementById('vehicleNumber').value = data.car_number;
document.getElementById('peakTraffic').value = data.max_cars;
document.getElementById('timeShow').value = data.timeShow;
document.getElementById('safetyWarning').value = data.safetyWarning;
});
</script>
以第一个
document.getElementById('frameNumber').value = data.frame_Num;
举例子,
- data.frame_Num就是上面的socketio.emit中传输的frame_Num。
- document.getElementById('frameNumber')就是下面<input>中的id。
<div class="col2">
<div class="BoxConTop">当前帧数</div>
<input type="text" id="frameNumber" name="frameNumber" readonly style="margin-top: -100px;">
<div class="BoxConTop">当前车辆数</div>
<input type="text" id="vehicleNumber" name="vehicleNumber" readonly style="margin-top: -100px;">
<div class="BoxConTop">车流量峰值</div>
<input type="text" id="peakTraffic" name="peakTraffic" readonly style="margin-top: -100px;">
</div>
<div class="col3">
<p>北京时间</p>
<input type="text" id="timeShow" name="timeWarning" readonly>
<p>安全预警栏</p>
<input type="text" id="safetyWarning" name="safetyWarning" readonly>
</div>
↓
如此便可以实现图片实时传输,显示
二、内!路由函数内的前后端数据传输
@app.route('/cpsb', methods=['GET', 'POST'])
def cpsb():
c = CardPredictor()
c.train_svm()
if request.method == 'POST':
file = request.files['image']
image = cv2.imdecode(np.frombuffer(file.read(), np.uint8), cv2.IMREAD_COLOR)
r, roi, color = c.predict(image)
r = "".join(r)
print(r,color)
return jsonify({'plate_number': r, 'plate_color': color})
else:
# 对于GET请 求,只需渲染模板即可
r = '待上传'
color = '待上传'
return render_template('cpsb.html', plate_number=r, plate_color=color)
使用render_template进行数据传输,非常简单同样的一一对应:
- 后端render_template中的plate_number = r 对应前端html中的 value = "{{ plate_number }}"
- 后端中render_template中的plate_color = color 对应前段html中的 value = "{{ plate_color }}"
<div class="htmlpage-cell">
<input type="text" value="{{ plate_color }}"/></div>
</div>
<div id="iafrm" class="htmlpage-cell c29697">
<input type="text" value="{{ plate_number }}"/>
</div>