写在前面在实验室里跑COCO数据集mAP刷到80%很容易但把模型搬到工厂产线上你会发现精度可能直接腰斩。工业视觉和通用检测完全是两个世界光源会衰减、工件会反光、零件会重叠、缺陷只有几个像素大。过去两年我先后参与了3C组装件外观检、新能源电池极片检测、汽车零部件分拣三个项目的YOLO落地。这篇文章不讲论文里的SOTA只聊我们在产线上真金白银砸出来的工程解法。每一个方案背后都是几十次误报停线和被客户追着骂的教训。一、 光照问题不是“调亮”那么简单1.1 工业现场的光照到底有多野很多人以为工业检测都有标准光源箱实际情况是金属件镜面反射同一个工件正面看是亮的侧面5°就变成纯白过曝区缺陷直接被高光吞掉环境光干扰车间顶灯老化、窗户透光、隔壁工位焊接弧光都会导致画面亮度在一天内波动±40%光源衰减LED环形灯用了半年中心亮度下降15%边缘下降30%模型训练时的数据分布已经漂移了。1.2 我们试过的方案与效果方案实施成本效果适用场景备注全局CLAHE低⭐⭐均匀暗场对局部过曝无效反而增强噪声Retinex增强中⭐⭐⭐阴影/不均匀照明计算量大Orin上增加8ms延迟多曝光融合高⭐⭐⭐⭐高动态范围金属件需相机支持触发频闪帧率减半域自适应预处理中⭐⭐⭐⭐⭐通用最终采用方案硬件偏振滤光高⭐⭐⭐⭐⭐镜面反射治本但需重新设计光路1.3 最终落地轻量级自适应预处理管线我们没有用重型图像增强算法而是设计了一个“感知-决策-处理”三段式管线核心思想是不盲目增强只在必要时对必要区域做最小干预。正常整体偏暗整体过曝局部高光亮度不均原始图像光照状态评估直通Gamma校正 γ0.6Gamma校正 γ1.8高光区域Mask 局部色调映射分块CLAHE tile16x16输出关键实现细节classAdaptivePreprocessor:def__init__(self,highlight_thresh240,dark_thresh40):self.highlight_threshhighlight_thresh self.dark_threshdark_threshdefevaluate(self,img_gray):快速评估光照状态耗时0.1msmean_valnp.mean(img_gray)highlight_rationp.sum(img_grayself.highlight_thresh)/img_gray.size dark_rationp.sum(img_grayself.dark_thresh)/img_gray.sizeifhighlight_ratio0.05:returnlocal_highlightelifmean_val200:returnglobal_overexposedelifmean_val60:returnglobal_darkelifdark_ratio0.1andhighlight_ratio0.02:returnunevenelse:returnnormaldefprocess_local_highlight(self,img):只对高光区域做色调映射保留其他区域原始信息hsvcv2.cvtColor(img,cv2.COLOR_BGR2HSV).astype(np.float32)maskhsv[:,:,2]self.highlight_thresh# 仅对V通道高光区域做压缩hsv[mask,2]self.highlight_thresh-(hsv[mask,2]-self.highlight_thresh)*0.3hsvnp.clip(hsv,0,255).astype(np.uint8)returncv2.cvtColor(hsv,cv2.COLOR_HSV2BGR)为什么不用端到端的光照鲁棒性训练试过。在训练数据中加入各种光照增强后模型在正常光照下的精度反而下降了2-3个点。数据增强不是万能的它会让模型学到“忽略光照特征”这个捷径而不是真正理解缺陷本身。预处理归预处理检测归检测职责分离才是正道。二、 遮挡问题从“看见全貌”到“看见就够了”2.1 工业遮挡的三种典型形态自遮挡异形工件自身结构导致的视角盲区如L型支架的内角互遮挡料框中零件堆叠、传送带上工件间距过小设备遮挡夹具、吸盘、传感器支架固定遮挡部分视野。这三种遮挡的应对策略完全不同混为一谈是新手最常犯的错。2.2 分层应对策略针对自遮挡多视角融合 单模型硬扛一个工件如果有3个面需要检测不要试图用一个相机一个模型搞定。我们的做法是相机A顶视 → 模型A → 结果A ─┐ 相机B侧视45°→ 模型B → 结果B ─┼→ NMS融合 → 最终结果 相机C底视 → 模型C → 结果C ─┘每个模型只负责自己视角下无遮挡的面单模型精度从72%提升到94%。融合时用3D标定将不同视角的检测结果投影到统一坐标系再做3D-NMS去重。针对互遮挡修改标注策略 损失函数调整料框抓取场景中零件堆叠是常态。传统做法是只标注可见部分但这会导致模型学到“残缺形状目标”的错误关联。我们的标注规范改动被遮挡50%的目标不标注bbox但标注为ignore区域训练时不参与正负样本匹配但也不作为背景惩罚被遮挡50%的目标标注完整bbox脑补被遮挡部分同时打上occludedTrue标签损失函数中对occludedTrue的样本box loss权重降为0.5cls loss权重保持1.0——允许定位有一定误差但分类必须准确。# train.yaml 遮挡相关配置ignore_overlap_thr:0.5# ignore区域与anchor的IoU阈值occluded_box_loss_weight:0.5use_complete_bbox_for_occluded:True# 标注完整框而非可见框实测效果在堆叠密度30%的测试集上召回率从68%提升到85%且误检率没有上升。针对设备遮挡ROI掩码 负样本注入夹具遮挡是固定的最简单有效的方案是在推理时加ROI掩码屏蔽遮挡区域。但仅这样做不够——训练时模型从未见过遮挡边界附近的特征上线后容易在掩码边缘产生误检。正确做法训练时随机生成与真实夹具形状相似的黑色遮罩以20%的概率叠加到训练图像上。让模型学会“看到遮罩边缘就知道这不是目标”。2.3 一个反直觉的经验不要追求“所有遮挡都能检出来”。在电池极片检测项目中我们曾花了两周优化严重遮挡下的检出率从75%提到82%。但客户反馈“那些被挡住一半的极片本来就是废品你检出来也没用反而增加了分拣机构的无效动作。”后来我们把遮挡40%的目标直接标记为“不可判定”交由下游复检工位处理。整体OEE设备综合效率反而提升了3%。工业AI的目标不是mAP最大化而是产线效率最大化。三、 小目标检测像素不够信息来凑3.1 工业小目标有多小PCB焊点缺陷在4K图像中占8×8像素手机屏幕划痕宽度仅2-3像素长度可达200像素极端长宽比轴承表面麻点直径5像素且与背景纹理高度相似。YOLO默认的下采样策略stride32对这些目标几乎是毁灭性的——经过5次下采样后8px的目标在特征图上只剩0.25个像素信息完全丢失。3.2 我们验证过的方案对比方案mAP提升推理开销增加工程复杂度推荐度增大输入分辨率(640→1280)8~12%4倍低⭐⭐⭐添加P2检测头(stride4)10~15%2.5倍中⭐⭐⭐⭐SAHI切片推理12~18%4~9倍低⭐⭐⭐⭐切图训练推理对齐15~22%2倍中⭐⭐⭐⭐⭐Transformer辅助头5~8%3倍高⭐⭐超分预处理3~6%5倍高⭐3.3 最终方案切图训练 推理对齐详解SAHI是好工具但它只是推理时的trick。如果训练时模型没见过切图后的数据分布推理时切图的效果会大打折扣。我们的核心改进是训练和推理使用完全一致的切图策略。推理阶段训练阶段导出模型原始4K图像滑动窗口切图 800×800 overlap200切图标注转换YOLOv8训练原始4K图像相同参数滑动窗口切图逐片推理预测框坐标还原加权NMS融合切图参数选择经验# 切图参数不是拍脑袋定的需要根据目标尺寸分布计算defcompute_slice_params(target_size_stats,image_size): target_size_stats: 训练集中目标尺寸的统计信息 原则切片边长 ≥ 目标最大尺寸的4倍确保上下文充足 max_targettarget_size_stats[p95]# 用95分位而非最大值slice_sizemax(640,int(max_target*4))# overlap至少为目标最大尺寸的1.5倍避免目标被切断overlapmax(100,int(max_target*1.5))# 对齐到32的倍数YOLO stride要求slice_size(slice_size//32)*32overlap(overlap//32)*32returnslice_size,overlap加权NMS融合的关键普通NMS在切片重叠区会把同一个目标的多次检测当作冗余删掉但实际上边缘切片的检测置信度通常低于中心切片。我们用距离加权替代固定阈值defweighted_nms(predictions,slice_centers,sigma100): 对同一目标的多次检测按距切片中心的距离加权融合置信度 靠近切片中心的检测结果权重更高 forpredinpredictions:distnp.linalg.norm(pred.center-slice_centers[pred.slice_id])pred.weightnp.exp(-(dist**2)/(2*sigma**2))# 融合后再做标准NMSmergedmerge_weighted_predictions(predictions)returnstandard_nms(merged,iou_thr0.45)这套方案在PCB焊点检测项目上8×8像素目标的召回率从61%提升到89%推理耗时从单张4K的120ms增加到240ms4切片并行仍在产线节拍要求内。3.4 小目标的另一个杀手锏合成数据当真实缺陷样本太少200张时与其纠结数据增强不如直接合成。我们用Blender搭建了工件3D模型渲染出带精确标注的合成缺陷图像与真实数据按1:1混合训练。注意事项合成数据的纹理、光照必须与真实数据做域对齐用CycleGAN或简单的颜色迁移合成比例不超过50%否则模型会过拟合渲染器的artifacts必须在纯真实数据上做最终评测合成数据只参与训练。四、 工程层面的“隐形坑”技术问题总有解法但以下这些非技术因素才是项目延期甚至失败的主因4.1 数据标注的一致性比数量重要10倍三个标注员对“划痕”的理解不同一个标了轻微擦痕另一个只标深度划伤。模型学到的就是混乱的决策边界。花一周时间制定标注SOP、做交叉验证、计算标注员间Kappa系数比多标5000张图有用得多。我们的标准是Kappa0.8的数据批次全部返工。4.2 别在开发机上训完就直接部署开发机用的是RTX 4090产线用的是Jetson Orin。同样的ONNX模型在不同硬件上的数值精度可能有微小差异这些差异经过NMS放大后可能导致边界case的结果翻转。务必在目标部署硬件上做完整的精度回归测试而不仅仅是速度benchmark。4.3 建立线上数据回流闭环产线运行3个月后光源老化、工件换型、新工艺引入……模型一定会退化。提前设计好低置信度样本自动保存人工复核结果回传标注平台每月自动触发增量训练精度对比新版本灰度发布机制新旧模型并行跑一段时间对比结果一致才切换。没有数据回流的工业AI项目交付之日就是衰退之始。五、 总结工业YOLO落地的思维转变学术思维工业思维mAP越高越好满足产线CT和良率要求即可数据越多越好数据质量数量标注一致性是生命线模型越新越好部署稳定、生态成熟、可维护性优先一个模型解决所有问题分治策略多视角、多模型、预处理解耦调参靠直觉调参靠数据分析AB测试业务指标反馈交付模型文件交付可持续迭代的系统工业视觉AI不是一个纯算法问题它是一个“光学机械算法软件业务流程”的系统工程。YOLO只是其中一环把它放在正确的位置、用正确的方式使用才能发挥真正的价值。希望这篇踩坑记录能帮你少走一些弯路。如果你有具体的工业检测场景问题欢迎评论区交流我会尽量结合实际经验回复。本文所述方案均来自真实项目实践敏感信息已脱敏。代码片段为示意性伪代码实际使用需根据具体框架适配。转载或引用请注明出处。