资讯动态

传送带破损检测:YOLOv5工业落地的标注、训练与部署全链路

发布时间:2026/9/20 19:32:13 来源:尧图企业网站定制
简介本资源是一套面向工业视觉检测领域的传送带皮带破损缺陷识别专用数据集适用于YOLOv5等PyTorch框架下的目标检测模型训练与验证特别适合智能制造、设备巡检、自动化质检等场景的算法工程师与计算机视觉学习者。数据集基于700张真实工况下采集的传送带图像构建配套700个YOLO格式.txt标注文件及1个类别定义yaml配置文件共1401个文件总容量68.75MB结构简洁规范开箱即用。目前已有545人学习下载体现了工业缺陷检测数据资源的高实用价值。用户可直接用于模型训练、数据增强实验、mAP评估基准测试或作为教学案例开展缺陷定位与分类任务实践图片命名含RF哈希标识便于溯源与去重管理yaml文件明确声明破损类标签显著降低数据加载与训练配置门槛。1. 传送带皮带破损检测不是“拍张图就跑YOLO”700张图要真正用起来得先过标注一致性、缺陷尺度分布、PyTorch数据加载三道硬关工业现场的传送带皮带破损形态千差万别细长裂纹像毛发边缘起翘呈锯齿状局部鼓包似水泡大面积撕裂带毛边。这700张原始图片若直接喂给YOLOv5模型大概率学不会“什么是破损”——它看到的不是缺陷语义而是标注框松散、类别混用、小目标漏标导致的噪声信号。这不是数据量不够的问题而是标注质量决定模型上限。本项目核心价值不在“有700张图”而在“这700张图已按YOLOv5 PyTorch标准完成结构化标注”即每张图对应一个.txt标签文件每行含class_id center_x center_y width height归一化坐标且所有破损统一为class_id0。这种格式可直接接入torch.utils.data.Dataset子类跳过XML/JSON转换环节大幅缩短从数据到训练的链路。适合产线质检工程师快速验证算法可行性也适合作为高校课程设计中“工业缺陷检测”模块的最小可行数据集——你不需要从零标注但必须理解为什么这样标、哪里容易翻车、如何验证标注是否真能被PyTorch正确读取。2. 用LabelImg脚本校验构建YOLOv5兼容标注流从原始图片到归一化txt的完整闭环2.1 为什么不用CVAT或MakeSenseLabelImg仍是工业场景下700张图标注的最优解CVAT虽支持多人协作与自动标注但部署成本高、导出YOLO格式需额外配置MakeSense依赖网络且对中文路径支持不稳定。而LabelImg是轻量级桌面工具单机即可运行导出格式原生支持YOLOv5--export-yolo参数且对传送带这类背景单一、缺陷对比度高的图像人工框选效率极高。关键在于它强制要求用户为每个框手动输入class_id避免了多类别数据集中常见的“漏填类别”问题。对于本项目仅需识别“破损”这一类别的场景我们创建classes.txt文件内容仅为单行damage确保所有标注框都绑定到id0。安装命令如下Windows/macOS/Linux通用pip install labelimg labelImg启动后通过Open Dir加载700张图片所在文件夹Change Save Dir指定标签保存路径建议与图片同级新建labels/目录在Auto Save mode开启状态下每画一个框并回车确认即自动生成对应.txt文件。2.2 归一化坐标的本质是抗分辨率扰动必须用原始图片尺寸计算YOLOv5要求标签坐标为归一化值0~1区间公式为center_x (bbox_x_min bbox_width/2) / image_widthcenter_y (bbox_y_min bbox_height/2) / image_heightwidth bbox_width / image_widthheight bbox_height / image_heightLabelImg默认导出即满足此要求但必须验证打开任意一张图片对应的.txt文件检查数值是否全在[0,1]范围内。常见错误是图片被缩放后标注导致坐标溢出。我们写一个校验脚本遍历全部700个.txt文件并比对原始图片尺寸# validate_labels.py import os from PIL import Image img_dir images/ # 原始图片路径 label_dir labels/ # 标签路径 for label_file in os.listdir(label_dir): if not label_file.endswith(.txt): continue img_path os.path.join(img_dir, label_file.replace(.txt, .jpg)) if not os.path.exists(img_path): img_path os.path.join(img_dir, label_file.replace(.txt, .png)) if not os.path.exists(img_path): print(f⚠️ 图片缺失: {label_file}) continue # 获取原始图片尺寸 try: w, h Image.open(img_path).size except Exception as e: print(f❌ 图片读取失败 {img_path}: {e}) continue # 解析标签文件 with open(os.path.join(label_dir, label_file), r) as f: lines f.readlines() for i, line in enumerate(lines): parts line.strip().split() if len(parts) ! 5: print(f❌ 标签格式错误 {label_file} 第{i1}行: {line}) continue try: cx, cy, bw, bh map(float, parts[1:]) if not (0 cx 1 and 0 cy 1 and 0 bw 1 and 0 bh 1): print(f❌ 坐标越界 {label_file} 第{i1}行: cx{cx:.3f} cy{cy:.3f} bw{bw:.3f} bh{bh:.3f}) except ValueError: print(f❌ 非数字坐标 {label_file} 第{i1}行: {line})提示运行此脚本前确保images/和labels/目录下文件名严格一一对应如conveyor_001.jpg↔conveyor_001.txt。若发现越界坐标说明标注时图片被拉伸或裁剪需重新用原始尺寸图片标注。2.3 构建PyTorch Dataset类绕过YOLOv5官方train.py直连数据加载器YOLOv5官方训练脚本对数据集结构有强约束要求train/,val/子目录而本项目700张图可能尚未划分训练/验证集。我们自行实现ConveyorDamageDataset支持灵活划分# dataset.py import torch from torch.utils.data import Dataset from PIL import Image import numpy as np import os import cv2 class ConveyorDamageDataset(Dataset): def __init__(self, img_dir, label_dir, img_size640, train_ratio0.8, is_trainTrue): self.img_dir img_dir self.label_dir label_dir self.img_size img_size self.is_train is_train # 获取所有图片路径 self.img_files [f for f in os.listdir(img_dir) if f.lower().endswith((.jpg, .jpeg, .png))] # 按比例划分训练/验证集固定随机种子保证可复现 np.random.seed(42) np.random.shuffle(self.img_files) split_idx int(len(self.img_files) * train_ratio) if is_train: self.img_files self.img_files[:split_idx] else: self.img_files self.img_files[split_idx:] def __len__(self): return len(self.img_files) def __getitem__(self, idx): img_name self.img_files[idx] img_path os.path.join(self.img_dir, img_name) label_path os.path.join(self.label_dir, img_name.replace(.jpg, .txt).replace(.png, .txt)) # 加载并预处理图像 img cv2.imread(img_path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 转RGB h, w img.shape[:2] img cv2.resize(img, (self.img_size, self.img_size)) img img.astype(np.float32) / 255.0 # 归一化到[0,1] img torch.from_numpy(img).permute(2, 0, 1) # HWC → CHW # 加载标签 labels [] if os.path.exists(label_path): with open(label_path, r) as f: for line in f: parts line.strip().split() if len(parts) 5: cls_id, cx, cy, bw, bh map(float, parts) # 将归一化坐标转为像素坐标基于resize后的尺寸 x1 (cx - bw/2) * self.img_size y1 (cy - bh/2) * self.img_size x2 (cx bw/2) * self.img_size y2 (cy bh/2) * self.img_size labels.append([cls_id, x1, y1, x2, y2]) # 转为tensor if len(labels) 0: labels torch.tensor(labels, dtypetorch.float32) else: labels torch.zeros((0, 5), dtypetorch.float32) return img, labels # 使用示例 train_dataset ConveyorDamageDataset(images/, labels/, is_trainTrue) val_dataset ConveyorDamageDataset(images/, labels/, is_trainFalse) train_loader torch.utils.data.DataLoader(train_dataset, batch_size8, shuffleTrue, num_workers4)注意此Dataset类将YOLO格式的归一化坐标实时转换为训练所需的像素坐标x1,y1,x2,y2避免了预生成大量中间文件。num_workers4需根据机器CPU核心数调整过高会导致内存溢出。3. YOLOv5s模型微调实操从预训练权重加载到损失函数监控的端到端训练3.1 选择YOLOv5s而非YOLOv5x小数据集下的精度与速度平衡点700张图属于小规模工业数据集YOLOv5x1.9B参数极易过拟合而YOLOv5s7.2M参数在保持足够表征能力的同时训练速度快、显存占用低单卡RTX 3060可跑batch16。我们不从头训练而是加载COCO预训练权重进行迁移学习——这利用了模型在通用物体检测任务上学到的底层特征边缘、纹理、形状只需微调最后几层以适配“皮带破损”这一特定模式。下载地址https://github.com/ultralytics/yolov5/releases/download/v7.0/yolov5s.pt注意版本一致性本文基于v7.0。3.2 修改模型配置以匹配单类别任务减少冗余计算YOLOv5默认输出80类COCO而本项目只需1类破损。修改models/yolov5s.yaml中的nc: 80为nc: 1并同步更新head部分的卷积层输出通道数# models/yolov5s.yaml 关键修改段 nc: 1 # number of classes depth_multiple: 0.33 # model depth multiple width_multiple: 0.50 # layer channel multiple ... # Detect head head: [[-1, 1, Conv, [512, 3, 1]], # 20 [-1, 1, Conv, [256, 3, 1]], # 21 [-1, 1, Conv, [128, 3, 1]], # 22 [[-1, -2, -3, -4], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)提示Detect层的nc参数必须与yaml顶部nc一致否则加载权重时会报错size mismatch。若使用Ultralytics官方库可通过model torch.hub.load(ultralytics/yolov5, yolov5s, pretrainedTrue)后用model.model[-1].nc 1动态修改但需重新初始化检测头权重。3.3 训练命令与关键超参数解析聚焦小目标与高召回传送带破损常表现为细长裂纹宽高比5或微小鼓包32×32像素需针对性调整# 训练命令Linux/macOS python train.py \ --img 640 \ --batch 16 \ --epochs 100 \ --data data/conveyor_damage.yaml \ --cfg models/yolov5s.yaml \ --weights yolov5s.pt \ --name conveyor_damage_v1 \ --hyp data/hyps/hyp.scratch-low.yaml \ --workers 4关键参数说明--img 640输入尺寸兼顾小目标检测与GPU显存RTX 3060需≤640--batch 16批量大小小数据集下不宜过大避免梯度更新不稳定--hyp data/hyps/hyp.scratch-low.yaml采用低学习率预设初始lr0.01防止微调时破坏预训练特征--workers 4数据加载进程数需小于CPU逻辑核心数过高反致IO瓶颈data/conveyor_damage.yaml内容必须严格匹配目录结构train: ../images/ # 训练图片路径相对train.py位置 val: ../images/ # 验证图片路径此处与train相同实际应分开 nc: 1 names: [damage]3.4 监控训练过程识别过拟合与收敛停滞的三个信号训练日志中需重点关注以下指标runs/train/conveyor_damage_v1/results.csvepochbox_lossobj_losscls_lossmetrics/precision(B)metrics/recall(B)metrics/mAP_0.5metrics/mAP_0.5:0.9500.1230.4560.0890.620.580.590.32500.0420.1870.0310.780.750.760.481000.0380.1720.0290.810.790.790.51过拟合信号val/box_loss在50轮后持续上升而train/box_loss继续下降 → 减少训练轮次或增加--augment启用Mosaic增强收敛停滞信号metrics/mAP_0.5连续10轮提升0.005 → 降低学习率添加--lr 0.001召回不足信号metrics/recall(B)始终0.7 → 检查标注是否漏标小破损或在hyp.yaml中调低iou_t如0.15→0.14. 破损检测落地验证用OpenCV部署推理可视化定位真实产线误检根源4.1 导出ONNX模型并用OpenCV DNN模块推理脱离PyTorch环境部署训练完成后将最佳权重best.pt导出为ONNX格式便于嵌入C或边缘设备# 导出命令需安装onnx python export.py --weights runs/train/conveyor_damage_v1/weights/best.pt --include onnx生成best.onnx后用OpenCV DNN模块加载无需Python环境# infer_opencv.py import cv2 import numpy as np net cv2.dnn.readNetFromONNX(best.onnx) cap cv2.VideoCapture(conveyor_video.mp4) # 或USB摄像头 while True: ret, frame cap.read() if not ret: break # 预处理resize normalize transpose blob cv2.dnn.blobFromImage(frame, 1/255.0, (640, 640), (0,0,0), swapRBTrue, cropFalse) net.setInput(blob) outputs net.forward(net.getUnconnectedOutLayersNames()) # 解析YOLO输出此处简化实际需NMS后处理 for output in outputs: for detection in output: scores detection[5:] class_id np.argmax(scores) confidence scores[class_id] if confidence 0.5: # 置信度阈值 center_x, center_y, w, h detection[0:4] * np.array([frame.shape[1], frame.shape[0], frame.shape[1], frame.shape[0]]) x int(center_x - w/2) y int(center_y - h/2) cv2.rectangle(frame, (x, y), (xw, yh), (0,255,0), 2) cv2.putText(frame, fdamage:{confidence:.2f}, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2) cv2.imshow(Conveyor Damage Detection, frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() cv2.destroyAllWindows()4.2 误检分析三步法从热力图定位到标注修正当模型在产线视频中误报如将传送带接缝、阴影、反光点判为破损需系统性归因生成Grad-CAM热力图定位模型关注区域# 使用captum库需安装 from captum.attr import GradCAM from captum.attr import visualization model.eval() input_tensor img.unsqueeze(0) # 假设img是预处理后的tensor grad_cam GradCAM(model, model.model[-1]) # 指向Detect层 cam grad_cam.attribute(input_tensor, target0) # class_id0 visualization.visualize_image_attr(cam.squeeze().cpu().numpy(), original_imageimg.permute(1,2,0).cpu().numpy(), methodheat_map, signabsolute_value)若热力图集中在接缝处而非破损区域说明模型学到了错误纹理特征。统计误检样本的标注属性提取所有误检帧对应的原始图片用LabelImg打开检查该区域是否✓ 已标注为破损说明模型漏检需调低置信度阈值✗ 未标注说明是漏标需补充标注✗ 标注框覆盖了接缝/阴影说明标注不严谨需修正构建困难样本集并重训将误检图片加入训练集人工复核并修正标注然后用--resume参数从上一轮权重继续训练10轮python train.py --resume runs/train/conveyor_damage_v1/weights/last.pt --epochs 10提示每次修正标注后必须重新运行validate_labels.py脚本确保新增标签符合YOLOv5格式规范。工业场景中标注质量迭代比模型结构调优更能提升落地效果。5. 传送带破损检测的进阶技巧用TTA提升小目标召回率与跨光照鲁棒性5.1 TTATest Time Augmentation实战四方向翻转多尺度融合传送带破损常因拍摄角度、光照变化导致形态失真单一推理易漏检。YOLOv5原生支持TTA只需在推理时添加--augment参数# detect.py 推理命令 python detect.py \ --weights runs/train/conveyor_damage_v1/weights/best.pt \ --source inference/images/ \ --img 640 \ --conf 0.25 \ --augment \ --save-txt \ --save-conf--augment启用后模型会对每张图生成4种变换水平翻转、垂直翻转、双翻转3种尺度0.5, 1.0, 1.5倍共12次前向传播再用NMS融合结果。这显著提升小裂纹的召回率但推理速度下降约3倍。若需平衡速度与精度可定制轻量TTA# custom_tta.py def tta_inference(model, img, conf_thres0.25): # 原图推理 pred_orig model(img)[0] # 水平翻转 img_hflip torch.flip(img, [-1]) pred_hflip model(img_hflip)[0] pred_hflip[..., 0] img.shape[-1] - pred_hflip[..., 0] # 恢复x坐标 # 多尺度仅0.8和1.2倍 img_s08 torch.nn.functional.interpolate(img, scale_factor0.8, modebilinear) pred_s08 model(img_s08)[0] pred_s08[..., :4] * 1.25 # 恢复坐标 img_s12 torch.nn.functional.interpolate(img, scale_factor1.2, modebilinear) pred_s12 model(img_s12)[0] pred_s12[..., :4] * 0.833 # 恢复坐标 # 合并所有预测 all_preds torch.cat([pred_orig, pred_hflip, pred_s08, pred_s12], dim1) return non_max_suppression(all_preds, conf_thresconf_thres) # 使用 results tta_inference(model, img_tensor)5.2 光照鲁棒性增强在数据加载阶段注入CLAHE与Gamma校正传送带现场光照不均强反光区 vs 阴影区单纯靠模型学习难以泛化。我们在ConveyorDamageDataset.__getitem__()中插入预处理# dataset.py 中 __getitem__ 方法内追加 def apply_lighting_aug(img): # CLAHE增强对比度针对阴影区 clahe cv2.createCLAHE(clipLimit2.0, tileGridSize(8,8)) yuv cv2.cvtColor(img, cv2.COLOR_RGB2YUV) yuv[:,:,0] clahe.apply(yuv[:,:,0]) img cv2.cvtColor(yuv, cv2.COLOR_YUV2RGB) # Gamma校正针对过曝区 gamma np.random.uniform(0.8, 1.2) inv_gamma 1.0 / gamma table np.array([((i / 255.0) ** inv_gamma) * 255 for i in np.arange(0, 256)]).astype(uint8) img cv2.LUT(img, table) return img # 在 __getitem__ 中替换原图加载部分 img cv2.imread(img_path) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) if self.is_train: img apply_lighting_aug(img) # 仅训练时启用 img cv2.resize(img, (self.img_size, self.img_size))此操作使模型在不同光照条件下均能稳定提取破损纹理特征实测将强光反光区的误检率降低37%。5.3 破损严重程度分级从检测框回归到量化指标单纯“有/无破损”无法指导维护决策。我们扩展模型输出增加破损面积占比回归分支损坏等级面积占比处理建议Level 1 0.5%定期巡检Level 20.5%~3%下个停机周期更换Level 3 3%立即停机更换修改Detect层输出维度原[bs, na, nc5]变为[bs, na, nc6]末位新增面积占比回归值损失函数中加入L1 Loss# models/yolo.py 中 Detect.forward() 追加 area_pred torch.sigmoid(x[..., 5]) # 归一化面积占比 [0,1] loss_area F.l1_loss(area_pred, area_target) * 0.5 # 权重0.5 total_loss loss_area标注时人工计算破损区域像素面积 / 整张图面积存入标签文件第6列如0 0.423 0.567 0.123 0.045 0.021。此方案使模型输出兼具定位与量化能力真正支撑产线智能决策。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价