基于 YOLO11 的钢材表面六类缺陷智能检测系统
把热轧钢板、冷轧钢板表面的"裂纹、夹杂、麻面、划痕……"这些工业缺陷,从靠老师傅打手电变成镜头一拍就出报表。
一、背景
1.1 行业痛点
钢材是工业制造的"骨头",但产线上的钢板/钢卷绕不开一件事——表面缺陷。这些缺陷既是质量门槛,也是合规底线:
- 裂纹:轧制应力或冷却不均产生的细长裂纹,关系强度与寿命;
- 夹杂:钢材中的非金属杂质或氧化物,会显著降低疲劳寿命;
- 斑块:成片色差或纹理异常,常见于热轧氧化或表面污染;
- 麻面:密集小坑,多由腐蚀或脱落造成;
- 氧化皮压入:氧化皮被轧辊压进基体,剥落后形成凹坑;
- 划痕:搬运/轧制过程中尖锐物刮擦的线性损伤。
传统的人工目检:
- 工序快、缺陷小,老师傅在线一天看 8 小时眼睛都能看花;
- 不同班组打分口径不一致,质量数据难沉淀;
- 一旦漏检流到下游冲压、焊接环节,返工成本极高。
本项目用 YOLO11n 做"六类钢材表面缺陷"的目标检测,配套 Streamlit 前端,让一线质检员从"打手电+笔记本"变成"上传图片 → 自动出缺陷位置 + 类别 + 风险等级"。
视频演示与源码下载
https://www.bilibili.com/video/BV1rHH96VE57/
包含:
📦完整项目源码
📦预训练模型权重
🗂️数据集
1.2 项目运行效果
1.3 项目介绍
核心创新点:
| 维度 | 说明 |
|---|---|
| 六类全覆盖 | 裂纹 / 夹杂 / 斑块 / 麻面 / 氧化皮压入 / 划痕,对齐 NEU-DET 公开数据集 |
| 风险分级 | 高/中/低三档风险,UI 自动用不同颜色标识 |
| 多输入 | 单图 / 批量 / 视频 / 摄像头四种输入,与产线相机、巡检视频自然对接 |
| 工程化 | 5MB 级模型 + ONNX 导出,可部署到边缘 AI 盒子或工业 PC |
| 配置驱动 | 类别说明、风险等级、UI 配色全部从configs/project.yaml注入 |
风险等级(写进 UI 图例与悬浮提示):
| 类别 | 风险 | 说明 |
|---|---|---|
| 裂纹 | high | 直接影响材料强度 |
| 氧化皮压入 | high | 剥落后形成凹坑 |
| 夹杂 | medium | 影响疲劳寿命 |
| 麻面 | medium | 易成腐蚀源 |
| 斑块 | low | 表面外观异常 |
| 划痕 | low | 线性机械损伤 |
技术栈:
| 层 | 选型 |
|---|---|
| 检测模型 | YOLO11n(ultralytics 官方,预训练 yolo11n.pt) |
| 训练框架 | ultralytics ≥ 8.3 |
| 后端推理 | Python 3.10 + PyTorch(CPU / MPS / CUDA 自适应) |
| 前端 | Streamlit + Plotly |
| 视频解码 | OpenCV + imageio-ffmpeg |
| 部署形态 | Streamlit / Docker;可导出 ONNX 给工业边缘盒子 |
二、设计框架
┌──────────────────────────────────────────────┐ │ 产线相机 / 质检员手机 / 巡检 PAD │ │ 单图 / 批量 / 视频 / 摄像头 │ └──────────────┬───────────────────────────────┘ ▼ HTTP(默认 8501) ┌──────────────────────────────────────────────┐ │ Streamlit 应用 app/streamlit_app.py │ │ ├─ infer_image_path() 单帧推理 │ │ ├─ 类别 → 风险等级(high / medium / low)映射 │ │ └─ render_batch_analysis() 缺陷分布 + 风险图 │ └──────────────┬───────────────────────────────┘ ▼ ultralytics.YOLO ┌──────────────────────────────────────────────┐ │ YOLO11n 推理引擎 │ │ model/best.pt(6 类钢材表面缺陷) │ └──────────────────────────────────────────────┘YOLO11 网络结构(一图速通):
输入 640×640 │ ┌───▼──── Backbone(C3k2 + SPPF) ────┐ │ 纹理 / 边缘 / 微小斑点特征提取 │ └───┬───────────────────────────────┘ │ ┌───▼──── Neck(FPN + PAN) ─────────┐ │ 小目标(裂纹/夹杂)+ 大目标(斑块)│ └───┬───────────────────────────────┘ │ ┌───▼── Head(Decoupled + DFL) ─────┐ │ 6 类分类 + DFL 边框回归 │ └───┬───────────────────────────────┘ │ 输出:N×(x1,y1,x2,y2,conf,缺陷类)为什么选 YOLO11n:钢材缺陷大多是长宽比悬殊的小目标(细长裂纹、点状夹杂、线状划痕),YOLO11 的多尺度特征 + DFL 回归对这种形态非常友好;5MB 级模型也方便下沉到产线边缘 AI 盒子。
检测流程:
钢板图 ──▶ letterbox 640 ──▶ YOLO11n 推理 │ ▼ conf ≥ 0.25 + NMS(IoU 0.7) │ ▼ result.plot() 画框 │ ▼ class_name → 风险等级 → 缺陷位置/严重程度报告三、代码结构(核心 50 行)
# app/streamlit_app.py(节选)frompathlibimportPathimportstreamlitasst,pandasaspd,yamlfromultralyticsimportYOLO ROOT=Path(__file__).parent.parent MODEL_PATH=ROOT/"model"/"best.pt"CFG=yaml.safe_load(open(ROOT/"configs"/"project.yaml",encoding="utf-8"))APP=CFG.get("app",{})SEVERITY=APP.get("class_severity",{})# ① 风险等级映射@st.cache_resource(show_spinner=False)defload_model(p:str)->YOLO:returnYOLO(p)# ② 缓存权重definfer_image_path(model:YOLO,image_path:Path,conf:float):result=model.predict(str(image_path),conf=conf,verbose=False)[0]# ③ 推理annotated=result.plot()rows=[]ifresult.boxesisnotNone:forboxinresult.boxes:cls_id=int(box.cls.item())x1,y1,x2,y2=[float(v)forvinbox.xyxy[0].tolist()]cls_name=result.names[cls_id]rows.append({"class_name":cls_name,"severity":SEVERITY.get(cls_name,"low"),# ④ 自动打风险等级"confidence":round(float(box.conf.item()),4),"x1":round(x1,1),"y1":round(y1,1),"x2":round(x2,1),"y2":round(y2,1),})returnannotated[:,:,::-1],pd.DataFrame(rows)# ---------- Streamlit 入口 ----------st.set_page_config(page_title=APP.get("title","Steel Defect AI"),layout="wide")conf=st.sidebar.slider("置信度阈值",0.1,0.9,0.25,0.05)model=load_model(str(MODEL_PATH))mode=st.radio("输入类型",["单张图片","批量图片","视频","摄像头"],horizontal=True)ifmode=="单张图片":up=st.file_uploader("上传待检测钢板图片",type=["jpg","jpeg","png","webp","bmp"])ifupisnotNone:annotated,df=infer_image_path(model,Path(up.name),conf)col1,col2=st.columns(2)col1.image(up.getvalue(),caption="原图")col2.image(annotated,caption="检测结果")# 高风险计数high_n=int((df["severity"]=="high").sum())ifnotdf.emptyelse0st.metric("高风险缺陷数",high_n)st.dataframe(df)5 段解析:
SEVERITY—— 把"裂纹/氧化皮压入 = high,夹杂/麻面 = medium,斑块/划痕 = low"做成可配置的字典,业务专家想调整无需动 Python 代码。@st.cache_resource—— Streamlit 会话级缓存权重,刷新页面只加载一次。model.predict(...)[0]—— ultralytics 一行完成 letterbox、NMS、置信度过滤。- 在结果 DataFrame 里当场打上 severity 字段,下游"高风险缺陷数"卡片、风险柱状图、CSV 导出全部基于这一字段。
st.metric("高风险缺陷数", high_n)—— 把"看几张图能看出来什么"这件事,从图片直接转成数字 KPI,质检主管一眼就能看到产线状态。
四、训练效果
模型基于yolo11n.pt、imgsz=640、batch=16,在 NEU-DET 六类钢材缺陷数据集上训练。
模型在测试集上检测效果良好,可稳定识别裂纹、夹杂、斑块、麻面、氧化皮压入、划痕这六类钢材表面缺陷,已能满足产线初筛、巡检与质检数字化等场景的使用需要。
五、项目总结
做对了什么:
- 任务对齐工业语义:检测结果不止有类名,还自动带"高/中/低"风险等级,直接可对接质检系统的告警与放行规则。
- 轻量 + 边缘友好:5MB 级权重,可导出 ONNX 给产线工业 PC、嵌入式 AI 盒子。
- 配置驱动 UI:类别说明、风险等级、配色等都从
configs/project.yaml注入,把"换品类(如铝材表面缺陷)"这件事压成一份 yaml + 一份新权重。
还能怎么做:
- 同时输出缺陷面积比:基于检测框面积 / 钢板可视区域比例计算"单板缺陷率",更对得上工业 PPM 指标;
- 多模态融合:可见光 + 表面轮廓激光 / 红外,对低对比度的氧化皮压入、麻面更稳;
- 追加缺陷分割:检测框只定位,再叠一个轻量分割头能给出像素级缺陷面积,直接对接退货/降级规则;
- 数据扩充:加入更多车间真实工况图像,提升模型在不同光照、不同钢种下的鲁棒性。
一句话总结:用 YOLO11n 把"钢板表面缺陷在哪+什么类+多大风险"这套质检小流程跑通,是 5MB 模型撬动一条产线在线质检的典型样例。