当前位置: 首页 > news >正文

【全栈AI开发1.0】基于 FastAPI + WebSocket + YOLOv8 的实时视频检测与统计系统

一、引言

在智能安防、新零售、工业质检等领域,实时目标检测与数据记录是不可或缺的基础能力。然而,传统方案往往存在开发成本高、部署复杂、数据难以可视化等问题。为此,我设计并实现了一个轻量级、开箱即用的实时视频检测系统,具备以下特点:

  • 🎥实时检测与标注:基于 YOLOv8,对摄像头每一帧进行推理,并用彩色方框标出物体类别与置信度。

  • 📊动态统计面板:网页右侧实时显示当前画面中各类目标的数量。

  • 💾Excel 自动记录:每隔 1 秒将检测统计数据写入 Excel,且支持动态添加新类别列(如画面首次出现“car”,表格自动新增该列)。

  • 🌐WebSocket 低延迟推送:前端通过 WebSocket 接收 base64 编码的视频帧,实现流畅播放。

  • 🚀一键启动与优雅退出:运行脚本自动打开 Chrome 浏览器;关闭所有网页后,后端自动停止服务并释放资源。

  • 🧩模块化前端:HTML、CSS、JavaScript 分离,便于维护和定制。

本文将从系统架构、关键代码实现、运行效果、部署方式等方面进行详细分享,并提供完整的项目源码。

二、技术栈

层级技术
后端框架FastAPI + Uvicorn (ASGI 服务器)
目标检测Ultralytics YOLOv8 (yolov8n.pt)
图像处理OpenCV
实时通信WebSocket
数据存储OpenPyXL(Excel 写入,支持动态列扩展)
前端HTML/CSS/JavaScript (原生)
浏览器控制subprocess + threading (自动打开)

三、系统架构

下图展示了整个系统的数据流与模块关系:

  • 后端:FastAPI 提供 REST API 用于启动/停止检测,同时提供 WebSocket 端点。

  • 前端:连接 WebSocket,接收 JSON 消息并更新<img>标签的src属性,同时渲染统计列表。

  • 数据持久化:全局变量latest_stats保存最新一帧的检测结果,log_stats_periodically每 1 秒将其写入 Excel,并自动处理新出现的类别

四、关键代码实现(核心片段)

4.1 摄像头采集(camera.py)

import cv2 class Camera: def __init__(self, source=0): self.source = source # 0 代表本地摄像头,也可以是 RTSP 地址 self.cap = None def open(self): self.cap = cv2.VideoCapture(self.source) return self.cap.isOpened() def read_frame(self): if self.cap and self.cap.isOpened(): ret, frame = self.cap.read() return frame if ret else None def release(self): if self.cap: self.cap.release()

4.2 YOLO 检测器(detector.py)

from ultralytics import YOLO from collections import Counter class YOLODetector: def __init__(self, model_path='./model/yolov8n.pt', conf=0.5): self.model = YOLO(model_path) self.conf = conf def detect(self, frame): if frame is None: return None, {} results = self.model(frame, conf=self.conf) if results[0].boxes is not None: cls_ids = results[0].boxes.cls.cpu().numpy().astype(int) names = [results[0].names[i] for i in cls_ids] stats = dict(Counter(names)) else: stats = {} annotated_frame = results[0].plot() # 自动绘制边界框和标签 return annotated_frame, stats

4.3 WebSocket 连接管理器(websocket_manager.py)

class ConnectionManager: def __init__(self): self.active_connections = set() self.on_empty = None # 回调:所有连接断开时触发 async def connect(self, websocket): await websocket.accept() self.active_connections.add(websocket) def disconnect(self, websocket): self.active_connections.discard(websocket) if not self.active_connections and self.on_empty: self.on_empty() # 触发关闭服务器 async def broadcast(self, message): for conn in self.active_connections.copy(): try: await conn.send_text(message) except: self.disconnect(conn)

4.4 视频处理主循环(app.py 核心)

async def video_processing_loop(): global is_running, latest_stats while is_running: frame = camera.read_frame() if frame is None: await asyncio.sleep(0.1) continue annotated_frame, stats = detector.detect(frame) async with stats_lock: latest_stats = stats # 供定时写入任务使用 _, buffer = cv2.imencode('.jpg', annotated_frame, [cv2.IMWRITE_JPEG_QUALITY, 80]) b64_image = base64.b64encode(buffer).decode() await manager.broadcast(json.dumps({ "type": "frame", "image": b64_image, "stats": stats })) await asyncio.sleep(0.033) # 约 30 fps

4.5 动态 Excel 写入(app.py)

async def log_stats_periodically(): try: while is_running: await asyncio.sleep(1) stats = latest_stats.copy() if not stats: continue wb = load_workbook(excel_file_path) ws = wb.active headers = [cell.value for cell in ws[1]] # 找出新类别 new_cats = [c for c in stats.keys() if c not in headers[1:]] for cat in new_cats: ws.cell(row=1, column=ws.max_column+1, value=cat) wb.save(excel_file_path) # 重新加载以获取最新表头 wb = load_workbook(excel_file_path) ws = wb.active headers = [cell.value for cell in ws[1]] row = [datetime.now().strftime("%Y-%m-%d %H:%M:%S")] for cat in headers[1:]: row.append(stats.get(cat, 0)) ws.append(row) wb.save(excel_file_path) except asyncio.CancelledError: print("表格写入任务已取消,不再写入新数据") raise

