上位机知识篇---Flask框架实现Web服务

本文将简单介绍Web 服务与前端显示部分,它们基于Flask 框架HTML/CSS/JavaScript实现,主要负责将实时视频流和检测结果通过网页展示,并提供交互式状态监控。以下是详细技术解析:

一、Flask Web 服务架构

1. 核心路由设计
@app.route('/')
def index():
    """渲染主页面"""
    return render_template('index.html')

@app.route('/video_feed')
def video_feed():
    """提供视频流"""
    return Response(web_streamer.generate(), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/status')
def status():
    """返回JSON格式的系统状态"""
    with web_streamer.lock:
        return {
            "fps": web_streamer.fps,
            "face_count": web_streamer.face_count,
            "posture_status": web_streamer.posture_status,
            "posture_data": web_streamer.posture_data,
            "timestamp": time.time()
        }

  • / 路由

    • 使用render_template渲染静态 HTML 页面,作为用户交互入口。
    • 自动创建templates目录(若不存在),并写入硬编码的 HTML 内容(见代码末尾的模板生成逻辑)。
  • /video_feed 路由

    • 核心功能:通过Response对象生成HTTP 多部分响应multipart/x-mixed-replace),格式为连续的 JPEG 图像帧,实现实时视频流传输。
    • 数据来源:调用web_streamer.generate()方法,该方法循环输出编码后的 JPEG 帧(通过cv2.imencode生成)。
    • 性能优化:通过锁(web_streamer.lock)保证多线程环境下帧数据的一致性,避免并发访问冲突。
  • /status 路由

    • 提供 JSON 格式的系统状态数据,包括 FPS、人脸数量、姿势状态、时间统计等。
    • 前端通过定时请求(如setInterval)拉取数据,实现非阻塞式实时更新。
2. 多线程与服务启动
# 启动处理线程
process_thread = threading.Thread(target=video_processing, daemon=True)
process_thread.start()

# 启动Flask服务
app.run(host='0.0.0.0', port=5000, threaded=True, use_reloader=False)

  • 线程分工

    • video_processing线程:独立处理摄像头读取、人脸 / 姿势检测、帧更新等计算密集型任务,避免阻塞 Flask 主线程。
    • Flask 主线程:专注于处理 HTTP 请求,确保 Web 服务的响应速度。
    • daemon=True:设置为守护线程,确保程序退出时自动终止,避免资源泄漏。
  • 服务配置

    • host='0.0.0.0':监听所有网络接口,允许远程访问。
    • threaded=True:启用多线程处理请求,支持并发连接(如多个用户同时访问视频流)。
    • use_reloader=False:关闭 Flask 的自动重载机制,避免在生产环境中重复启动线程。

二、前端显示技术实现

1. HTML 结构设计
<!-- 关键结构片段 -->
<div class="status-bar">
    <!-- 状态栏:显示FPS、人脸数量、姿势状态等 -->
</div>

<div id="video-container">
    <img src="/video_feed" id="video" alt="实时监控画面">
</div>

<div class="stats">
    <!-- 统计卡片:展示姿势时间、触发次数等 -->
</div>

  • 视频流显示

    • 使用<img src="/video_feed">标签直接加载 Flask 提供的视频流接口,浏览器会自动解析多部分响应并更新图像。
    • max-width: 100%和 Flex 布局实现响应式设计,适配不同屏幕尺寸。
  • 状态监控栏

    • 通过 Flex 布局实现水平排列,包含系统状态、FPS、人脸数量、姿势状态等信息。
    • 使用颜色编码(如.good.bad类)直观区分姿势状态(绿色为良好,红色为不良)。
  • 统计卡片

    • 采用网格布局(Grid)展示关键指标(如良好 / 不良姿势时间、触发次数),提升信息可读性。
    • 大字体数值(如stat-value类)突出核心数据,便于快速浏览。
