从具身智能到工业视觉:打造全链路工业机器人视觉管控平台
一、背景:一个"不对口"的仓库
今天接到一个工业机器人视觉主题的比赛任务。比赛要求开发一套完整的可视化 Web 应用系统,覆盖数据集管理、数据增强、模型训练、推理部署、结果可视化全链路功能。
翻看 GitCode 仓库,发现有一个现成的 cloudrobo-embodied-ai 项目——之前参加 CloudRobo 具身智能比赛的,基于 LeRobot 框架的 ACT(Action Chunking with Transformers)模型,用于机器人模仿学习动作策略。
乍看似乎沾边,但仔细对照比赛要求后发现问题很大:
| 比赛要求 | 现有项目 | 差距 |
|---|---|---|
| 可视化 Web 应用系统 | 纯 Python CLI 工具 | 无前端 |
| 数据集管理(导入/划分/统计) | 仅有 data_loader.py | 无管理界面 |
| 数据增强(≥3种+实时预览) | 完全没有 | 从零开始 |
| 模型训练(参数配置+指标可视化) | 有 train 但无 UI | 缺可视化 |
| 推理部署(一键推理+图片上传) | 有 evaluate 评测脚本 | 非推理服务 |
| 结果可视化(检测框+导出) | matplotlib 绘图 | 非 Web 可视化 |
结论:5 个必做模块基本全部缺失,赛道也从"机器人动作控制"偏到了"工业视觉检测"。但原有代码的数据加载和可视化思路可以复用。
决定:保留原有代码作为参考,在同一个仓库上重构为全新架构。
二、技术选型
后端:FastAPI + YOLOv8 + OpenCV
选择 FastAPI 而非 Flask/Django,原因:
- 原生支持异步,训练任务可以后台线程运行不阻塞 API
- 自动生成 OpenAPI 文档,调试方便
- 文件上传用
UploadFile非常简洁
模型选 YOLOv8(Ultralytics):
- 工业视觉主流选择,目标检测性能强
- API 简洁,
model.train()一行启动训练 - 内置回调机制,可以 hook 训练过程实时采集指标
- 预训练模型
yolov8n.pt开箱即用
前端:Vue 3 + Element Plus + ECharts
- Element Plus 组件丰富,表单/表格/对话框/上传组件全覆盖
- ECharts 画统计图表和训练曲线,比 Chart.js 更适合中文场景
- Vite 构建极快,10 秒打包完成
存储:SQLite + 本地文件
比赛项目不需要重型数据库,SQLite 零配置、单文件,足够存储数据集元数据。
三、架构设计
┌─────────────────────────────────────────────────┐
│ 前端 (Vue 3 + Element Plus) │
│ ECharts 可视化 + Axios 请求层 │
├─────────────────────────────────────────────────┤
│ API 层 (FastAPI + Uvicorn) │
│ /api/dataset /api/augmentation │
│ /api/training /api/inference │
├─────────────────────────────────────────────────┤
│ 核心引擎层 │
│ YOLOv8 (Ultralytics) + OpenCV + Pillow │
├─────────────────────────────────────────────────┤
│ 存储层 │
│ SQLite (元数据) + 本地文件 (图片/模型) │
└─────────────────────────────────────────────────┘
项目结构:
cloudrobo-embodied-ai/
├── backend/
│ ├── main.py # FastAPI 入口
│ ├── config.py # 全局配置
│ ├── api/ # 4 个路由模块
│ │ ├── dataset.py # 数据集管理
│ │ ├── augmentation.py # 数据增强
│ │ ├── training.py # 模型训练
│ │ └── inference.py # 推理部署
│ └── core/legacy/ # 保留的原有 LeRobot 代码
├── frontend/
│ └── src/views/ # 5 个页面
│ ├── Dashboard.vue
│ ├── DatasetManagement.vue
│ ├── DataAugmentation.vue
│ ├── ModelTraining.vue
│ └── InferenceDeployment.vue
└── README.md
四、逐模块实现
4.1 数据集管理模块
后端 用 SQLite 存三张表:datasets(数据集)、categories(类别)、samples(样本)。
核心 API:
POST /api/dataset/create— 上传图片创建数据集,自动读取图片尺寸POST /api/dataset/{id}/split— 按比例随机划分训练/验证集GET /api/dataset/{id}/statistics— 返回划分分布、类别分布、尺寸统计
前端 用 ECharts 画饼图展示训练/验证集比例,柱状图展示类别分布。el-upload 组件处理拖拽上传。
一个细节:图片尺寸用 Pillow 的 Image.open() 读取,比 OpenCV 更轻量。
4.2 数据增强模块
比赛要求至少 3 种增强方式,我实现了 7 种,覆盖工业场景常见需求:
| 增强方式 | 核心实现 | 工业场景用途 |
|---|---|---|
| 亮度调节 | HSV 空间 V 通道缩放 | 模拟不同光照环境 |
| 高斯噪声 | np.random.normal 叠加 |
传感器噪声模拟 |
| 随机裁剪 | 随机偏移裁剪区域 | 目标位置偏移增强 |
| 仿射变换 | cv2.getRotationMatrix2D |
多角度多尺度检测 |
| 形态学处理 | 开运算+闭运算 | 表面反光抑制、去噪点 |
| 高斯模糊 | cv2.GaussianBlur |
运动模糊模拟 |
| CLAHE 均衡 | cv2.createCLAHE |
低对比度图像增强 |
前端支持多选增强方式、参数滑块调节、原图与增强结果并排对比预览。所有图片用 base64 编码通过 JSON 返回,避免临时文件管理。
4.3 模型训练模块
这是最核心的模块。关键设计:
异步训练:用 threading.Thread 在后台运行 YOLOv8 训练,主线程不阻塞。前端通过轮询 GET /api/training/status 每 2 秒获取进度。
指标采集:利用 Ultralytics 的回调机制:
def on_fit_epoch_end(trainer):
record = {
"epoch": trainer.epoch + 1,
"loss": float(trainer.loss),
"precision": float(trainer.metrics["metrics/precision(B)"]),
"mAP50": float(trainer.metrics["metrics/mAP50(B)"]),
...
}
TRAINING_STATUS["metrics_history"].append(record)
model.add_callback("on_fit_epoch_end", on_fit_epoch_end)
每个 epoch 结束时自动采集 Loss、Precision、Recall、mAP50、mAP50-95 五项指标,存入全局状态字典。前端用 ECharts 画 5 条折线图实时展示训练曲线。
4.4 推理部署模块
一键启停:POST /api/inference/start 加载 YOLOv8 模型到内存,后续请求直接用内存中的模型推理,避免重复加载。
检测结果可视化:后端用 OpenCV 在图片上绘制检测框、类别标签、置信度,编码为 base64 返回。前端直接 <img> 展示,无需 Canvas 绘制。
def _draw_results(img, results):
for box in results[0].boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0].tolist())
cv2.rectangle(img, (x1, y1), (x2, y2), color, 2)
label = f"{cls_name} {conf:.2f}"
cv2.putText(img, label, ...)
return img
结果导出:支持 JSON 和 CSV 两种格式,用 StreamingResponse 流式返回,浏览器直接触发下载。
4.5 前端 Dashboard
首页用渐变卡片展示 4 个功能模块入口,el-timeline 展示技术架构层级,el-steps 展示功能流程。整体风格简洁专业。
五、开发过程中的踩坑记录
2. Git 作者身份
git commit 报 Author identity unknown,新环境需要先配置:
git config user.email "lightyears@gitcode.com"
git config user.name "lightyears"
3. 前端构建 chunk 过大
Vite 构建时警告 index-Bb6yjXMn.js 超过 500KB——这是 ECharts 全量打包导致的。对于比赛项目可以接受,生产环境可以按需引入 ECharts 模块优化。
4. OpenCV headless 版本
requirements.txt 用 opencv-python-headless 而非 opencv-python,避免服务器环境无 GUI 时安装失败。
六、最终成果
代码统计
- 35 个文件变更,4158 行新增,796 行删除
- 后端 4 个 API 模块,约 1200 行 Python
- 前端 5 个页面 + 布局 + 路由 + API 封装,约 800 行 Vue/JS
- 前端构建产物:CSS 361KB + JS 约 2.3MB(gzip 后约 750KB)
比赛要求覆盖情况
| 必做功能 | 状态 | 亮点 |
|---|---|---|
| 数据集管理 | ✅ | 支持上传+文件夹导入,ECharts 饼图+柱状图统计 |
| 数据增强 | ✅ | 7 种增强方式(超出要求的 3 种),多方式对比预览 |
| 模型训练 | ✅ | YOLOv8 异步训练,5 项指标实时曲线 |
| 推理部署 | ✅ | 一键启停,单张+批量检测 |
| 结果可视化 | ✅ | 检测框标注+详情表格+JSON/CSV 导出 |
打包下载
项目已打包上传至华为云 OBS,下载链接:
https://cloudrobo-download-1787477182.obs.cn-north-4.myhuaweicloud.com/cloudrobo-embodied-ai.tar.gz
七、总结与思考
这个项目最大的挑战不在于单个技术点,而在于全链路打通——从数据导入到最终检测结果导出,每一步都要前后端联动、数据格式对齐。
几个关键决策点:
- 保留原有代码而非全新仓库——尊重历史工作,
backend/core/legacy/保留了 LeRobot ACT 代码 - base64 传图而非临时 URL——简化文件管理,代价是 JSON 响应体较大
- 线程异步训练而非 Celery——比赛项目不需要分布式任务队列,threading 足够
- SQLite 而非 PostgreSQL——零配置,单文件,部署友好
如果后续要进一步优化,可以考虑:
- 前端 ECharts 按需引入减小包体积
- 训练任务用 WebSocket 推送指标替代轮询
- 增加 YOLOv8-seg 分割模型支持
- 添加用户权限管理和多模型对比功能
- 点赞
- 收藏
- 关注作者
评论(0)