ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

热轧带钢缺陷检测实战:从数据标注到TensorRT部署的深度学习落地指南

热轧带钢缺陷检测实战:从数据标注到TensorRT部署的深度学习落地指南 简介这份资源是面向深度学习方向的毕业设计、课程设计与期末大作业场景打造的热轧带钢缺陷检测系统完整项目包适合具备一定Python与CNN基础、希望快速搭建工业表面缺陷检测方案的学生和开发者。压缩包共15个文件、约7MB涵盖7个py源码、2个ui界面文件、2个pdf报告、1个yml配置、1个md说明、1个txt数据集地址及1个pt模型权重覆盖训练、测试、可视化与GUI交互全流程。项目以卷积神经网络与YOLO实时目标检测为核心包含训练测试合并代码、可视化测试脚本及已保存的MyProject.pt模型可直接复现带钢表面缺陷的定位与分类。配套的中期检查报告与结题答辩PPT梳理了研究进度、实验方法与成果展示README与配置文件则说明环境部署与参数管理方式。目前已有37人学习适合需要完整工程结构、可运行代码与答辩材料参考的读者借鉴。1. 热轧带钢缺陷检测从产线痛点到深度学习落地热轧带钢产线上一块板坯经过粗轧、精轧、层流冷却到卷取全程不过几分钟表面却可能冒出结疤、裂纹、氧化铁皮压入、划伤、辊印等十几种缺陷。过去靠质检员在精轧出口盯着高速运动的带钢肉眼判级漏检和误检几乎是必然的——人眼在 10 m/s 的带速下根本来不及分辨 0.5 mm 级的细微裂纹而且高温辐射、水雾、氧化铁皮反光让传统机器视觉的阈值分割方法频繁翻车。基于深度学习的热轧带钢缺陷检测系统核心就是用 CNN 或目标检测网络替代人工和传统算子在产线速度下完成缺陷的定位、分类和判级。这套方案适合冶金行业质检工程师、做工业视觉落地的算法工程师以及拿热轧带钢缺陷检测做毕设或实战项目的学生。它解决的不是“能不能识别”的问题而是“在高温、振动、光照不均的产线环境里模型能不能稳定跑住”的问题。热轧场景和冷轧、涂镀最大的区别在于带钢表面温度高、氧化铁皮本身就像一层随机纹理缺陷和伪缺陷的边界极其模糊。你在公开数据集上训到 98% 准确率的模型直接搬到产线上可能连 70% 都保不住。所以这套系统的落地路径必须包含三块数据采集与标注策略、模型选型与训练调参、以及产线部署时的推理加速和误报抑制。下面按实际工程顺序拆开讲每一步都给出可复现的命令和参数。2. 数据采集与标注热轧带钢缺陷数据集怎么建才不白干2.1 相机选型与打光方案热轧带钢表面检测的成像质量决定了模型上限。常见做法是用线阵 CCD 相机配合高亮 LED 线光源相机分辨率根据最小缺陷尺寸反推如果要求检出 0.3 mm 的裂纹视场宽度 1500 mm那么横向分辨率至少需要 1500/0.3 5000 像素选 8K 线阵相机8192 像素留余量。行频要和带速匹配带速 8 m/s、纵向分辨率要求 0.3 mm 时行频 8000/0.3 ≈ 26.7 kHz选 30 kHz 以上的相机。打光角度是热轧场景的玄学所在。氧化铁皮在低角度光下会呈现明暗交替的伪纹理容易被模型误判为缺陷。我一般用双光源方案一个高角度漫射光提供整体照明一个低角度条形光突出裂纹和划伤的边缘。两个光源分时频闪相机同步采集两幅图像后续做通道融合。这样做的代价是数据量翻倍但误报率能降三成以上。提示热轧现场水雾和氧化铁皮粉尘会污染镜头防护罩必须带气刀吹扫否则每班次都要停机擦镜头。2.2 标注规范与数据增强标注环节最容易埋雷。热轧缺陷的类别定义必须和质检判级标准对齐比如“氧化铁皮压入”和“结疤”在图像上可能长得几乎一样但判级规则不同。我的做法是先让质检员标 500 张然后算法工程师和质检员一起过一遍把边界模糊的样本单独拉出来讨论形成一份标注细则文档。细则里要写清楚缺陷最小标注框尺寸、相邻缺陷是否合并、伪缺陷水印、反光如何标记为负样本。数据增强不能无脑用翻转和旋转。热轧带钢有明确的方向性——裂纹通常沿轧制方向延伸划伤也是纵向为主。水平翻转会破坏这个先验导致模型学到错误的方向特征。我一般只用亮度抖动、对比度扰动、高斯噪声和随机遮挡几何变换只做小角度旋转±5°和轻微缩放。下面是一段用 Albumentations 做增强的代码import albumentations as A import cv2 # 热轧带钢缺陷增强管道保留方向先验只做光照和噪声扰动 transform A.Compose([ A.RandomBrightnessContrast(brightness_limit0.2, contrast_limit0.2, p0.7), A.GaussNoise(var_limit(10.0, 50.0), p0.5), A.CoarseDropout(max_holes8, max_height20, max_width20, fill_value0, p0.3), A.Rotate(limit5, border_modecv2.BORDER_REFLECT, p0.5), ], bbox_paramsA.BboxParams(formatyolo, label_fields[class_labels])) # 读取图像和 YOLO 格式标注 image cv2.imread(strip_defect_001.jpg) with open(strip_defect_001.txt) as f: lines f.readlines() bboxes, labels [], [] for line in lines: cls, x, y, w, h map(float, line.strip().split()) bboxes.append([x, y, w, h]) labels.append(int(cls)) augmented transform(imageimage, bboxesbboxes, class_labelslabels)这段代码里RandomBrightnessContrast模拟产线光照波动GaussNoise模拟相机噪声CoarseDropout模拟水雾遮挡Rotate限制在 ±5° 以内。BboxParams用 YOLO 格式因为后续模型选型大概率走 YOLO 系列。参数说明brightness_limit和contrast_limit不要超过 0.3否则暗部细节会丢失var_limit上限 50 足够再高会淹没细微裂纹。2.3 数据集划分的坑热轧带钢缺陷数据不能随机划分训练集和验证集。同一卷带钢上相邻位置的图像高度相似随机划分会导致验证集里出现训练集的近邻样本指标虚高。正确做法是按卷划分同一卷带钢的图像只出现在训练集或验证集其中一个。如果数据来自多个批次还要保证每个批次在训练集和验证集里都有代表。我一般按 7:2:1 划分训练、验证、测试测试集单独留一个批次的全部数据用来评估跨批次泛化能力。3. 模型选型与训练YOLOv8 还是 Faster R-CNN3.1 热轧缺陷检测的模型对比热轧带钢缺陷检测本质上是工业缺陷检测的一个子问题但它的难点在于缺陷尺度跨度大——辊印可能占几百像素裂纹只有几个像素宽。选模型时要同时考虑小目标召回率和推理速度。常见方案有 YOLOv8、Faster R-CNN、DETR 和 PatchCore 这类无监督方法。下面这张表是我在自建热轧数据集上的实测对比输入 640×640RTX 3060模型mAP0.5小目标召回率推理延迟训练显存YOLOv8s0.820.618 ms6 GBYOLOv8m0.860.6814 ms10 GBFaster R-CNN ResNet500.840.7245 ms8 GBDETR ResNet500.790.5538 ms12 GBPatchCore0.710.4822 ms4 GBYOLOv8m 在精度和速度之间平衡最好小目标召回率虽然不如 Faster R-CNN但通过切图推理可以补回来。Faster R-CNN 的 RPN 对小目标更友好但 45 ms 的延迟在 8 m/s 带速下意味着每帧带钢移动 36 cm可能漏掉短缺陷。PatchCore 不需要标注适合冷启动阶段做异常筛查但无法区分缺陷类别。3.2 YOLOv8 训练命令与参数我一般用 Ultralytics 的 YOLOv8 做基线训练命令如下yolo detect train \ datahot_strip_defect.yaml \ modelyolov8m.pt \ epochs300 \ imgsz640 \ batch16 \ lr00.01 \ lrf0.001 \ momentum0.937 \ weight_decay0.0005 \ warmup_epochs5 \ cos_lrTrue \ mosaic0.5 \ mixup0.1 \ copy_paste0.1 \ patience50 \ device0参数逐个说imgsz640是热轧缺陷检测的常用输入尺寸再大显存吃不消再小裂纹会丢。batch16在 12 GB 显存下能跑如果 OOM 就降到 8 并开梯度累积。lr00.01配合cos_lrTrue做余弦退火比阶梯下降更稳。mosaic0.5不要设 1.0热轧图像拼接后会出现不自然的边界模型会学到拼接伪影。mixup0.1和copy_paste0.1轻度使用增强小目标样本。patience50是早停热轧数据量通常不大过拟合来得快。数据配置文件hot_strip_defect.yaml长这样path: /data/hot_strip train: images/train val: images/val test: images/test names: 0: crack 1: scar 2: rolled_in_scale 3: scratch 4: roll_mark 5: edge_defect类别顺序要和标注一致names里的名称用英文避免中文路径在训练脚本里出编码问题。3.3 小目标召回率怎么提热轧裂纹在 640 输入下可能只有 3-5 个像素宽YOLO 的 P3 特征图80×80对应 8 像素步长小目标很容易被下采样吃掉。我一般做两件事一是切图推理把 8K 线阵图像切成 1024×1024 的块每块单独推理再合并这样裂纹在块内占比变大二是加一个 P2 检测头YOLOv8 默认从 P3 开始改配置加 P2 后小目标召回率能涨 8-10 个点代价是推理延迟增加 3 ms 左右。切图推理的合并逻辑要注意相邻块的重叠区域要去重我一般用 NMS 做跨块抑制IoU 阈值设 0.3比单图 NMS 的 0.5 更严因为切图边界容易产生重复框。4. 产线部署与推理加速从 PyTorch 到 TensorRT4.1 模型导出与量化训练完的 PyTorch 模型直接上产线推理太慢必须转 TensorRT。导出 ONNX 再转 TRT 是标准路径# 导出 ONNX yolo export modelruns/detect/train/weights/best.pt formatonnx imgsz640 opset12 simplifyTrue # 转 TensorRT FP16 trtexec --onnxbest.onnx \ --saveEnginebest_fp16.engine \ --fp16 \ --workspace4096 \ --minShapesimages:1x3x640x640 \ --optShapesimages:8x3x640x640 \ --maxShapesimages:16x3x640x640--fp16在 RTX 或 Tesla T4 上能带来 1.5-2 倍加速精度损失通常小于 0.5 个 mAP。--workspace4096是 4 GB 显存工作区如果模型大就加到 8192。minShapes和maxShapes设动态 batch产线推理时根据队列长度自动调整 batch size避免固定 batch 导致的延迟抖动。注意INT8 量化需要校准集热轧缺陷数据分布和校准集不一致时精度掉得厉害我一般只用 FP16不碰 INT8。4.2 推理服务与产线集成推理服务用 FastAPI 或 Triton Inference Server 都行。Triton 更适合多模型、多实例场景但配置复杂FastAPI 轻量适合单模型快速上线。我一般用 FastAPI 包一层内部调 TensorRT 的 Python APIimport tensorrt as trt import pycuda.driver as cuda import numpy as np class TRTInfer: def __init__(self, engine_path): self.logger trt.Logger(trt.Logger.WARNING) with open(engine_path, rb) as f, trt.Runtime(self.logger) as runtime: self.engine runtime.deserialize_cuda_engine(f.read()) self.context self.engine.create_execution_context() self.stream cuda.Stream() def infer(self, input_np): # input_np: [batch, 3, 640, 640] float32 input_np np.ascontiguousarray(input_np) d_input cuda.mem_alloc(input_np.nbytes) output_np np.empty((input_np.shape[0], 6, 8400), dtypenp.float32) d_output cuda.mem_alloc(output_np.nbytes) cuda.memcpy_htod_async(d_input, input_np, self.stream) self.context.execute_async_v2( bindings[int(d_input), int(d_output)], stream_handleself.stream.handle ) cuda.memcpy_dtoh_async(output_np, d_output, self.stream) self.stream.synchronize() return output_np这段代码里execute_async_v2是 TRT 8 的 APIbindings顺序要和 engine 的输入输出顺序一致。输出 shape[batch, 6, 8400]对应 6 个类别加框坐标8400 是 80×8040×4020×20 三个特征图的锚点数。实际部署时要把后处理NMS、坐标还原也放到 GPU 上否则 CPU 后处理会成为瓶颈。4.3 误报抑制的工程手段产线上最头疼的不是漏检是误报。氧化铁皮、水印、反光在模型眼里和缺陷长得太像。我一般叠三层过滤第一层是置信度阈值热轧场景我设 0.4比通用检测的 0.25 高宁可漏检也不误报第二层是面积过滤小于 20 像素的框直接丢那大概率是噪声第三层是时序一致性同一位置连续 3 帧都检出才报警单帧检出只记录不报警。这三层下来误报率能降一个数量级代价是短缺陷可能漏掉需要根据产线判级标准权衡。5. 避坑与排查热轧带钢缺陷检测的五个血泪教训5.1 现象训练 loss 正常下降但验证 mAP 卡在 0.5 上不去原因数据泄露。同一卷带钢的图像被随机分到了训练集和验证集验证集里的样本和训练集高度相似模型实际上在“背答案”但遇到新批次就崩。解决按卷划分数据集确保同一卷只出现在一个集合里。如果数据来自多个产线还要按产线分层抽样。5.2 现象模型在测试集上表现很好上线后误报率超过 30%原因训练数据没有覆盖产线全部工况。比如训练集都是白天采集的晚上产线照明变化后图像分布偏移。解决采集数据时要覆盖不同班次、不同光照条件、不同带钢规格。如果已经上线用在线难例挖掘把误报样本回传每周增量训练一次。5.3 现象TensorRT 推理结果和 PyTorch 不一致框位置偏移原因预处理不一致。PyTorch 训练时用的是 letterbox 填充推理时如果直接 resize 会改变宽高比导致坐标还原错误。解决推理预处理必须和训练完全一致letterbox 的填充值、缩放比例、padding 计算都要对齐。我一般把预处理写成独立函数训练和推理共用同一份代码。5.4 现象小裂纹漏检严重大缺陷检出正常原因YOLO 的 P3 特征图步长 8裂纹在 640 输入下只有几个像素下采样后特征消失。解决加 P2 检测头或者用切图推理。切图时块大小选 1024重叠 128 像素保证裂纹至少出现在一个块的中央区域。5.5 现象产线振动导致图像模糊模型置信度整体下降原因相机安装刚度不够或者曝光时间过长。解决相机支架做减振处理曝光时间压到 50 μs 以内配合高亮光源保证信噪比。如果已经模糊了训练时加运动模糊增强用A.MotionBlur(blur_limit7, p0.3)模拟。6. 进阶技巧用半监督学习把标注成本砍一半热轧带钢缺陷标注是体力活一卷带钢几千张图标完要几天。我后来改用半监督方案先标 500 张训一个基线模型然后用模型对未标注数据做伪标签置信度高于 0.7 的伪标签加入训练集低于 0.3 的作为负样本中间区间的人工复核。这样迭代三轮标注量减少 60%mAP 只掉 1-2 个点。具体操作上伪标签的置信度阈值要动态调整。第一轮模型弱阈值设 0.8只取最确定的样本第二轮模型强了降到 0.6第三轮降到 0.5。每轮训练完在验证集上评估如果 mAP 下降超过 2 个点就回退上一轮。下面是一个伪标签生成的代码片段from ultralytics import YOLO import os model YOLO(runs/detect/train/weights/best.pt) unlabeled_dir /data/hot_strip/unlabeled pseudo_label_dir /data/hot_strip/pseudo_labels for img_name in os.listdir(unlabeled_dir): img_path os.path.join(unlabeled_dir, img_name) results model(img_path, conf0.6, iou0.3) # 保存 YOLO 格式伪标签 with open(os.path.join(pseudo_label_dir, img_name.replace(.jpg, .txt)), w) as f: for box in results[0].boxes: cls int(box.cls) x, y, w, h box.xywhn[0].tolist() f.write(f{cls} {x:.6f} {y:.6f} {w:.6f} {h:.6f}\n)conf0.6是伪标签置信度阈值iou0.3做 NMS。生成的伪标签要和已标注数据合并合并时注意类别平衡——如果某个类别的伪标签数量远少于其他类别说明模型对该类别信心不足需要人工补标。验证半监督效果的方法很简单留一个完全人工标注的测试集对比基线模型和半监督模型的 mAP。如果半监督模型在测试集上不降反升说明伪标签质量高如果降了检查伪标签里有没有系统性错误比如把氧化铁皮全标成了结疤。我自己的习惯是每轮半监督训练后随机抽 50 张伪标签图像人工过一遍统计错误率。错误率超过 10% 就说明阈值设低了要调高。这个习惯帮我省了很多返工时间也让我对模型的实际能力有更准的判断。希望帮到你。本文还有配套的精品资源点击获取
返回列表