2. CSS 样式优化
/* 关键样式片段 */
body { background: #1a1a1a; color: white; }
.status-bar { background: #333; border-radius: 8px; }
.good { color: #2ecc71; } /* 绿色 */
.bad { color: #e74c3c; }  /* 红色 */
.unknown { color: #f39c12; } /* 橙色 */

  • 暗黑主题

    • 背景色采用深色调(#1a1a1a、#333),减少视觉疲劳,适合长时间监控场景。
    • 关键状态(如姿势结果)使用高对比度颜色(绿 / 红),增强信息辨识度。
  • 响应式布局

    • flexgrid布局确保在桌面、平板、手机等设备上正确显示。
    • max-width: 100%border-radius提升界面美观度和适配性。
3. JavaScript 交互逻辑
setInterval(() => {
    fetch('/status')
        .then(res => res.json())
        .then(data => {
            // 更新FPS、人脸数量等状态栏信息
            document.getElementById('fps').textContent = data.fps;
            
            // 更新姿势状态颜色
            const postureStatus = document.getElementById('posture-status');
            postureStatus.className = `status-value ${data.posture_status.toLowerCase()}`;
            
            // 更新统计卡片数据
            document.getElementById('good-time').textContent = `${data.posture_data.good_time}s`;
        })
}, 1000);

  • 实时数据拉取

    • 每秒调用fetch('/status')获取最新状态数据,通过JSON解析后更新页面元素。
    • 使用textContent而非innerHTML避免 XSS 风险,确保安全性。
  • 动态样式更新

    • 根据姿势状态(Good/Bad/Unknown)动态添加 CSS 类,改变文本颜色(如.good对应绿色)。
    • 通过className属性批量修改样式,避免重复操作 DOM 元素。
  • 视频流刷新机制

    • <img src="/video_feed">会自动处理multipart/x-mixed-replace响应,无需 JavaScript 干预,简化实现逻辑。

三、关键技术细节与优化

1. 视频流传输效率
  • JPEG 压缩

    • 通过cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 60])将视频帧压缩为 JPEG 格式,质量参数设为 60(平衡画质与文件大小)。
    • 压缩后单帧大小约为 10-20KB,适合在局域网中传输(若需公网访问,可进一步降低质量或使用 H.264 编码)。
  • 多部分响应格式

    --frame\r\n
    Content-Type: image/jpeg\r\n\r\n
    [JPEG数据块]\r\n
    --frame\r\n
    ...
    
     
    • 每个帧数据块以--frame分隔,浏览器会自动丢弃旧帧并显示最新帧,实现 “伪实时” 流(延迟约 1 秒)。
2. 线程安全与数据一致性
  • 锁机制
    • web_streamer.update_frameweb_streamer.generate中使用threading.Lock,确保同一时刻只有一个线程操作img_encoded等共享变量。
    • 避免多线程下的竞态条件(Race Condition),防止视频流出现花屏或数据错乱。
3. 模板动态生成
# 写入HTML模板
with open(os.path.join(template_dir, 'index.html'), 'w') as f:
    f.write('''
    <!-- 硬编码的HTML内容 -->
    ''')

  • 动态创建模板
    • 程序启动时自动生成templates/index.html文件,无需手动创建模板目录。
    • 适合简易场景或容器化部署(如 Docker),但生产环境中建议使用静态模板文件。

四、扩展与优化方向

1. 性能优化
  • HTTP/2 支持
    • 升级 Web 服务器(如 Nginx+Gunicorn)支持 HTTP/2,减少视频流传输的延迟和带宽占用。
  • 缓存策略
    • 对静态资源(CSS/JS)设置缓存头(Cache-Control),减少重复请求。
2. 功能扩展
  • 用户认证
    • 添加/login路由和会话管理(如 Flask-Login),确保只有授权用户可访问监控页面。
  • 历史数据存储
    • 将姿势状态、人脸识别记录存入数据库(如 SQLite/MySQL),提供历史查询和统计图表。
  • 移动端适配
    • 使用媒体查询(@media)优化移动端布局,或开发 PWA(渐进式 Web 应用)支持离线访问。
3. 协议扩展
  • RTSP 流支持
    • 集成ffmpeg将视频流转换为 RTSP 格式,适配安防监控设备(如 NVR)。
  • WebSocket 通信
    • 改用 WebSocket 实现双向通信(如实时控制硬件、发送指令),替代轮询式的/status请求。

总结

该系统的 Web 服务与前端显示部分通过Flask 的轻量级架构浏览器原生能力,实现了实时视频流展示与状态监控的高效整合。核心优势包括:

  • 低延迟:通过多线程和 HTTP 多部分响应,确保视频流接近实时(约 1 秒延迟)。
  • 易部署:无需额外依赖(除 Python 标准库外),可直接在本地或边缘设备运行。
  • 可扩展:通过路由和接口设计,方便添加用户认证、数据存储等功能。

适用于需要快速搭建实时监控界面的场景(如智能家居、小型企业安防),若需生产环境部署,建议补充安全认证、日志系统和性能监控等机制。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值