4.6 前端模块化(HTML + CSS + JS)

index.html(仅结构,引用外部资源):

<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="/static/style.css"> <title>YOLOv8 智能检测系统</title> </head> <body> <div class="container"> ...(视频区、统计面板等) </div> <script src="/static/script.js"></script> </body> </html>

script.js(WebSocket 连接与消息处理):

ws.onmessage = function(event) { const data = JSON.parse(event.data); if (data.type === 'frame') { document.getElementById('videoFeed').src = `data:image/jpeg;base64,${data.image}`; let html = ''; for (const [obj, cnt] of Object.entries(data.stats)) { html += `<div class="stat-item"><span>${obj}</span><span>${cnt}</span></div>`; } document.getElementById('statsList').innerHTML = html; } };

五、运行效果

5.1 终端启动日志

INFO: Started server process [51988] INFO: Waiting for application startup. ✓ YOLO模型加载成功: ./model/yolov8n.pt ✓ 摄像头初始化完成 ✓ YOLO模型加载完成 INFO: Application startup complete. INFO: Uvicorn running on http:myip (Press CTRL+C to quit) 🌐 使用默认浏览器打开: http:myip INFO: ('127.0.0.1', 34007) - "WebSocket /ws" [accepted] INFO: connection open ✓ Excel日志文件已创建: work\20260501_121356.xlsx ✓ 检测已启动,Excel记录已开启 INFO: 127.0.0.1:9109 - "POST /start HTTP/1.1" 200 OK

5.2 浏览器界面截图

5.3 Excel 文件内容示例

六、总结

本文完整地介绍了一个基于 FastAPI、WebSocket 和 YOLOv8 的实时目标检测系统。从架构设计、代码实现到部署运行,每个环节都力求简洁明了。系统不仅具备实时检测、动态统计、Excel 自动记录等实用功能,还实现了自动打开浏览器、关闭网页自动退出等用户体验优化。所有代码均可直接运行,适合作为 AI 视觉项目的基础原型或教学案例。

如果您觉得有帮助,欢迎给个 Star ⭐!

http://www.jsqmd.com/news/740581/

相关文章:

  • 告别麦克风水流声!实测Realtek R2.83驱动噪音抑制效果,附官方文件校验指南
  • 别再傻傻分不清!一张图看懂802.1、802.3、802.11到底管啥(附思维导图)
  • 【C语言物联网加密实战指南】:3种超轻量级算法(ChaCha20-Poly1305、TinyAES、XOR-PRNG)在8KB内存设备上的零依赖实现
  • 别再手动轮询了!用STM32G473的DMA+ADC实现高效数据采集(附CubeMX配置截图)
  • Claude Code 安全吗?代码隐私保护注意事项
  • 快速原型开发中如何利用 Taotoken 多模型能力进行方案选型
  • TI CC2642R1开发环境配置避坑大全:从syscfg图形化到OpenOCD调试的那些‘坑’
  • AI视频生成中的角色一致性与视觉质量优化
  • 使用 UniApp 来开发手持 PDA 的数据录入应用
  • AI抢内存致存储芯片半年涨340%,手机电脑下半年或迎普涨!
  • 3步解锁Switch控制器:JoyCon-Driver的Windows适配终极指南
  • 保姆级教程:在STM32平台上通过SPI驱动NXP TJA1145收发器(附代码片段)
  • PAJ7620手势模块避坑指南:从I2C通信失败到识别不稳定的5个常见问题
  • 文化差异如何重塑AI语言理解能力
  • STEMPHONIC框架:AI音乐生成的多轨同步技术
  • OpenAI 2028 年将量产自研 AI 手机,能否重定义人机交互?
  • 构建魔兽世界私服Web门户:TrinityCore现代化前端部署与安全实践
  • 告别‘so库找不到’:用Android Studio的APK Analyzer一键诊断libc++_shared.so缺失问题
  • 3步解锁Cyber Engine Tweaks:从安装到高效游戏优化的完整指南
  • AI Agent平台技术选型:OpenClaw与Hermes Agent深度对比
  • VS Code配置C/C++环境时,90%新手都会踩的坑(tasks.json路径、多文件编译、第三方库)
  • 华为交换机SSH远程登录保姆级配置教程(含AAA认证与密钥生成)
  • 长期使用中感受到的聚合 API 服务稳定性与技术支持体验
  • 中断响应延迟飙升?内存屏障失效?嵌入式C多核任务调度配置错误导致系统崩塌,立即排查这7个关键点
  • 跨平台流媒体下载利器:N_m3u8DL-RE深度解析与实战指南
  • 深入对比:RK3576的ISP和VPSS图像处理管线,如何榨干这颗芯片的视觉性能?
  • 面向文物仓库的巡检机器人电子标签【附代码】
  • 从一次线上故障复盘讲起:DMZ 配置不当,如何让你的 FTP 服务器成为内网“后门”?
  • AI模型自然语言理解能力的核心影响因素
  • LTX2.3-EditAnything - 用提示词轻松改视频:加物、删物、换物、换风格 一句话搞定 一键整合包下载