ARTICLE DETAIL

资讯详情

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

YOLOv11与多模态融合:工业质检落地实战与避坑指南

YOLOv11与多模态融合:工业质检落地实战与避坑指南 简介面向工业质检领域算法工程师与产线技术人员的技术文档聚焦YOLOv11与多模态数据融合在复杂缺陷检测中的落地路径。内容共28页从工业质检背景与挑战切入系统讲解YOLOv11的网络架构、核心算法与训练策略并围绕数据层、特征层、决策层展开多模态融合方案覆盖汽车零部件、航空航天、电子元器件、钢铁冶金、木材加工五大行业案例同时提供项目规划、模型调优、系统部署与运维等实战经验。资源包为1个PDF大小2.12MB目录支持章节跳转排版完整清晰便于按图索骥快速定位所需内容。目前已有213人学习下载适合希望深入掌握目标检测工程化应用及多模态融合策略的进阶读者参考使用。1. 工业质检为什么盯上 YOLOv11多模态数据融合先从复杂缺陷说起产线上的金属件表面缺陷检测老师傅一眼能看出的问题传统机器视觉方案却经常翻车。不是算法笨而是单一光源下一张灰度图能提供的信息量太少划伤和纹理边界分不开针孔和油污长得一模一样反光区域里缺陷彻底隐身。把多个成像通道——RGB、深度、红外甚至不同角度光源下的画面——当成多个模态一起喂给检测模型缺陷与背景的可区分度才会真正拉开。YOLOv11 这类 anchor-free 结构的实时检测器在精度和速度上能压住产线节拍配合多模态数据融合正好把复杂缺陷检测拉回工程可行域。这篇文章按一线工业视觉项目最常见的落地方案讲清楚选型理由、融合做法、训练参数和部署细节适合正在评估 AI 视觉工业质检方案、准备在自己产线上试点验证的工程师。2. YOLOv11 选型与训练环境从网络结构改动点到显卡上能跑的配置2.1 从网络结构看 YOLOv11 为工业质检准备了什么YOLOv11 是 Ultralytics 在 YOLOv8 之后推出的目标检测系列结构上仍然走 backbone、neck、head 三件套但内部替换了不少关键模块。对工业质检来说我第一眼关注的是它把检测头改成了 anchor-free 解耦结构分类分支和回归分支分开输出这让低对比度缺陷的定位和分类不再互相干扰。第二个值得注意的点是 C3k2 模块替代了之前常见的 C3计算量下降但感受野保持得不错在小目标缺陷上表现比同类轻量网络稳。neck 里的 C2PSA 带了自注意力对背景纹理复杂、目标形态不规则的缺陷有一定抑制作用像金属拉丝表面上的细微划伤这类“背景强干扰”场景正好吃这一套。从落地角度讲YOLOv11 把过往 YOLO 系列里那些“看起来厉害但跑不动”的结构做了删减n/s/m/l/x 几个规格覆盖了从 Jetson Nano 到工控机独显的算力区间。很多刚接触 AI 视觉工业质检的朋友一上来就问“哪个模型最强”我的经验是先选 s 或 m产线缺陷检测不是打榜漏杀和过杀都要用真实数据反复磨结构太重的模型训一轮就要多花几倍时间调参周期拉长后反而不划算。把网络结构打出来看一眼是熟悉模型最快的方式用 Ultralytics 自带的 Python API 就能直接打印不需要翻训练的源码。from ultralytics import YOLO # 载入预训练权重会自动下载 yolo11s.pt model YOLO(yolo11s.pt) # 打印完整的网络结构逐层看 backbone/neck/head 的模块组成 print(model.model) # 只筛选关键模块名快速确认 C3k2、SPPF、Detect head 是否按预期加载 for name, module in model.model.named_modules(): cls_name type(module).__name__ if C3k2 in cls_name or SPPF in cls_name or Detect in cls_name: print(name, cls_name)这段代码的作用是把网络结构从“黑匣子”变成可检查的清单。第一次拿到 YOLOv11 时先跑一遍确认预训练权重加载正常再开始改配置。实际项目中我还会顺手把每个模块的参数量打印出来方便对比不同规格模型在部署设备上的内存占用。需要注意 Ultralytics 的版本要统一训练、导出、部署用同一套版本否则容易出现权重兼容问题。2.2 YOLOv11 环境配置与最小训练命令YOLOv11 的环境配置在目标检测框架里算最省心的那档核心依赖就是 PyTorch 和 Ultralytics 包。建议用 Python 3.9 以上版本PyTorch 按自己显卡的 CUDA 版本安装然后 pip 装 ultralytics 即可。很多现场工程师的环境里同时有别的深度学习项目我一般会建独立 conda 环境避免依赖相互打架。# 创建独立环境规避与其他项目的依赖冲突 conda create -n yolov11 python3.10 -y conda activate yolov11 # 安装 PyTorch这里按 CUDA 12.1 的版本示例实际以你的驱动为准 pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121 # 安装 Ultralytics pip install ultralytics # 验证是否装好用一张任意图片做推理测试 yolo predict modelyolo11s.pt source./sample.jpg推理测试能通过说明环境基本没问题。接着要确认训练链路通不通直接用官方 COCO 预训练权重跑一个极短的训练任务这一步能尽早暴露数据集路径、标注格式、显存这些基础问题。yolo detect train \ modelyolo11s.pt \ datadefect.yaml \ epochs20 \ imgsz640 \ batch8 \ device0命令里几个参数是必须说清楚的epochs20只是验证链路用的迭代数正式训练后文会给完整参数imgsz640是默认分辨率小目标缺陷建议往上加但显存成本同步上升batch8要根据显卡显存动态调整显存不够就降到 4 或 2训练慢一点总比 OOM 中断好。跑通一次哪怕损失函数曲线再难看也比零报错更重要因为这条链路后续要反复用。2.3 小目标缺陷的改进方向切块推理与 P2 检测头复杂缺陷里小目标占比普遍不低金属表面的针孔、微小裂纹、焊点气泡往往只有十几个像素。YOLOv11 默认下采样倍率到 32 倍时这些缺陷在深层特征图上只剩一两个像素点检测头能拿到的信息近乎为零。解决小目标问题最基本的两个手段一是切块推理二是增加 P2 检测头。P2 检测头需要改动模型 yaml 结构不是改一行配置就能搞定切块推理则可以在不改模型的前提下立刻见效适合先验证产线对小目标的真实需求。from ultralytics import YOLO model YOLO(yolo11s.pt) def infer_tile(img, tile640, overlap64, conf0.25): 对大图做切块推理解决小目标因下采样丢失导致的漏检。 h, w img.shape[:2] detections [] for y0 in range(0, h, tile - overlap): for x0 in range(0, w, tile - overlap): crop img[y0:y0 tile, x0:x0 tile] results model.predict(crop, imgsztile, confconf) for box in results[0].boxes: x1, y1, x2, y2 box.xyxy[0].tolist() detections.append([ x0 x1, y0 y1, x0 x2, y0 y2, float(box.conf[0]), int(box.cls[0]) ]) return detections这段代码的思路是把原图切成多个 640×640 的块分别推理再还原到大图坐标系下。切块后小目标在输入图里的相对尺寸变大网络能提取到的特征更充足漏检率通常明显下降。overlap64是给相邻块留的重叠区域避免缺陷恰好被切在两块边界上导致重复检测或漏检。代价是推理次数成倍增加节拍压力大时要把 tile 和 overlap 调小来平衡。我在产线项目里一般先测切块推理确认收益后再考虑改网络结构这样改动风险更小。3. 多模态数据融合的落地做法成像对齐、特征融合与数据管道3.1 先想清楚模态哪些数据值得融哪些只是凑数多模态数据融合这个词听起来高级但工业现场的“模态”必须落到成像设备上。我见过最务实的分类是按信息维度划分RGB 提供颜色和纹理深度图提供高度和凹凸信息红外热像提供温度分布多角度光源提供不同辐照条件下的表面反射特性。选择哪些模态取决于缺陷本身的物理特性——划伤和凹坑在深度图上区分度极高色差类缺陷在 RGB 下更明显虚焊和热应力裂纹则要靠红外。模态组合和适用缺陷的对应关系我整理成一张表方便评估时快速对号入座。模态组合适合的缺陷类型设备成本落地难度RGB 多角度光源划伤、反光表面缺陷、纹理干扰低低RGB 深度图凹坑、凸起、虚焊、胶路断胶中中RGB 红外热像虚焊、热裂纹、电阻类缺陷高高RGB 高光谱材质混料、极轻微色差很高很高我的建议是先从低成本模态组合开始把多光源当成多模态融合的第一步。很多缺陷在特定角度光源下会现出原形而单张图里它就是一片灰。等确认了缺陷确实需要额外维度的信息再上深度或红外避免项目一上来就堆设备最后发现部分通道一点贡献都没有。别被“多模态”三个字架住它本质是“给模型更多能区分缺陷的信号”。3.2 数据对齐比融合更重要像素级配准与离线校验多模态融合最隐蔽的坑不是网络结构而是模态之间的像素对齐。RGB 相机和深度相机安装位置不同视野有偏差直接把两个通道拼在一起喂给网络模型的收敛会被不一致的图像内容干扰。我见过不止一个项目在融合阶段折腾了两个月最后发现深度图和 RGB 图之间存在几个像素的平移缺陷位置在两幅图里根本没对准。处理对齐的常见做法是先做相机标定算出两个传感器之间的单应性矩阵再对深度图做透视变换把深度图映射到 RGB 图的坐标系下。这一步的产出应该是一张拼合图像方便肉眼直接检查对齐效果——不建议直接跳到模型训练人眼确认过的对齐质量才可靠。import cv2 import numpy as np # 读入同一时刻采集的 RGB 图和 16bit 深度图 rgb cv2.imread(rgb.png) depth_raw cv2.imread(depth.png, cv2.IMREAD_UNCHANGED) # 深度图归一化避免全图 min-max 把前景细节压扁 roi depth_raw[100:900, 100:1200] depth_norm cv2.normalize(roi, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8) depth_bgr cv2.applyColorMap(depth_norm, cv2.COLORMAP_JET) # 加载标定得到的单应性矩阵把深度图投影到 RGB 视角 H np.load(align_homography.npy) depth_aligned cv2.warpPerspective(depth_bgr, H, (rgb.shape[1], rgb.shape[0])) # 拼成一张图做人工校验同时保留 6 通道数据用于后续训练 multi np.concatenate([rgb, depth_aligned], axis-1) cv2.imwrite(check_alignment.png, np.hstack([rgb, depth_aligned]))这段代码里最值得注意的细节是深度图归一化。很多人的第一反应是直接对整张深度图做 min-max 归一化结果背景区域站了大部分灰度范围前景缺陷的微弱高度差被彻底压没。我习惯先框定目标出现的 ROI在 ROI 内做归一化这样缺陷的高度差异才能保留下来。warpPerspective之后还要人工抽查几个特征点确保障碍物边缘、工件轮廓在两张图里位置一致再进入下一步。这一步的数据流设计决定了后续融合的上限。像素级配准是地基地基没打好融合网络设计得再精巧也只能学到模态之间的噪声对应关系。3.3 两种融合结构输入级拼接与特征级注意力融合多模态融合在算法层面通常分成输入级和特征级两种我都跑过落地节奏差别很大。输入级融合最直接把 RGB 和深度/红外在通道维度拼接成 6 通道输入模型第一层卷积从 3 通道改成 6 通道其他结构完全不动。这个方案改动小、训练快特别适合项目前期验证多模态到底有没有价值。用 Ultralytics 加载 YOLOv11 后直接替换第一个卷积层就能把输入从 3 通道扩展成 6 通道预训练权重的前三个通道可以保留复用新增通道用原权重的平均复制初始化。import torch from ultralytics import YOLO model YOLO(yolo11s.pt) # 第一层卷积原来是 3 通道输入改成 6 通道 old_conv model.model.model[0] new_conv torch.nn.Conv2d( 6, old_conv.conv.out_channels, kernel_sizeold_conv.conv.kernel_size, strideold_conv.conv.stride, paddingold_conv.conv.padding ) with torch.no_grad(): # 前 3 个通道继承原权重后 3 个通道用前 3 通道的均值初始化 new_conv.weight[:, :3] old_conv.conv.weight new_conv.weight[:, 3:] old_conv.conv.weight.mean( dim1, keepdimTrue ).expand(-1, 3, -1, -1) model.model.model[0] new_conv这段代码的关键在于权重继承策略。直接把新通道权重置零会导致训练初期梯度异常置成原权重的平均值可以让新通道在初始阶段输出相对平滑的特征网络更容易稳定收敛。训练时要注意关掉或降低 mosaic 增强因为 mosaic 会把四张不同图拼在一起多模态通道的对应关系会被打乱模型等于在学错误的对齐模式。特征级融合是更进阶的做法RGB 和深度各自过 backbone 编码在 neck 位置把特征层拼接起来再用可学习的权重或注意力机制决定每个模态的贡献。这里我常用的一个简洁结构是给两个模态的特征各接一个 1×1 卷积投影到相同维度然后引入可学习的模态权重做加权求和。类似 HCANet 那种把注意力机制用在跨尺度融合上的思路在工业缺陷场景下比简单拼接更稳。import torch.nn as nn class ModalFusion(nn.Module): 特征级模态融合用可学习权重动态调整 RGB 与深度的贡献。 def __init__(self, rgb_ch, depth_ch, out_ch): super().__init__() self.rgb_proj nn.Conv2d(rgb_ch, out_ch, 1) self.depth_proj nn.Conv2d(depth_ch, out_ch, 1) self.modal_weight nn.Parameter(torch.ones(1, 2, 1, 1)) def forward(self, rgb_feat, depth_feat): rgb_feat self.rgb_proj(rgb_feat) depth_feat self.depth_proj(depth_feat) w torch.softmax(self.modal_weight, dim1) return w[:, 0] * rgb_feat w[:, 1] * depth_feat特征级融合的优点是模型能根据缺陷类型自适应地选择信息更丰富的模态在复杂场景下的上限更高缺点是需要改造网络结构调试难度大训练时间也长。我一般建议项目按“输入级验证价值、特征级提升上限”的节奏走先用输入级融合快速跑通实验确认多模态有收益再切换到特征级融合做精度优化。直接上特征级融合而跳过输入级验证等于在还没确认原材料有价值的时候就开始做精细加工出了问题很难定位是融合结构的问题还是模态本身的问题。4. 复杂缺陷检测实战标注策略、训练参数与部署评测4.1 标注策略类别怎么定背景负样本怎么加多模态数据准备好了标注策略直接决定模型能否收敛出可用的检测器。复杂缺陷的标注第一原则是按形态分不按成因分。同样一条划痕可能是来料磨损造成的也可能是加工过程磕碰造成的但从图像上看就是一条线状缺陷机器没有能力、也没有必要区分成因。类别设计越贴近视觉形态模型学起来越容易。我经手的项目里类名一般压到 3~6 个超过 6 类标注一致性和模型精度都会明显下降。典型的数据集组织和数据集配置文件如下所示path指向数据集根目录train和val指向图片目录names按类别序号排列。标注文件每行内容为“类别 x1 y1 x2 y2”坐标是归一化后的值。# defect_multi.yaml path: /data/defect_plus_depth train: images/train val: images/val names: 0: scratch 1: pinhole 2: bubble 3: contaminant标注圈框的原则是宁紧勿松框要紧贴缺陷边缘背景多圈进去一个像素模型就多学一份噪声。这里有个新手容易踩的坑只标“有缺陷”的样本不标“无缺陷”的负样本。深度学习的检测器在训练时会把没有标注框的区域当作背景如果整个数据集全是正样本模型对背景的建模就严重不足上线后误报率会高到没法用。我一般会在训练集里混入 20%~30% 的纯负样本图并且这些负样本图的采集工况要和正样本一致否则模型会靠“是不是这条产线拍的”来做判断泛化能力大打折扣。4.2 训练参数从收敛曲线到置信度阈值YOLOv11 训练参数比 YOLOv5 时代多了不少但工业质检真正需要反复调的其实就那几个。下面是多模态缺陷检测项目里比较稳的一组训练配置以 s 模型、单卡 24GB 显存为基准。yolo detect train \ modelyolo11s.pt \ datadefect_multi.yaml \ epochs200 \ imgsz640 \ batch16 \ lr00.01 \ optimizerAdamW \ mosaic0.5 \ close_mosaic10 \ patience30 \ workers8 \ device0 \ projectruns/defect \ namergbd_v1参数我常用的值说明imgsz640~1024小目标多就调大显存不够先减 batchmosaic0.5多模态场景不要开满模态配对齐会被拼图打乱close_mosaic10最后 10 个 epoch 关掉 mosaic让模型在真实分布上收敛patience30验证集指标连续 30 个 epoch 不涨就早停optimizerAdamW收敛稳对 lr 的敏感度弱于 SGDlr00.005~0.01batch 越大 lr 可以越高16 时 0.01 起步安全训练过程要盯的不是训练集 loss而是验证集上的 P 和 R 曲线。训练集 loss 降到低位但验证集指标不动大概率是过拟合或者标注噪声太大验证集指标上下乱跳可能是模态对齐问题也可能是某个类别样本量太少。我在每次 epoch 结束后会看一眼保存下来的预测样例图比任何指标都直观。4.3 评估不止看 mAP过杀率、漏杀率与样本级指标工业质检的评估体系和学术目标检测不一样。mAP 高不代表能上线产线上真正让人头疼的是过杀和漏杀过杀是把合格品当缺陷拦下来造成产线拥堵漏杀是缺陷品混出去这是质量事故。我习惯用样本级指标来评估不只看框级 mAP。import json with open(val_pred.json) as f: preds json.load(f) with open(val_gt.json) as f: gts json.load(f) # 把 GT 和预测都按“图类别”分组做样本级统计 def group(items): groups {} for it in items: groups.setdefault((it[img_id], it[cls]), []).append(it) return groups pred_g, gt_g group(preds), group(gts) missing, overkill 0, 0 for key, gt_items in gt_g.items(): pred_items pred_g.get(key, []) hit any(p[conf] 0.3 for p in pred_items) missing not hit for key, pred_items in pred_g.items(): if key not in gt_g: overkill 1 print(漏杀率:, missing / max(len(gt_g), 1)) print(过杀率:, overkill / max(len(pred_g), 1))这段代码的核心逻辑是按“哪张图、哪个缺陷类别”做维度只要该图该类下存在置信度超过阈值的预测框就认为缺陷被命中了不再关心框级 IoU 是否完美贴合。这样算出来的漏杀率、过杀率直接对应质检员和产线管理者能听懂的指标。框级 IoU 匹配需要在框与框之间做分配stage 级的评估在项目早期更实用。我在项目里真正盯的接受标准是过杀率压到 3% 以下、漏杀率压到 1% 以下。达不到就按缺什么补什么来迭代漏杀高优先加难例样本、调小目标优化过杀高优先压置信度阈值、加负样本、检查标注一致性。4.4 部署到 Jetson Nano 或工控机导出与加速训练收敛后进入部署环节。常见部署设备是 NVIDIA Jetson Nano 这类边缘盒子或工控机加 GPU 卡。无论哪种导出成 TensorRT 引擎都是提速的关键一步。PYTHON 环境下直接推理 .pt 权重虽然简单但动态尺寸和 FP32 精度对 Jetson Nano 这种小显存设备是双重负担推理速度往往只有 TensorRT FP16 的一半不到。# 导出 TensorRT 引擎固定输入尺寸并开启半精度加速 yolo export modelruns/defect/rgbd_v1/weights/best.pt \ formattensorrt \ imgsz640 \ halfTrue导出的 .engine 文件直接替换原来的 .pt 权重做推理即可。如果在 Jetson Nano 上部署我会特别强调固定输入尺寸有多重要动态尺寸会触发 TensorRT 重新选择 kernel每次推理都多出几十毫秒开销产线上这就是按秒累积的。用 yolo11n 加 TensorRT FP16 通常能跑到实时还不够的话就回到 2.3 节的切块方案把分辨率和块尺寸一起压下来。部署后的又一次验证必须用产线实拍图重新跑一遍不能用训练集和验证集的图这部分脏数据带来的精度损失往往超出很多人的预期。5. 工业质检避坑指南YOLOv11多模态融合的常见问题排查5.1 验证集 mAP 很高过杀率却压不下来这是一个非常迷惑人的现象模型在验证集上精度漂亮一上产线就疯狂报警质检员一天到晚在跟误报搏斗。原因多数出在置信度阈值和数据分布上。验证集的标注框全是“相对标准的缺陷”而产线上大量存在的是边缘形态缺陷——半截划痕、轻微压痕、可疑脏点这些样本在验证集里没有对应标注模型就倾向于把它们也当作目标框出来。解决思路要从两个方向同时下手。第一把置信度阈值从默认的 0.25 往上提到 0.4 甚至 0.5先看过杀率是否回落这一步成本最低。第二把产线采集到的“难负样本”加进训练集这类样本的特征是“像缺陷但不是缺陷”它们就是过杀率降不下来的根源。我见过一个密封圈检测项目加了 2000 张难负样本后过杀率直接从 25% 降到 4%模型结构一行代码没改。5.2 加了深度或红外通道精度反而比单模态更差多模态融合并不是通道越多越好。深度图跟 RGB 图没有对齐红外图里有大量与缺陷无关的环境热噪声这些脏信号被网络当成有效特征学进去精度自然往下掉。遇到这种情况先别急着怪融合网络返回去查数据质量。第一步检查像素级对齐用 3.2 节的可视化脚本把拼接图逐张翻一遍确认工件边缘、定位孔、纹理特征在模态之间完全重合。第二步是逐个模态做消融实验只用 RGB 训一版只用深度训一版再用融合通道训一版哪一版精度最低就说明那个模态在拖后腿。如果深度图单独训的效果很差融合后把 RGB 的精度也带崩了这个模态在现阶段就是负资产果断去掉比硬融更有工程价值。5.3 Jetson Nano 上推理从演示变卡顿开发机上推理流畅部署到 Jetson Nano 后直接卡成幻灯片这是边缘部署最常见的摔跤。原因基本是三点没导出 TensorRT、用了动态尺寸、开了 FP32。开发机的 GPU 显存和算力远强于 Jetson Nano同样的模型在两端性能差距可能有四五倍。按照 4.4 节的导出命令重新生成 TensorRT 引擎固定 imgsz 为 640开启 half 精度通常能让推理时间降到原来的三分之一左右。如果还嫌慢把模型从 yolo11s 降到 yolo11n或者对输入图做缩放加切块牺牲一点精度换节拍。这里我的经验是部署板子到手的第一天就装上 TensorRT 跑一个基准测试别等模型训完再折腾那时候时间成本已经很贵了。5.4 小目标缺陷一批一批漏检指标全被拖垮小目标缺陷漏检在多模态融合项目里同样常见因为新增的深度或红外通道在浅层特征上的分辨率往往更低小目标的信息被进一步稀释。现象是第一轮验证时中大型缺陷全检出来了单独看小目标类别的召回率只有三四成。原因有两层一是下采样倍数太高小目标在深层特征图上只剩零星几个激活值二是小目标样本在训练集里占比天然偏低正样本数量不足模型学不好。解决方向按顺序来先用 2.3 节的高重叠切块推理验证能不能把小目标召回提上来同时把训练集里小目标样本的占比人为抬高比如对小目标区域做复制增强。P2 检测头是更彻底的手段但需要改网络结构并做更长的调参周期建议放到前两步做完仍然不够时再上。5.5 换了一个班次的光源模型效果就漂移工业现场的光照稳定性永远是个玄学问题。白天自然光透过窗户漏进来夜班换了不同色温的照明灯甚至产品批次表面颜色有细微差异都会让模型精度肉眼可见地下降。原因只有一个训练数据的成像分布和实际产线不一致模型把“光怎么打”也当成了一种特征。解决方式从数据侧和算法侧同时做。数据侧在采集阶段刻意覆盖多个光源角度、多个亮度等级把光照变化当成训练集的一部分。算法侧训练时把 HSV 增强的强度开大一些尤其对色相和饱和度做扰动降低模型对颜色绝对值的依赖。我现在的习惯是每次产线换光源或换班次后先拿 100 张实拍图跑一遍离线预测把置信度分布和之前的一个月做对比漂移立刻就能看出来不用等质检员来投诉。6. 每次推理都保存结果缺陷可视化复查与阈值校准的一个实用技巧模型部署之后最容易被忽视的就是推理结果的保存习惯。很多团队只保留了“合格/不合格”的判定结果缺陷框、置信度、原图一概不存等质检员反馈误报多了想复盘手里什么都没有。我现在的做法是每次推理都把文本结果单独落盘一图一 txt后续复查和阈值校准全靠这批文件。from ultralytics import YOLO import cv2 import os model YOLO(best.engine) out_dir inspection_log os.makedirs(out_dir, exist_okTrue) for img_path in img_list: img cv2.imread(img_path) results model.predict(img, imgsz640, conf0.3) lines [] for box in results[0].boxes: x1, y1, x2, y2 box.xyxy[0].tolist() cls int(box.cls[0]) conf float(box.conf[0]) lines.append(f{cls} {x1:.1f} {y1:.1f} {x2:.1f} {y2:.1f} {conf:.4f}) txt_path os.path.join(out_dir, os.path.basename(img_path)[:-4] .txt) with open(txt_path, w) as f: f.write(\n.join(lines))这段代码把每张图的检测结果保存成文本每一行对应一个缺陷框。保存格式里最关键的是置信度不要只存坐标和类别。积累一周的推理结果后把所有缺陷的置信度拉成直方图再结合质检员的复判记录就能算出每个置信度阈值对应的过杀、漏杀代价。阈值校准的活干过几次之后会发现很多所谓的“模型不稳定”其实是产线本身的光照和产品状态在漂移定期用保存下来的数据做阈值复审比反复重训模型更划算。另一个高阶用法是连续帧验证对同一产品拍多帧只在连续 N 帧都检出同一位置缺陷时才判为不合格能显著压掉瞬时噪声和光源闪烁造成的误报。这需要把一个产品关联到的全部 txt 文件按时间顺序对齐分析也是保存了结果才能做的事。我现在的习惯是上线第一天就把推理结果保存脚本挂上和产线数据同步积累。一个月后不管是做阈值调整还是模型更新手里都有一批真实分布的历史数据而不是靠记忆和感觉。这个习惯帮我挡掉过很多次“返工式调参”也希望帮你在自己的质检项目里少踩几个同样的坑。本文还有配套的精品资源点击获取
返回列表