基于 ResNet34 的混凝土坍落度智能预测系统
基于 ResNet的混凝土坍落度智能预测系统
基于 ResNet34 的混凝土坍落度智能预测系统(前后端分离架构)
项目地址:https://github.com/crazyjack44/Concrete_Slump_Test_System
一、项目背景
在混凝土生产和施工过程中,坍落度(Slump)是衡量混凝土工作性最关键的指标之一。传统坍落度测试依赖人工现场操作,耗时耗力,且结果受人为因素影响较大。随着深度学习和工业视觉技术的发展,利用摄像头实时采集混凝土图像,通过AI模型自动分类坍落度状态,已成为一种高效、客观的替代方案。
本项目正是基于这一思路,使用 ResNet34 卷积神经网络对混凝土坍落度进行三分类预测(合适 / 偏干 / 偏稀),并构建了完整的 Web 应用系统,实现从图像采集、AI推理、数据标注到模型微调的全流程闭环。

二、系统功能一览
| 功能模块 | 说明 |
|---|---|
| 实时视频采集 | 支持本地USB摄像头和海康威视RTSP工业相机 |
| AI智能预测 | ResNet34三分类,GPU加速推理,毫秒级响应 |
| 数据采集管理 | 图像自动保存,元数据编码入文件名,支持人工标注 |
| 模型在线微调 | 一键启动训练,自动组织数据集,训练进度实时反馈 |
| Web界面 | 暗色工业风UI,前后端分离,浏览器即开即用 |
[占位符:功能流程图]
三、技术架构
系统采用 前后端分离 的 B/S 架构,后端提供 RESTful API,前端通过 AJAX 调用接口,职责清晰、便于维护和扩展。
┌─────────────────────────────────────────────────┐
│ 浏览器前端 │
│ (HTML + CSS + 原生JavaScript) │
└──────────────┬──────────────────┬────────────────┘
│ RESTful API │
▼ ▼
┌──────────────────────┐ ┌───────────────────────┐
│ Flask API 层 │ │ ML 模块层 │
│ ┌────────────────┐ │ │ ┌─────────────────┐ │
│ │ /api/camera/* │ │ │ │ classifier.py │ │
│ │ /api/predict/* │ │ │ │ (单例推理引擎) │ │
│ │ /api/train/* │ │ │ ├─────────────────┤ │
│ └────────────────┘ │ │ │ trainer.py │ │
│ │ │ │ (微调训练器) │ │
└──────────────────────┘ │ ├─────────────────┤ │
│ │ resnet34.py │ │
│ │ (模型定义) │ │
│ └─────────────────┘ │
└───────────────────────┘
3.1 后端架构
后端基于 Flask 框架,按功能拆分为 4 个 Blueprint:
| Blueprint | URL前缀 | 职责 |
|---|---|---|
main |
/ |
页面路由,渲染前端HTML |
camera |
/api/camera |
摄像头开关、帧获取、RTSP配置 |
predict |
/api/predict |
AI预测、图片上传预测、结果保存 |
train |
/api/train |
数据组织、训练启动、进度查询 |
核心设计决策:
- UI与API完全分离:前端不依赖后端模板渲染逻辑,所有数据交互通过 JSON API 完成,未来可轻松替换为 Vue/React 前端或对接移动端
- ML模块独立:模型定义、推理、训练各自为独立模块,不依赖 Flask,可单独作为 Python 包使用
- 线程安全:相机状态、模型单例、训练任务均使用
threading.Lock保护,避免并发问题 - 优雅降级:缺少 PyTorch 时 Flask 仍能正常启动,API 返回友好错误信息而非崩溃
3.2 前端设计
前端采用纯 HTML/CSS/JS 实现,无需 Node.js 构建流程,一个浏览器即可运行。
设计要点:
- 全屏Flex布局:
html,body固定100%高度不滚动,三列面板各自overflow-y:auto独立滚动,避免页面级滚动导致操作区被遮挡 - 暗色工业风:深蓝黑底色配亮蓝强调色,贴合工业视觉系统的使用场景
- 实时反馈:视频帧 100ms 轮询、训练进度 1.5s 轮询、Toast 通知,操作状态一目了然
- 响应式适配:三列 → 双列 → 单列自动响应
[占位符:前端界面三列布局截图]
3.3 ML 模块设计
这是本项目的技术核心,也是相比原版改进最大的部分。
模型单例加载
class ModelManager:
"""模型单例管理器,线程安全"""
_instance = None
_lock = threading.Lock()
def __new__(cls):
with cls._lock:
if cls._instance is None:
cls._instance = super().__new__(cls)
cls._instance._model = None
return cls._instance
def load_model(self):
if self._model is not None:
return self._model # 已加载则直接返回
self._device = torch.device(...)
self._model = resnet34(num_classes=3).to(self._device)
self._model.load_state_dict(torch.load(...))
self._model.eval()
return self._model
为什么需要单例? 原版代码每次调用 predict_() 都会重新创建模型并加载权重文件,这意味着:
- 每次推理都要从磁盘读取 85MB 的
.pth文件 - 每次都要将模型参数拷贝到 GPU 显存
- 推理延迟从亚毫秒级暴涨到秒级
单例模式下,模型只加载一次,后续推理直接复用 GPU 上的模型实例,推理耗时回归正常水平。
训练模块修复
原版训练代码存在一个严重 bug —— 优化器在每个 batch 中重新创建:
# 原版代码(有bug)
for batch, (x, y) in enumerate(train_dataloader):
optimizer = optim.Adam(model.parameters(), lr=0.001) # 每个batch重建!
optimizer.zero_grad()
loss.backward()
optimizer.step()
这导致 Adam 优化器的一阶矩和二阶矩估计在每个 batch 被重置,动量机制完全失效,训练效果退化为普通 SGD。修复后:
# 修复后
optimizer = optim.Adam(model.parameters(), lr=0.001) # 只创建一次
for batch, (x, y) in enumerate(train_dataloader):
optimizer.zero_grad()
loss.backward()
optimizer.step()
此外还增加了:
- 数据增强(RandomHorizontalFlip、RandomRotation),提升泛化能力
- shuffle=True 的 DataLoader,避免批次偏差
- 训练完成后自动保存模型并热重载推理引擎
- 训练进度回调机制,前端可实时显示 epoch/loss/acc
四、完整API接口文档
4.1 摄像头接口
| 接口 | 方法 | 请求体 | 说明 |
|---|---|---|---|
/api/camera/open |
POST | {"type":"local"|"rtsp","index":0} |
打开摄像头 |
/api/camera/close |
POST | - | 关闭摄像头 |
/api/camera/status |
GET | - | 获取摄像头状态 |
/api/camera/config |
POST | {"user":"","password":"","ip":""} |
配置RTSP参数 |
/api/camera/frame |
GET | - | 获取当前帧(base64 JPEG) |
/api/camera/capture |
POST | - | 截取当前帧 |
4.2 预测接口
| 接口 | 方法 | 请求体 | 说明 |
|---|---|---|---|
/api/predict/analyze |
POST | - | 对当前帧进行AI预测 |
/api/predict/analyze_upload |
POST | multipart文件 | 上传图片预测 |
/api/predict/save |
POST | {"concrete_type":"0","slump":"180","human_label":"0","pred_label":"0","timestamp":"..."} |
保存结果 |
/api/predict/count |
GET | - | 获取采集次数 |
4.3 训练接口
| 接口 | 方法 | 请求体 | 说明 |
|---|---|---|---|
/api/train/organize |
POST | - | 组织采集数据到训练/测试集 |
/api/train/start |
POST | {"epochs":10,"lr":0.001} |
启动训练(后台线程) |
/api/train/status |
GET | - | 查询训练进度 |
五、项目目录结构
Concrete_Slump_Test_System/
├── run.py # 启动入口
├── config.py # 全局配置
├── requirements.txt # Python依赖
├── README.md # 项目说明
├── resNet34.pth # 模型权重(需自行放置)
├── app/
│ ├── __init__.py # Flask应用工厂
│ ├── api/ # API接口层
│ │ ├── main.py # 页面路由
│ │ ├── camera.py # 摄像头API
│ │ ├── predict.py # 预测API
│ │ └── train.py # 训练API
│ ├── ml/ # 机器学习模块
│ │ ├── resnet34.py # ResNet模型定义
│ │ ├── classifier.py # 推理引擎(单例)
│ │ └── trainer.py # 训练器
│ ├── templates/
│ │ └── index.html # Web前端
│ └── static/
└── data/
├── saved_frames/ # 采集图像
└── dataset/
├── train/ # 训练集
└── test/ # 测试集
这种分层结构的优势:
api/与ml/完全解耦,ML模块可以独立于Web服务使用- 配置集中管理在
config.py,修改设备/路径/端口一处搞定 - 数据目录与代码目录分离,便于
.gitignore管理
六、使用流程
6.1 安装与启动
# 克隆项目
git clone https://github.com/xxx/Concrete_Slump_Test_System.git
cd Concrete_Slump_Test_System
# 安装依赖
pip install -r requirements.txt
# 放置模型权重文件 resNet34.pth 到项目根目录
# 启动服务
python run.py
# 访问 http://localhost:5000
6.2 操作步骤
- 打开摄像头:选择相机类型,点击"打开摄像头",视频画面实时显示
- 截取帧:点击"截取视频帧",捕获当前画面到分析区
- AI预测:点击"开始预测",模型返回分类结果、置信度和推理耗时
- 标注与保存:选择混凝土标号、输入坍落度值、勾选人工标注,点击"保存结果"
- 模型训练:积累足够数据后,点击"训练模式"一键微调,训练进度实时更新
6.3 预测结果展示
模型输出三分类结果,界面以不同颜色高亮显示:
| 分类 | 颜色 | 含义 |
|---|---|---|
| 合适 | 绿色 | 坍落度符合标准 |
| 偏干 | 橙色 | 混凝土偏干,坍落度不足 |
| 偏稀 | 青色 | 混凝土偏稀,坍落度过大 |
七、相比原版的改进
本项目由一个 PySide6 桌面应用重构而来,主要改进如下:
| 维度 | 原版(PySide6桌面端) | 重构版(Flask Web端) |
|---|---|---|
| 界面技术 | PySide6/Qt,需本地安装 | Web浏览器,零安装 |
| 架构 | UI与业务逻辑混在main.py | 前后端分离,API与ML独立 |
| 模型加载 | 每次预测重建模型+加载权重 | 单例模式,一次加载持续复用 |
| 训练bug | optimizer每batch重建,动量失效 | optimizer正确初始化,新增数据增强 |
| 跨平台 | 需配置Qt环境 | 浏览器即可访问,支持远程部署 |
| 可扩展性 | 紧耦合,难扩展 | API标准化,可对接移动端/其他前端 |
| 代码质量 | 冗余文件多,命名混乱 | 规范目录结构,完整文档和配置 |
| 依赖管理 | 无 | requirements.txt + .gitignore |
关键改进详解
1. 模型推理性能提升
原版每次调用 predict_() 都会执行 resnet34().load_state_dict(torch.load(...)),即每帧推理需从磁盘读取 85MB 权重文件并初始化模型。单例模式下只需首次加载,后续推理跳过这两步,性能提升显著。
2. 训练收敛性修复
Adam优化器的核心优势在于自适应学习率和动量积累。原版代码在每个batch中重建optimizer,导致动量向量被反复清零,训练退化为无动量的SGD。修复后收敛速度和最终精度均有明显改善。
3. 部署灵活性
Web架构支持远程部署 —— 可以将GPU服务器部署在现场,工程人员在办公室通过浏览器即可操作,无需安装任何客户端软件。
八、技术亮点总结
- 前后端分离:Flask提供标准化RESTful API,前端纯HTML/JS,易于维护和二次开发
- 模型单例推理:避免重复加载权重,推理延迟从秒级降至毫秒级
- 在线微调闭环:采集→标注→训练→部署,全流程在Web界面完成,无需命令行操作
- 多相机支持:同时兼容USB摄像头和海康威视工业相机,适配实验室和工地场景
- 优雅降级:缺少PyTorch时Web服务仍可启动,不会因环境问题直接崩溃
- 工业风UI:暗色主题、实时视频、进度反馈、日志面板,贴合工程应用场景
九、未来展望
- 支持更多分类类别(如坍落度数值回归预测)
- 集成检测模型,自动定位坍落度筒区域
- 支持多用户登录和权限管理
- 添加历史数据查询和统计报表
- 部署为Docker容器,一键启动
- 模型自动选择CPU/GPU,支持无GPU环境推理
十、参考与致谢
- ResNet论文 - Deep Residual Learning for Image Recognition
- PyTorch官方文档
- Flask文档
如果觉得项目有用,欢迎 Star ⭐ 和 Fork,也欢迎提出 Issue 和 PR!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)