简介:本资源是一套开箱即用的YOLOv5钢材表面缺陷检测完整方案,面向工业视觉初学者、智能制造方向学生及产线质检工程师,解决钢材生产中裂纹、划痕、凹坑等典型缺陷的自动化识别难题。压缩包共180个文件,含34个核心Python脚本(含训练/推理/QT界面逻辑)、29个YOLOv5配置yaml文件、32张标注样例JPG图像、5个预训练.pt权重与5个XML标注文件,并集成PyQt5开发的图形界面(含4个.ui设计文件),支持图片、视频及实时摄像头检测;另有PR曲线、loss曲线图、results.csv评估结果及TensorBoard日志文件,便于模型效果复现与分析。资源包大小为141.66MB,结构清晰,数据集已用LabelImg完成双格式(XML+TXT)标注,可直接用于迁移训练或教学演示。目前已有1750人学习下载,配套博文详细展示了数据集构成、界面操作流程与检测效果对比,是兼顾工程落地与课程实践的高实用性工业检测项目资源。 做钢材表面缺陷检测这件事,业内其实已经卷了不少年。传统视觉方案用灰度阈值、频域滤波、形态学处理,对钢带表面的那几类典型瑕疵能跑通,但一换产线、一换光源、钢材表面稍有点水渍氧化皮,规则就崩,维护成本极高。YOLOv5出来之后,很多做工业视觉的朋友开始把它当作缺陷检测的主力模型,原因很简单:在精度不掉的大前提下,部署成本低,推理速度快,社区资料还多。我这次整理的这套项目,就是用YOLOv5做钢材表面六类常见缺陷的检测,配合训练好的权重文件和数据集,再套一个Qt界面用于现场操作和结果展示,整套东西既可本地跑通,也可以挪到工控机上做产线级验证。
适合谁看?如果你是刚准备把深度学习检测模型落到工业场景的算法工程师、做机器视觉的售前售后工程师,或者在校学生需要快速搭建一套能跑通的全流程检测Demo,这篇内容就是给这类需求写的。下面会把数据集准备、模型训练、权重选型、界面整合这几个环节拆开讲清楚,每一步都给可直接照搬的参数和命令,也会把我在实际调试中踩过的坑一并说出来。
1. 项目整体设计与方案选型
1.1 为什么选YOLOv5而不是其他检测模型
钢材缺陷检测的场景相对特殊:被测表面纹理复杂、反光强烈、缺陷类型多且偶尔出现小目标缺陷,比如细小的夹杂和斑块。早期我用过Faster R-CNN做类似任务,精度上没问题,但推理速度在工业场景里撑不住,尤其是如果相机分辨率高、同时接多路相机,GPU资源一下就被占满。YOLOv5的anchor-based检测机制在速度和精度之间取得了很好的平衡,网络结构上对输入尺寸的适应性也好,可以把输入分辨率拉到640甚至1280来提升小目标召回,代价可控。
YOLOv5的另一个优势是工程生态成熟。数据增强、超参数进化、模型导出(ONNX、TensorRT)都做得非常顺手,对不擅长算法底层的视觉工程师来说,它是目前综合门槛最低、见效最快的方案。YOLOv8虽然更新,但如果你需要直接部署到厂里的老版本工控机,或者需要依赖一些较老的精简框架,YOLOv5反而更稳。和现在很多团队选择YOLOv8相比,YOLOv5的灵活性和可替换部件的社会资源存量依然值得坚持。
1.2 项目构成:三块拼图缺一不可
这套项目完整度高的原因在于三块拼图都有落地:
- 数据集:标注好的钢材表面缺陷数据,包含轧制氧化皮、斑块、开裂、点蚀表面、麻点、夹杂这六类常见缺陷,也就是业内熟悉的NEU-DET数据集对应的六类。如果你想自建数据,这套格式可以通用。
- 权重文件:基于上述数据训练出的YOLOv5权重,包括best.pt和last.pt。权重的作用不仅是给测试跑个结果,更重要的是作为基准线。有了它,你在自己的产线数据上做微调时就不用从头开始训练。
- Qt界面:用PyQt5或者PySide2写的一套桌面客户端,负责加载模型、选择图片/视频/相机源,实时显示检测结果并输出缺陷统计信息。
这三块是一个典型的“算法+界面”闭环。很多项目训练好模型就放那儿了,实际现场操作员根本不会用命令行在线推理,必须给一个可视化界面,这也是为什么“YOLOv5钢材缺陷检测模型权重数据集Qt界面”这套组合会同时被大家搜索和关注。
2. 数据集准备与处理
2.1 选公开数据集还是自建数据集
钢材缺陷这块公开数据集中最有名的就是NEU-DET,由东北大学发布,包含1800张热轧带钢表面缺陷图片,每类缺陷各300张,尺寸统一为200x200。这个数据集包含的六类缺陷是:crazing(裂纹)、inclusion(夹杂)、patches(斑块)、pitted_surface(点蚀表面)、rolled-in_scale(轧制氧化皮)、scratches(划伤)。类别不多,但每类形态差异很大,尤其是crazing和pitted_surface,往往带光照和纹理干扰,很适合用来跑通训练流程。
实际生产环境中,NEU-DET的分辨率偏低,图片上的缺陷尺寸相对偏大,直接用它训练出的模型到现场不一定好用。建议把它作为算法基线和迁移学习的起点,如果条件允许,从现场采集真实钢材表面图片,标注格式对齐成YOLOv5要求的txt格式(类别编号 中心点x坐标 中心点y坐标 宽度 高度,均为归一化值),这样训练出的权重才贴合现场工况。另外热词里也提到了“钢铁缺陷数据集servtal”之类的变体,实际都是同一批公开数据在不同渠道的传播命名,判断数据好坏的方式主要是看标注质量,而不是看名称噱头。
做自建数据集时需要注意采集时的光源方向:打光角度变化会导致同一类缺陷在图像上的灰度梯度完全不同,模型很容易学到光源特征而非缺陷本身,这一点在钢材检测里特别重要。
2.2 标注格式转换与数据增强策略
如果你拿到的数据不是YOLO格式,可以用LabelImg或labelme导出的XML/JSON格式转换过来。这里我习惯写一段Python脚本批量处理,避免手动改标注的体力活。需要注意XML中坐标是左上角和右下角,转YOLO格式时要算中心点、宽度、高度,并且全部除以图片宽高做归一化,否则训练时会报错或者效果极差。
数据增强方面,YOLOv5自带马赛克(mosaic)增强和随机仿射变换,工业表面缺陷场景中我还习惯叠加以下操作:
- 轻度高斯模糊:模拟镜头轻微失焦或反光扩散。
- 随机亮度/对比度调整:模拟不同产线光照条件。
- 随机水平翻转:注意有些缺陷方向有物理意义(比如划伤方向),不要盲目翻转。
- Cutout / Random Erase:可以模拟表面氧化皮遮挡造成的不完整缺陷形态,提升模型鲁棒性。
但增强比例不宜过大,钢材缺陷本来就占图小,过度增强反而会让模型学到噪声。我在训练时通常只开YOLOv5默认增强,手动把hsv_h、hsv_s强度降一点,因为钢材表面色彩信息很少,饱和度扰动意义不大,反而可能让缺陷区域颜色失真。
2.3 数据划分与训练集/验证集的坑
数据集划分不是简单随便分一下,它在缺陷检测中相当影响最终性能评估。最常见的问题是真实验证时发现mAP很高,但现场一测就废,原因是训练时数据分布和验证集太相似。钢材图片如果来自同一批连铸板坯,前后帧的光照、纹理基本不变,模型记住场景而没记住缺陷。
我的做法是:按图片采集时间或者产线批次划分训练集和验证集,而不是随机打乱。保证验证集包含不同光线条件下拍摄的图片,而不是来自同一时段。这是我踩过多次坑后总结出来的经验——工业视觉项目里,验证集构建是否合理,直接决定你后续模型能不能在现场落地。如果样本量少,记得使用K折交叉验证来评估稳定性,避免某一折凑巧效果很差或很好。
YOLOv5的目录结构按标准格式放即可:
dataset/ ├── images/ │ ├── train/ │ └── val/ ├── labels/ │ ├── train/ │ └── val/注意images和labels里对应文件的文件名必须一一对应,扩展名可以不同(.jpg/.png对应.txt),但主名必须一致。这种小细节一旦出错导致标注文件缺失,训练时loss会看上去正常,但实际大量图片没有参与监督计算。
3. 模型训练与权重调优
3.1 环境搭建与版本选择
如果是从“yolov5下载安装”这个关键词点进来的,可以直接去GitHub官方仓库拉最新release版本。建议不要用默认的master分支最新代码,而是选择v6.0或v7.0这种经过大量人验证的稳定版,因为最新代码可能依赖更新版本的依赖库,容易在安装环节卡住。克隆仓库后创建虚拟环境:
git clone https://github.com/ultralytics/yolov5.git cd yolov5 python -m venv venv source venv/bin/activate # Windows下为 venv\Scripts\activate pip install -r requirements.txt如果你有NVIDIA GPU,再装对应版本的PyTorch,用CUDA 11.8对应torch 2.0.1一般不会出问题。如果只有CPU,也能训练,但速度会慢到怀疑人生。工业场景中推理机通常用GPU,训练机最好也是GPU,内存建议16G以上,显存8G起步。
依赖安装后先跑一个检测demo验证环境,用官方给的yolov5s.pt跑一下:
python detect.py --source data/images/bus.jpg --weights yolov5s.pt能正常出结果框,再开始正式训练流程。
3.2 训练参数配置与计算过程
训练前需要准备一个数据配置文件。以NEU-DET为例,写一个钢材缺陷专用的yaml:
train: D:/steel_dataset/images/train val: D:/steel_dataset/images/val nc: 6 names: ['crazing', 'inclusion', 'patches', 'pitted_surface', 'rolled-in_scale', 'scratches']训练命令我习惯写成这样:
python train.py --data steel.yaml --weights yolov5s.pt --img 640 --batch 16 --epochs 100 --device 0 --name steel_yolov5s几个关键参数的选择逻辑:
- 输入分辨率img:NEU-DET原始图只有200x200,但训练时缩放至640并配合mosaic增强可以增强模型对多尺度特征的适应性。如果主要检测小缺陷,推荐训练分辨率640,推理时可以用640或1280。
- batch size:取决于GPU显存。以NVIDIA RTX 3060 12G为例,YOLOv5s在640分辨率下batch 16没问题。如果显存紧张,batch 8也可以,但收敛会稍慢。可以先用小batch跑几个epoch,观察显存占用再决定。
- epochs:对于NEU-DET这样1800张的小数据量,100轮已经足够看到收敛。自建数据规模大,建议200轮起,同时配合早停机制。
- weights:可以使用预训练权重yolov5s.pt做迁移学习,也可以基于自己之前训练好的best.pt继续训练。如果类别差异大,迁移学习对收敛速度的提升非常明显。
训练过程中你会看到很多训练指标输出,包括box_loss、cls_loss、obj_loss、mAP@0.5、mAP@0.5:0.95等。mAP@0.5达到0.8以上就是不错的结果,但对于钢材表面缺陷,目标是现场漏检率低,所以我会更关注recall和各类缺陷单类别的AP值,例如crazing通常最难检测,AP往往偏低,这跟缺陷边缘与背景纹理难区分有关。
3.3 权重选择与模型剪枝优化
训练结束后,在runs/train/steel_yolov5s/weights目录下会有best.pt和last.pt两个文件。best.pt根据验证集最优mAP保存,last.pt是最后一轮保存结果。默认用best.pt,但如果你的验证集划分合理,有时候last.pt在特定类别上的召回反而更好,可以都测试对比一下。
权重选好后,还要考虑部署阶段的模型瘦身。如果放在Qt界面里用,直接用PyTorch权重即可;如果要上产线,建议导出为ONNX或TensorRT格式,推理速度会有数量级提升。
导出ONNX非常简单:
python export.py --weights runs/train/steel_yolov5s/weights/best.pt --include onnx --opset 12导出后可以用onnxruntime加载推理,比直接跑PyTorch推理要省内存,速度也更快。TensorRT则需要在目标工控机上安装对应版本的TensorRT,在这里不展开。另外有一个细节:如果导出后onnx推理结果与pt结果不一致,记得检查导出时的opset版本和输入分辨率是否一致。
YOLOv5超参数(hyp.scratch.yaml)中影响最大的是lr0(初始学习率)、mosaic(马赛克增强概率)、fliplr(水平翻转概率)。工业场景中,我建议把fliplr设为0.3以下,因为水平翻转对划伤这类长条状缺陷的方向性有干扰,模型可能学到缺陷必须朝某一方向才算正样本,实际现场方向是任意的,所以翻转比例要谨慎。
4. Qt界面集成与部署
4.1 界面功能设计与线程模型
Qt界面在整个项目里解决的是“让非算法人员用起来”的问题。界面功能设计上,我的划分是:
- 左侧:功能控制区域,包括选择模型权重文件、选择图片/视频/相机源、开始/停止检测、阈值滑块。
- 中间:图像显示区域,原始图像和检测结果图像切换显示。
- 右侧:检测结果列表,包括缺陷类别、置信度、数量统计。
- 底部:检测耗时和FPS显示。
从技术角度,最关键的是要让推理不出现在主线程中。如果在Qt的主线程(GUI线程)里跑YOLOv5推理,界面会卡住,拖动窗口都成问题,别说实时显示了。我通常的做法是使用QThread把推理流程放进单独的线程,通过信号槽机制把推理结果传回主线程更新界面。在PyQt5里定义推理线程类:
class DetectThread(QThread): result_ready = pyqtSignal(list, str) # 检测结果,显示图像路径 def __init__(self): super().__init__() self.model = None self.source = "" def load_model(self, weights_path): self.model = torch.hub.load('ultralytics/yolov5', 'custom', path=weights_path, force_reload=True) def run(self): # 加载图片+推理+发送信号 results = self.model(self.source) self.result_ready.emit(results.pandas().xyxy[0].values, self.source)这里用了torch.hub.load加载模型,优点是代码简单,无需自己在代码里拼模型结构和权重路径;缺点是每次加载都要联网或缓存,离线环境需要预先下载好hubconf,否则会卡在加载阶段。
4.2 界面布局与显示逻辑
界面布局我推荐用QHBoxLayout和QVBoxLayout组合,而不是用Qt Designer拖出来的固定尺寸控件。因为现场工控机的屏幕分辨率不固定,布局管理器可以自适应窗口大小。使用QGraphicsView或QLabel显示图片,注意QLabel显示大图时要用scaled来缩放,否则会把控件撑爆。
图像显示的逻辑也有讲究:YOLOv5推理返回的结果是已标注完的图片(NumPy数组),直接用QPixmap转成QImage显示即可。但要注意,cv2读入的图像是BGR通道,需要转换成RGB再在Qt里显示;用matplotlib显示时还要注意没有GUI后端时会崩溃,建议直接用cv2.imencode转png字节流再显示。
另外,阈值滑块联动检测置信度时,我习惯用滑块控制self.conf阈值,每帧推理结果中置信度低于阈值的框直接滤掉。这个设计对现场调参很有用:不同光线条件下缺陷置信度波动,操作员可以根据实际情况实时调整阈值,不用重启程序、不用改代码。但注意过滤逻辑需要放在后处理中,避免重新设定模型参数。
4.3 相机接入与网络IP设置
很多用户搜索“qt 界面ip设置”或“qt 界面linux ip设置”,说明界面不只是本机文件检测,还要接入工业相机或局域网视频流。工业相机常见通过RTSP协议接入,比如海康、大华相机,或者远程工控机上的RTSP流。Qt中可以调用cv2.VideoCapture来读取:
cap = cv2.VideoCapture("rtsp://192.168.1.100:554/Streaming/Channels/101")需要注意RTSP流读取和显示不能放在GUI线程里,建议单独开一个采集线程,读帧后存入队列,推理线程从队列中取帧进行检测。两个线程之间用threading.Queue或QQueue来传递数据,队列长度控制在3帧左右,超出丢帧,保证实时性。
关于IP设置,最常见的问题是相机与电脑不在同一网段,导致cv2.VideoCapture一直返回失败。排查步骤是先ping相机的IP,确认网络连通性,然后在Qt界面中提供一个设置IP的输入框,把子网掩码、网关都做成可配置项。如果你在Linux工控机上,还需要注意ens33/eth0等网卡名称是否正确,网卡未启用时系统配置了IP也不生效,可以使用nmcli或ifconfig排查。建议界面上额外加一个网络状态显示模块,读取当前主机的IP配置,方便现场判断问题出在相机还是网络层。
5. 常见问题与排查技巧实录
5.1 训练阶段:loss异常、数据加载慢、显存溢出
训练时最常见的一个坑是loss直接nan。多数原因是学习率设置过大,可以将lr0从0.01降到0.001。如果数据集中存在空标注文件(图片没有对应标签),也会导致计算loss时出现nan,建议训练前写脚本扫描label目录,确保每张图片都有标注且类别编号在0到nc-1之间。
数据加载慢的问题多半是磁盘IO瓶颈。如果数据集放在机械硬盘上,训练时读取图片会成为性能瓶颈。YOLOv5自带cache-images参数,可以把数据集缓存到内存,训练速度提升非常明显,前提是内存足够。另外图片过大的场景建议先压缩图片尺寸再训练,不需要直接拿原图5000x3000去喂给模型。
显存溢出(CUDA out of memory)时,可以逐步降低batch大小到8、4,或者打开--cacheImages后释放部分内存。但在训练阶段,最好不要一上来就降低分辨率,因为分辨率影响检测性能,优先考虑batch和优化器设置。
5.2 推理阶段:结果与训练不一致、延迟高、乱码
很多人在Qt界面里集成模型后,发现同一张图检测结果和训练时验证结果差别很大。这一般是预处理不一致导致的,比如训练时走了letterbox(保留长宽比加灰边)预处理,而界面推理时没有做同样的letterbox,直接resize成方形,导致目标变形,检测性能明显退化。YOLOv5的detect.py会自动做letterbox,但自己写推理代码时很容易忽略这个细节,我用PyTorch的torchvision加载图片时也遇到过。强烈建议在Qt中直接调用YOLOv5提供的推理封装,而不是自己拼预处理流程。
推理延迟高,通常是模型过重或设备太弱。可以尝试改用yolov5s或yolov5n的权重,或者在导出ONNX后开启fp16精度,速度会有明显提升。CPU推理时建议使用OpenVINO导出的IR模型,在Intel平台上速度提升显著。如果要保持重量级的检测精度,考虑提升推理线程优先级,并把界面刷新控制在15-30帧,不必每帧都刷新UI,检测结果可以按固定频率更新显示。
关于中文显示乱码,这个问题在工业现场很常见。YOLOv5训练时类别名用的是英文,Qt界面上如果需要显示中文类别名,注意不要直接从模型读取名称,而是在界面映射表中自己处理中文名称。Qt的QLabel默认字体不支持中文时,有可能显示成方框,你需要在程序启动时设置:
from PyQt5.QtGui import QFont QFont("Microsoft YaHei", 10)5.3 权重和文件路径的坑
最容易被忽视的一个坑是路径中有中文或空格:权重文件路径、数据集路径如果有中文,训练阶段PyTorch能正常读,但导出ONNX或Qt加载时经常报错。网上很多“模型加载失败”的案例,最后都是路径问题。建议项目根目录纯英文、无空格。
另一个坑是在Qt中加载权重时,直接使用绝对路径,但不做文件类型校验。用户手滑选了.pt文件类型之外的模型或者文件不完整,会导致加载时直接崩溃。所以在打开文件选择框时过滤后缀,并在加载前检查文件大小的合理性,至少不应为0字节。
从我的实际经验来看,把best.pt放到一个统一的models目录下,并带上日期和mAP信息命名,例如steel_yolov5s_0912_089.pt,对于多版本模型比对非常有帮助。工业现场的工程师通常记不住哪个权重是哪个版本,文件名写清楚比什么都强。
写在最后的实操心得
整套流程走通之后,最让我有感触的一点是:YOLOv5本身并不是难点,真正的工程难点在于数据质量、前后处理一致性和界面线程稳定性。这些内容不是读论文能学会的,而是需要在现场一台相机一台相机排查、一个一个bug解决中积累起来的。如果你准备从头搭这个项目,我建议先把训练这一环跑稳,拿到一个满意的权重后再写Qt界面。把界面写完了再回头调模型,调试成本会高很多。另外,如果要部署到现场,尽量把模型导出成ONNX或者TensorRT,推理速度和资源占用都会好得多。希望这篇内容能帮你跳过一些我自己当年踩了又踩的坑。
本文还有配套的精品资源,点击获取