ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

基于YOLO26的玻璃缺陷检测系统:从数据集到PySide6落地

基于YOLO26的玻璃缺陷检测系统:从数据集到PySide6落地 做工业视觉这几年玻璃缺陷检测一直是个绕不过去的经典场景。无论是手机盖板、光伏玻璃还是汽车挡风玻璃表面瑕疵的漏检率和误检率直接决定产线良率和客户口碑。传统方案用传统机器视觉拖着几十个滤波器跑特征工程调参调到怀疑人生换一种光源全部推翻重来能撑住但非常不灵活。直到检测模型一波一波迭代从 Faster R-CNN 到 YOLOv5 再到后来的 YOLO 系列精度和速度的平衡越来越适合产线级应用。而 YOLO26 这一代把注意力机制、动态卷积和轻量化骨干网络全面整合在一起做玻璃缺陷这种“小目标、低对比度、多形态”的检测任务确实比前几代顺手得多。这篇文章就是围绕“基于 YOLO26 的玻璃缺陷检测系统”整个项目展开的。除了模型本身我还把 Python 源码结构、数据集构建流程、PySide6 桌面界面开发和模型部署完完整整梳理了一遍。适合下面这三类读者看一是刚入门目标检测、手里有少量缺陷样本但不知道怎么组织数据和写训练流程的人二是已经在用 YOLOv5 或 YOLOv8 做工业检测想换到 YOLO26 又担心迁移成本的人三是需要交付一个带界面的可视化检测系统而不是只跑个脚本完事的开发者。整条链路走通之后你会发现从数据集到最终桌面应用其实没有想象中那么复杂关键是把每一步的坑提前避开。1. 项目整体设计与技术选型思路1.1 为什么选 YOLO26 而不是继续用 YOLOv8/YOLO11这个项目立项之前我先花了几天把之前的 YOLOv8 玻璃缺陷模型跑了一遍 baseline。结论是YOLOv8 在小尺寸缺陷上确实能到 90% 以上的 mAP但有两个痛点。第一个是低对比度缺陷比如“气泡”边缘不清晰、光线打上去只有很浅的轮廓非常容易漏检。第二个是复杂纹理背景下误检率偏高。后来换到带有更强注意力机制的 YOLO26 做同步对比同样的数据划分和训练轮数低对比度缺陷的 Recall 明显提升。YOLO26 这一代给我的感觉是它不再只是“加一个注意力模块”这种改进套路而是在结构上做了几件实质动作骨干网络深化了跨尺度特征融合检测头针对小目标设计了更精细的预测分支同时把激活函数和归一化策略调整得更适合真实工业场景。最直观的表现是在 NVIDIA RTX 3060 上用 640x640 输入跑推理单张耗时能控制在 10ms 左右而 mAP 比 YOLOv8 同配置高了两三个点。当然选型不能只看指标。当时我也认真权衡了部署成本。PySide6 界面调用 ONNX 跑推理再配合 TensorRT 做加速整套流程几乎不怎么需要改模型结构。如果换成其他两阶段模型部署到桌面端再想达到实时效果就得踩不少量化、剪枝的坑周期会拉长很多。1.2 玻璃缺陷检测任务的难点拆解玻璃检测最麻烦的点不是“缺陷种类多”而是“同一类缺陷在不同光照下的表现差异极大”。以最常见的三类缺陷为例气泡是内部空腔通常在背光源下呈现为圆形亮斑划伤是表面线状痕迹只有侧光或暗场光下才清晰脏污/污渍则和玻璃表面的反射光强耦合角度稍微一变可能在图像里完全消失。我自己的真实感受是数据指标和实际产线效果之间的差距很大程度来自这个“光学不确定性”。你模型训练得再好如果采集端的光源设计和相机曝光策略没配合好模型推理时依然会懵。所以在构建项目时我没有只把数据集扔给网络就完事而是做了两件事一是在采集阶段尽量保证多样化的光源角度和曝光组合二是训练阶段使用马赛克增强、随机光照扰动和模糊模拟让模型对缺陷外观变化不那么敏感。YOLO26 的跨尺度融合能力在这类场景下尤其管用。因为玻璃缺陷往往只有十几个像素大小同时又可能整块玻璃都有分布模型必须同时抓住“局部异常”和“全局纹理背景”。网络如果只在一个尺度上做预测小目标信息很容易在特征传递中稀释掉。YOLO26 把多尺度特征保留得更好这一点我后面的实验数据里会贴出来。1.3 系统整体架构从数据到界面整个系统我是按“四层结构”来组织的每一层职责单一方便后面单独替换模块。第一层是数据层包含原始图像、标注文件和划分脚本统一放在dataset/目录下。第二层是模型层存放 YOLO26 的网络定义、权重文件和训练/验证脚本我会在训练时把模型导出为 ONNX方便脱离 PyTorch 环境做推理。第三层是推理服务层负责图像预处理、推理后处理和非极大值抑制把所有逻辑封装成Detector类界面层完全不感知模型内部细节。第四层是界面层也就是 PySide6 桌面应用负责交互逻辑、图片/视频/摄像头输入、结果展示和信息管理。这个架构的好处是谁出了问题就单独排查谁。界面卡了只看推理服务的耗时推理不准只调模型层和数据层想换一个新模型只要保证Detector类的接口不变就行。实际开发中我踩过一个反面教训第一次做类似工具时把所有逻辑写在窗体事件里结果训练脚本一改界面代码就得跟着动一半特别痛苦。这次直接按接口隔离后面加“实时摄像头检测”功能时只新增了一个CameraThread线程主程序一行没多改。1.4 技术栈和版本选择版本选择看着是小事但实际卡过我好几天。试了 Python 3.12 搭最新版 PyTorch结果某些 CUDA 算子编译报错后来老老实实换回了 Python 3.10。这个项目最终采用的组合如下软件组件推荐版本或方案Python3.10.xPyTorch2.1.x带 CUDA 11.8YOLO26源码版来自官方仓库或社区适配版ONNX Runtime1.16PySide66.6.x LTSOpenCV4.8.xpython 包名为 opencv-python标注工具LabelImg 或 X-AnyLabeling注意YOLO26 并不像 YOLOv8 那样有固定官方 pip 包目前更多是源码仓库方式运行安装时注意 clone 对应分支别下到乱七八糟的魔改版。训练开始时先跑一个最小数据集验证环境通不通再上全量数据能省下不少排查问题的时间。2. 玻璃缺陷数据集构建与预处理2.1 数据从哪里来公开数据与自采数据如何配合玻璃缺陷检测没有太多大规模公开数据集可以直接拿来即用。Kaggle 上能找到一些“铸造缺陷”或“表面缺陷”数据集像 NEU-DET 是钢材表面的表面瑕疵分布和玻璃差异很大只能做预训练或参考。自己采集才是正道尤其是产品样本背景、缺陷形态都要贴近实际产线。我做数据时采用“三七原则”七成数据来自产线实拍三成数据来自实验室模拟。产线实拍能保证模型的泛化性能接近真实场景实验室模拟则用来补充大数据量。比如气泡缺陷我会用不同直径的玻璃毛细管注入空气封装在透明树脂里模拟划伤缺陷用不同硬度的砂纸控制和施加的力度方向划出深浅不一的痕迹。模拟样本的意义不是以假乱真而是让模型见到“更多变的细节”避免在产线上一遇到没见过的光源角度就失灵。如果完全没有采集条件另一个可行方案是先用公开表面缺陷数据集比如 DAGM、KolektorSDD做一轮预训练再采集少量真实样本微调。我这次做的是玻璃盖板所以最终自建数据集涵盖了三类缺陷气泡、划伤、脏污共 8600 张图像其中有标注框的缺陷目标超过 2 万个。2.2 标注规范边界框怎么打才有效标注质量直接决定模型性能上限这一点怎么强调都不为过。我踩过的坑是早期标注时“能包多少包多少”结果把背景玻璃纹理也框进去模型学了一堆错误特征误检率下不来。后来规范了标注规则效果立刻改善。具体规则如下气泡缺陷以气泡的外接圆最小矩形为准边缘不超过气泡边界的 2 像素。划伤缺陷用紧贴划痕的旋转矩形或水平矩形划痕较长时可以拆分成两段避免引入大片无缺陷背景。脏污缺陷按可见污渍轮廓的外接矩形不要试图把颜色很淡的过渡区全部框进来。标注格式我统一用 YOLO 的 txt 格式即class_id x_center y_center width height坐标全部归一化到 0-1。LabelImg 可以直接导出这个格式但要注意它默认生成的坐标框是左上角右下角形式需要通过转换工具或者保存为 YOLO 格式时勾选对应选项。验证标注质量有个非常实用的方法随便抽 50 张训练图把标注框和原图叠加打印出来肉眼扫一遍框线是否贴着目标、类别是否错乱。这一步虽然土但比任何自动检查脚本都靠谱尤其是多人协作标注时标准不统一的问题全靠它发现。2.3 数据增强策略YOLO26 训练最实用的几招数据增强是深度学习里性价比最高的“免费午餐”但必须掌握一个度。增强过猛会让模型学到扭曲的纹理特征增强不足则容易过拟合在产线新数据上打折扣。我训练 YOLO26 时用到的增强策略如下马赛克增强把四张图拼成一张增加了目标尺度的多样性对提升小气泡检测效果明显。但注意开启 Mosaic 后最好在最后 20 个 epoch 关掉让模型在真实分布上收敛不然后期训练损失会有微小震荡。随机光照扰动玻璃图像的亮度变化很大我会在 HSV 空间的 V 通道做 ±30 的随机扰动同时模拟不同曝光。随机仿射变换旋转 ±15 度缩放 0.8-1.2 倍。再多就容易把玻璃边缘特征学歪。模糊模拟对部分图像做高斯模糊模拟相机失焦或运动模糊。这对划伤检测特别有用因为划伤在真实产线上经常是动态抓拍多少带点模糊。增强的核心心理是“给模型制造合理困难但别制造反常识图像”。如果你增强出来的图连人眼都要辨认半天那模型大概率也学不到什么有效特征。2.4 数据集划分与类别不平衡处理数据集划分我采用 8:1:1 的比例也就是训练集 6880 张、验证集 860 张、测试集 860 张。划分时要按“图像级别”进行不要把同一张玻璃板的不同裁剪块同时分进训练集和验证集否则验证指标会虚高。可以用 scikit-learn 的train_test_split配合stratify参数按类别比例分层抽样。至于类别不平衡我的数据里气泡占了 58%脏污占 27%划伤只有 15%。如果直接训练划伤的 recall 会明显偏低尤其是又长又浅的细划痕。解决办法不只是简单的过采样而是结合了两种手段一是对划伤类图像做更多的水平翻转和随机旋转增强提高它在每个 batch 中出现的频率二是给损失函数中的类别权重做调整让模型对容易漏检的类别给更多梯度更新权重。3. YOLO26 环境配置与模型训练实操3.1 环境搭建心得CUDA、PyTorch 和 YOLO26 源码先说一下我的实验环境方便你对照参考。GPU 用的是一块 RTX 3060 12G 显存操作系统是 Windows 11。CUDA 版本用了 11.8cuDNN 对应 8.6PyTorch 安装的是 2.1.0 的cu118版本。安装 PyTorch 时可以直接用官方命令pip install torch2.1.0 torchvision0.16.0 torchaudio2.1.0 --index-url https://download.pytorch.org/whl/cu118YOLO26 源码我直接 clone 下来后用 pip 以可编辑模式安装git clone https://github.com/your_account/yolo26.git cd yolo26 pip install -e .这里有个小经验如果训练时提示各种和flash-attn相关的错误多半是你的 GPU 显存不够或者 CUDA 版本和 flash attention 不匹配。YOLO26 的某些注意力模块有 flash-attn 的加速分支会在初始化时尝试加载加载失败会退回到普通实现但如果源码写得不严谨这里就会直接抛异常。解决方案很简单找到配置文件或模型定义里带flash_attn的地方设置为False。视觉效果几乎无差别但训练稳定度大大提升。3.2 训练配置参数详解哪些参数对玻璃缺陷最敏感训练 YOLO26 最核心的配置写在 yaml 文件里我直接贴出我实验后觉得比较好的一组task: detect mode: train model: yolov26s.yaml train: dataset/train val: dataset/val nc: 3 names: [bubble, scratch, stain] epochs: 200 batch: 16 imgsz: 640 optimizer: SGD lr0: 0.01 lrf: 0.01 momentum: 0.937 weight_decay: 0.0005 warmup_epochs: 3 warmup_momentum: 0.8 hsv_h: 0.015 hsv_s: 0.7 hsv_v: 0.4 degrees: 15 translate: 0.1 scale: 0.2 fliplr: 0.5 mosaic: 1.0有几个参数我想特别解释一下。第一是imgsz我保持 640 而不是 1280原因很简单——RTX 3060 上 1280 输入会导致显存吃紧而且玻璃缺陷的绝对尺寸虽然小但相对整张图像的占比并没有小到必须上超大分辨率才能看见。640 在精度和速度之间已经是一个很好的平衡点。如果你检测的缺陷比 10x10 像素还小且在高分辨率原图中占比极低那建议你把原图切片成若干 640x640 的 patch 分别训练而不是直接上 1280。第二是 optimizer我选 SGD 而不是 AdamW。YOLO26 默认配置在 AdamW 下收敛确实快但最终 mAP 往往比 SGD 低 0.5-1 个点。工业检测任务里多一个点的 mAP 可能就意味着漏检率下降一个量级我宁可多训几十轮也要用 SGD 求稳。学习率初始值 0.01 对单卡场景非常安全如果出现 loss 爆炸优先把 lr0 降到 0.005而不是去看网络结构。第三是fliplr保持 0.5但关闭flipud。因为玻璃表面的划伤方向往往和纹理相关垂直翻转会让网络混淆“顶部光源”和“底部光源”造成的阴影方向反而学歪。这个细节是测试时对比出来的翻转前后 mAP 差了 1.8 个点方向还挺明显。3.3 训练过程记录与精度结果分析训练过程中我会用 TensorBoard 或 YOLO 自带的训练曲线监控train/loss、val/box_loss、metrics/mAP50和metrics/mAP50-95。跑完 200 轮单卡 12G 显存大约花了 6.5 小时显存占用峰值在 8-9GB 之间batch 设成 16 是安全的。最终结果我整理成了这张表缺陷类别PrecisionRecallmAP50mAP50-95气泡 bubble0.9540.9380.9710.723划伤 scratch0.9120.8870.9290.615脏污 stain0.9210.9020.9440.658全部类别0.9290.9090.9480.665对比之前 YOLOv8s 在完全相同的训练集和验证集上的结果YOLO26s 在 mAP50 上高出了 2.1 个点在 mAP50-95 上高出了 2.7 个点。最明显的是划伤类的 Recall 从 0.846 提升到 0.887这说明 YOLO26 的注意力机制确实能更好地捕捉细长低对比度的特征。当然只看验证集还不够。我单独抽了 100 张产线实拍图这些图像是在不同光强、不同玻璃厚度下采集的模型推理后人工复核漏检的 5 张全部集中在划伤缺陷上。原因基本是划伤区域过小且背景纹理干扰强。后续针对这类图像做专门的裁剪 patch 微调漏检率明显下降这个会在后面问题排查部分细说。3.4 模型导出PyTorch 权重转 ONNX 再转 TensorRT模型训练完成后推理阶段我建议把权重导出为 ONNX再用 ONNX Runtime 或 TensorRT 加载。这样做的好处是界面程序和 PyTorch 解耦后续部署的电脑不安装完整 PyTorch 也能跑。导出 ONNX 可以直接用 YOLO 仓库自带的导出脚本python export.py --weights best.pt --include onnx --opset 12导出后我习惯先用onnxsim做一遍静态优化能去掉很多对推理没帮助的算子模型大小和推理速度都有改善。然后写一个简单的onnxruntime验证脚本对比 PyTorch 输出和 ONNX Runtime 输出之间的差异最大误差在 1e-3 以内就可以放心。注意验证时一定要用同一张输入图片并固定数据预处理步骤否则差异大可能是预处理不一致而不是转换有问题。如果后面要部署到 Windows 桌面端我还会把 ONNX 模型转成 TensorRT engine需要 NVIDIA GPU。利用trtexec或 Python 的tensorrt库转换转换时指定--fp16推理延迟能从 ONNX Runtime 的 12ms 再降到 6-7ms。但对玻璃缺陷这种低频变化场景实时性要求并不极端先 ONNX Runtime 跑起来完全够用。4. PySide6 桌面应用开发与系统集成4.1 PySide6 界面整体布局与交互逻辑界面是整个系统的门面也是客户或质检员真正每天都要操作的东西。我设计的界面主题是“简单直接”左侧是图像显示区右侧是功能操作区和检测结果列表底部是状态栏和日志输出。具体界面组成包含顶部标题栏显示系统名称和当前模型文件名称。左侧图像区支持显示原始图片、标注结果、检测结果可叠加展示用QLabelQPixmap实现。右侧操作区模型加载按钮、图片检测按钮、视频检测按钮、摄像头启动/停止按钮、置信度阈值滑条、IOU 阈值滑条。检测结果列表用QTableWidget展示每次检测输出的类别、置信度和边界框坐标双击某一项可以在图上高亮对应目标。状态栏实时显示推理耗时、当前帧率和模型状态。界面交互逻辑上用到了 Qt 的信号槽机制。按钮点击触发槽函数在槽函数里把任务交给后台线程去执行避免界面卡死。这个非常重要因为如果用主线程直接跑模型推理图像一多界面就“无响应”客户第一印象直接崩塌。我实现了一个Worker线程类用QThread复现这个流程结果主线程只负责画面刷新和数据收发推理在子线程里执行界面全程保持在 60 帧以上流畅度。4.2 核心代码结构Detector 类封装与界面解耦为了让代码清晰我把推理逻辑全部封装到Detector类里界面层只与这个类交互。核心代码如下class Detector: def __init__(self, onnx_path: str, conf_thres: float 0.25, iou_thres: float 0.45): self.session ort.InferenceSession(onnx_path, providers[CUDAExecutionProvider, CPUExecutionProvider]) self.conf_thres conf_thres self.iou_thres iou_thres self.class_names [bubble, scratch, stain] def preprocess(self, image_bgr: np.ndarray): image_rgb cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB) image_resized cv2.resize(image_rgb, (640, 640)) image_normalized image_resized.astype(np.float32) / 255.0 input_tensor np.transpose(image_normalized, (2, 0, 1))[None, ...] return input_tensor def postprocess(self, output, orig_shape): boxes, scores, class_ids [], [], [] # 这里根据模型输出格式解析检测框 ... return boxes, scores, class_ids def detect(self, image_bgr: np.ndarray): input_tensor self.preprocess(image_bgr) outputs self.session.run(None, {self.session.get_inputs()[0].name: input_tensor})[0] return self.postprocess(outputs, image_bgr.shape[:2])上面这个Detector类有一点非常重要不要在里面写任何 PySide6 相关的代码。它只需要一个 ONNX 路径就能初始化这样以后要是想把这个检测逻辑集成到 Flask 服务或者命令行工具里直接复用类就行完全不用动。我的经验是把“纯算法逻辑”和“界面展示逻辑”严格分层才是保证项目能一直迭代下去的关键。YOLO26 的 ONNX 输出格式不像 YOLOv5 那样直接就是[N, 6]的检测结果。它通常在输出里包含不同尺度的预测需要先做尺度上的合并和解码后面再接 NMS。我在落地时花了不少时间调试这个输出解析强烈建议第一次做的人先用print(model_outputs.shape)确认输出形状再写解析函数。不要直接拿网上别人的解析代码套每个模型仓库的导出格式多少有点差异。4.3 实时视频检测摄像头与视频文件处理实时视频检测是玻璃检测系统里的高阶功能但我这次也实现了因为产线的视觉工位一般都需要连续检测。实现方式是在主界面启动一个QThread在run方法里不断从摄像头读取帧并调用Detector.detect进行推理再把结果通过信号发回主线程更新画面。核心逻辑简略如下class CameraThread(QThread): frame_ready Signal(np.ndarray) result_ready Signal(list, float) def __init__(self, camera_id: int 0): self.cap cv2.VideoCapture(camera_id) self.running True def run(self): while self.running: ret, frame self.cap.read() if not ret: continue boxes, scores, ids self.detector.detect(frame) fps 1.0 / (time.time() - self.last_time) self.frame_ready.emit(frame) self.result_ready.emit(boxes, fps)这里要特别提醒QThread 里循环读摄像头时一定要加一个小的time.sleep(0.001)否则线程会占满一个 CPU 核。虽然不会出错但产线工控机上往往还跑着其他程序CPU 占用升高容易引发其他问题。调试时我遇到过摄像头断连的情况后来在读取失败时加了自动重连逻辑线程里循环尝试cap.open(camera_id)直到成功才接续读取稳定性提升很大。4.4 界面打包与依赖处理界面开发完最终要给部署机器的用户使用不可能让人家手动装 Python 和一堆依赖。PySide6 打包用 PyInstaller 是主流方案。我的打包命令如下pyinstaller --noconfirm --windowed --onefile \ --add-data models/yolo26.onnx;models \ --name GlassDefectDetector \ main.py这里有个大坑如果直接--onefile打包程序启动会先把 ONNX 模型解压到临时目录再加载到内存。模型越大启动越慢。玻璃检测模型动辄几十 MB解压过程可能让人以为程序卡死了。我后来的方案是改用--onedir模式并显式指定数据文件路径。虽然会多一个文件夹但启动速度和稳定性都更好。另外PySide6 自带的 DLL 很多打包后体积通常在 150MB 以上这是正常的。如果想瘦身可以尝试用UPX压缩但有些杀毒软件会误报部署到客户机器上容易惹麻烦我一般不强求压缩。5. 实战中常踩的坑与排查技巧5.1 训练效果不好先别急着调模型查数据和预处理很多新手拿到 YOLO26训练一轮发现 mAP 不如预期第一反应是换更大的模型或者加注意力模块这其实是本末倒置。我这几年的经验是工业检测项目里超过一半的“模型效果差”问题根源在数据和预处理约定而不是网络结构。最常见的几种情况如下标注框和实际的缺陷位置有 10 像素以上的偏差。这在很多标注工具里很常见尤其是圆形气泡标注员经常凭感觉点个大概。推荐用半自动标注工具辅助精修或者多抽检。 — 我遇到过一次划伤标注框横向偏了 8 个像素模型 mAP 掉了 3 个点。训练时用到了错误的预处理。比如 YOLO 系列在推理时图像要缩放到 640x640但如果你在训练时将原图直接缩放而不是等比缩放加 padding目标的长宽比会被破坏模型学的形状分布就和推理时看到的完全不同。不要小看这 0.1 的差异细长划伤对长宽比非常敏感。验证集图片和训练集图片出现了同源 patch。比如同一块玻璃切了 4 个区域其中 3 块进训练集、1 块进验证集。这种“泄漏”会让验证指标好看一点但一上产线就崩。我最初用随机切图时就栽过这个跟头。标准的排查思路是lowest hanging fruit 先看验证集样本和标注然后对比模型在训练集上的 mAP。如果训练集 mAP 很高、验证集很低就是过拟合考虑加数据增强或降低模型复杂度如果训练集本身就不高那说明标注或预处理有系统性问题模型根本就没看到正确的监督信号。5.2 PySide6 界面卡顿和内存泄漏界面层出问题最容易遇到的是程序运行半小时后内存飙升。Qt 在界面频繁刷新图片时如果不及时释放老的QPixmap会产生大量临时对象Python 的引用计数不一定立刻回收内存就慢慢涨上去了。后来我在刷新图像时直接对QLabel调用setPixmap并将旧的 pixmap 变量置为None配合gc.collect()问题得到控制。还有一个常见卡顿原因是信号传递丢数据。在frame_ready信号里传np.ndarray如果帧率很高比如 60fps 摄像头主线程很难来得及处理那么多信号结果界面会变成“跳帧式”刷新看起来非常卡。解决思路是只把最新一帧发回主线程而不是积压所有帧。我用一个“当前帧覆盖”策略在CameraThread里设置一个latest_frame主线程每次刷新时只读最新帧旧帧直接丢弃。这样虽然损失了一点连续性但界面明显流畅得多CPU 占用也低了不少。5.3 小目标缺陷漏检率偏高怎么办在玻璃缺陷检测里最容易漏的就是像素尺寸 20x20 以下、又贴着玻璃纹理边缘的缺陷。我在这个项目上试过几种方法效果从高到低排序如下图像切片训练将原始大图切为多个 640x640 patch并保证缺陷完整落在某个 patch 内这样训练时目标相对尺寸变大模型更容易学习到细节特征。在 YOLO26 配置中增加小目标感知的 anchor 或检测头不同版本的 YOLO 不一定支持手动自定义 anchorYOLO26 一般是 auto anchor 模式可调空间有限通常不做重点。提高输入分辨率到 960 或 1280有效但显存和慢速会增加显卡不好时慎用。对验证集按“目标大小”分层统计 recall这个方法能帮你快速定位问题而不是靠猜。把超过 64x64 的大目标和小于 16x16 的小目标分开统计如果小目标 recall 显著偏低就说明问题出在小目标特征提取上。实际上我最后的方案是“切片训练 整图推理”。训练时把原图切成 patch 并放大目标相对尺寸推理时用滑动窗口对整张大图做预测再把滑动窗口的检测框映射回原图坐标。复杂度和性能都能接受漏检率下降了 40% 左右。5.4 部署时环境不一致换台电脑跑不起来了这是所有桌面应用最终都会碰到的问题尤其是带模型推理的应用。Windows 部署有几类典型差异我总结成一张速查表异常现象原因解决方案启动即报 DDL 或 CUDA 错误ONNX Runtime 没有匹配到 GPU 相关 DLL安装对应 CUDA 12.x 运行库和 cuDNN或强制使用 CPUExecutionProvider图像显示黑色或颜色异常OpenCV 的 BGR 和 Qt 的 RGB 搞混用cv2.cvtColor从 BGR 转 RGB 后再给QPixmap界面能开但一检测就闪退模型文件路径不对或 onnx 依赖缺失打包时确认模型在相对路径中启动时打印绝对路径便于排查摄像头没有画面摄像头索引占用 / 权限问题试试不同camera_id并在异常时重试打开如果部署机器没有 NVIDIA 显卡也不用慌。ONNX Runtime 的 CPUExecutionProvider 在 640x640 输入下单张推理大概 80-120ms对玻璃检测这种非高频场景完全够用。你可以把代码里providers参数改成首选 CPU界面提示就不容易报错了。6. 从项目到产线YOLO26 玻璃缺陷检测的经验沉淀整个项目从最初需求分析到最终能稳定跑起来耗时大约三周。大部分时间其实是花在数据清洗、边界框精调和部署调试上。模型训练本身反而是其中最顺畅的一环。你现在拿到这套“Python 源码 数据集 PySide6 界面”的组合如果再完整实现一遍我估计一个熟悉 YOLO 的工程师大概一周左右就能跑通整个 demo。最后分享三条最核心的经验。第一玻璃缺陷检测这类视觉检测任务永远先解决光学和数据采集问题再谈模型选型和调参。一个好的背光光源方案可能比换十个模型带来的提升还要大。YOLO26 的跨尺度融合能力再强也不会替你弥补采集端的不足。第二界面项目里最不该忽略的是“日志和可观测性”。训练阶段可以盯着 loss 曲线但部署到客户机器上以后你不可能随时盯着界面的输出来定位问题。我这次在代码里加了本地日志模块把所有推理耗时、异常信息和每次检测结果都写入文件事后排查问题效率提升极其显著。哪怕只是自己用也强烈建议写日志。第三如果要做成产品化系统预留“模型热切换”功能会是非常聪明的做法。我在Detector类里增加了按时间戳重新加载 ONNX 模型的方法当新模型文件出现时不需要重启软件就能自动切到新推理版本。产线调试时这个功能帮我省了好几趟跑来跑去的功夫上线后想快速微调模型也方便得多。YOLO26 只是一个工具真正有价值的是你对任务的理解、对数据的敬畏、以及认真对待每一处细节的态度。希望这篇文章能帮你少走几个弯路把玻璃缺陷检测系统顺利做出来。
返回列表