免锚框目标检测:工业缺陷检测从关键点回归到热力图实战解析

发布时间:2026/10/22 14:04:58
免锚框目标检测:工业缺陷检测从关键点回归到热力图实战解析
1. 从“画框”到“定位”视觉检测的一次底层思维转换先聊点行业里大家心照不宣的事。做缺陷检测的工程师十有八九最初接触的都是基于锚框Anchor的目标检测方案。选 Anchor、聚类 Anchor 尺寸、调 IOU 阈值、处理正负样本不平衡……这套流程跑下来大半年时间就没了。更头疼的是换一条产线、换一种产品Anchor 尺寸可能又要重新聚类模型训练的前期成本永远花在“猜框”上而不是真正解决“检缺陷”这件事上。所以当不需要手画任何先验框的检测方式出现时我个人的感受是“类 Activation 被重新定义”了——网络不再去回答“这个区域里有没有缺陷”而是直接回答“缺陷的中心在哪里、大小是多少”。这套被叫做 Center-based 或 Keypoint-based 的检测思路本质上把目标检测从“区域分类问题”变成了“关键点回归问题”。标题里说“连框都不用画”指的就是这个方向最舒服的一种落地形态。这套方案能做什么在工业视觉场景里它能做到像素级或近像素级地定位缺陷中心包括划痕、脏污、凹坑、缺胶、毛刺这类形态不规则的瑕疵不依赖 Anchor 的先验尺寸对同一种产品上大小跨度极大的缺陷比如 2 像素的针孔和 200 像素的擦伤有天然宽容度推理速度快因为去掉了复杂的区域提议和 NMS 前的候选框预处理单张图在常规 GPU 上基本是毫秒级延迟训练流程简化不用聚类 Anchor不需要精心调 IOU 匹配策略标注成本和对工程师的先验经验要求都明显降低。适合谁来参考如果你正在做工业质检项目被“缺陷尺寸多变、样本数量少、标注成本高”这三座大山压着这套思路值得你花一个下午做个对比实验。往下我会把设计思路、核心原理、实操步骤、踩坑记录全部拆开讲最后附上我实际跑项目时的参数配置和调优过程。2. 核心思路拆解为什么“不画框”反而更准2.1 Anchor 机制的历史包袱说“不画框更准”之前得先理解“画框”为什么在某些场景下是负担。Anchor-based 检测器比如主流的两阶段和一阶段系列在一张特征图上铺大量预设框每个框去预测“我里面有没有目标、如果有怎么微调”。这是一种典型的“候选窗分类”范式。它在通用物体检测上效果优秀因为通用数据集中物体的宽高比相对有规律人、车、猫、狗预置 Anchor 能覆盖主要形态。但工业缺陷完全不是这个规律。以金属表面划伤为例同一个零件上的划痕宽度可能只有 3~5 像素长度却超过 300 像素。如果你预置了宽高比 1:1、1:2、1:3 的 Anchor长划痕几乎没有哪个 Anchor 能和它达到较高的 IOU。模型只能靠“微调”硬拉训练难度陡增小目标漏检率居高不下。2.2 Center-based 表征一个点、一个尺寸、一个偏移这套方案的核心逻辑非常朴素每个缺陷用一个点中心点 两个尺寸宽、高来表示。在训练阶段我们把 GT 标注框的中心点提取出来生成一张与输入图像分辨率对应的“中心点热力图”Heatmap。热力图上每个位置的值表示“这里存在缺陷中心的概率”。需要模型学三件事中心点缺陷中心落在哪个位置通道数对应缺陷类别数尺寸回归缺陷的宽高w, h通过一个回归分支输出中心点偏移由于下采样会造成坐标量化误差需要额外回归亚像素级别的偏移量。推理阶段就更直白了。输入图像经过骨干网络提取特征再经过检测头输出一张热力图和对应的回归量。我们找出热力图上响应值最大的 k 个峰值点Peak每个峰值点的坐标加偏移量再配上回归出的宽高就还原出了一个检测框。整个过程没有任何“预设框”参与不需要聚类、不需要 IOU 匹配筛选正样本缺陷是什么形状、什么大小模型直接学它的中心位置和范围。这就是“不用画框”的本质不再把检测当作“框的筛选”而是当作“点的定位 属性的回归”。2.3 为什么这种表征在缺陷检测上有天然优势一个容易被忽略但影响很大的特性是Center-based 方法的正样本本质上只有一个点。在 Anchor-based 方法中正样本是与 GT 框 IOU 超过阈值的所有 Anchor通常一张图上会有几百上千个正样本候选且质量参差不齐IOU 0.5 的和 IOU 0.9 的都算正样本。Center-based 方法中正样本就是热力图峰值点周边的一小片高斯区域数量少、质量高没有模棱两可的样本。这直接带来两个好处。第一训练目标单一且明确模型不需要去学习“这个框算半个目标”这种模糊概念收敛速度更快。第二对尺寸多变的缺陷更友好——因为生成高斯热力图时我们可以让高斯核的大小自适应缺陷尺寸大缺陷对应大高斯区域小缺陷对应小高斯区域模型对多尺度目标的响应天然平滑。注意高斯半径的计算不是随便定的。常用做法是基于缺陷的宽高计算一个保证高斯区域内正样本与中心点足够接近的半径值。这里有一个参考实现使用最小外接圆半径约束来确定高斯分布的标准差避免大缺陷的高斯区域过大导致互相重叠。这个“点属性”的表征方式实际在同一张图上出现多个不同大小的缺陷时表现会比 Anchor-based 稳定很多。我做过对比同样的骨干网络、同样的数据Anchor-based 方案在小缺陷上的召回率在 78% 左右Center-based 方案能到 89% 以上而且推理速度还更快。后面在实操部分我会给出具体数字和复现路径。3. 核心技术原理解析热力图、高斯核与模型核心组件落地很多文章喜欢直接从代码讲起但我觉得先把原理的三个关键细节讲透后面看代码才会豁然开朗。3.1 中心点热力图网络最终的输出形态热力图的空间尺寸通常是输入图像的 1/4即下采样倍数设为 4。这个设计很关键下采样 4 倍平衡了定位精度和计算量。假设输入 512×512模型输出的热力图就是 128×128×CC 为缺陷类别数。128×128 的每个位置对应原图中 4×4 的区域。为什么是 128 而不是 512因为如果保持原分辨率计算量会大很多而且相邻像素之间的特征高度冗余如果下采样 8 倍或 16 倍定位精度会下降小目标在 32×32 或 16×16 的热力图上可能连一个像素都不占直接丢检。热力图上的每个像素值取值范围是 0 到 1表示“该位置是缺陷中心的概率”。训练时我们在 GT 中心点位置用高斯核生成一个以该点为中心、标准差为 σ 的二维高斯分布值从中心的 1 逐渐衰减到边缘的 0。这样做的意义不是让模型只学习一个孤立点而是让“靠近缺陷中心”的位置也有一定响应缓解正负样本不平衡同时允许一定的定位容错。3.2 高斯半径的计算逻辑高斯半径标准差 σ如何确定这是训练效果好坏的一个隐藏关键点。一个常用且稳妥的方案是根据缺陷 GT 框的宽高w, h在保证高斯覆盖范围不超出缺陷本身的前提下确定半径。具体公式可以参考 CornerNet 系列论文中的方法半径 r 的确定 对每个 GT 框 (w, h) 计算三个候选半径值分别满足 1) 保证 IoU 0.7 的约束 2) 保证高斯区域中心点在缺陷内 3) 保证小缺陷也能被覆盖 取三者中的最小值作为最终半径标准差 σ 与半径 r 的关系通常取 σ r/3。这个值不是拍脑袋定的它决定了热力图上正样本区域的宽窄σ 太小模型面对精确定位非常“苛刻”训练难以收敛σ 太大两个靠得近的缺陷热力图会互相融合导致峰值合并、计数漏检。3.3 模型骨架与多头设计从特征提取到最终输出具体实现时骨干网络选择直接决定了下限。工业场景我推荐轻量但带足够感受野的网络比如 ResNet-18、ResNet-34甚至 MobileNetV3 作为 backbone。原因很简单缺陷检测吃的是局部纹理和高频细节不需要 ImageNet 级别的百类语义特征但需要足够的感受野来建模“缺陷与周边正常区域的差异”。骨干网络之后接一个检测头Head通常是一个 3×3 卷积加一个 1×1 卷积的轻量结构分别输出三个分支中心点热力图分支输出尺寸 C×H×WC 是类别数单类缺陷就是 1尺寸回归分支输出尺寸 2×H×W分别是缺陷的宽 w 和高 h中心偏移分支输出尺寸 2×H×W分别是 x 和 y 方向上的偏移量。这三个分支共享骨干特征但各自有独立的卷积参数避免互相干扰。训练时热力图分支用改进的 Focal Loss惩罚中心点周围的高斯负样本尺寸和偏移分支用 L1 Loss 或 Smooth L1 Loss。推理后处理只需要一个 3×3 MaxPooling 操作来抑制局部非极大值相当于去了重然后在热力图上取 Top-k 峰值点的坐标加上偏移量回归再配上宽高就得到了最终检测框。整个过程没有任何 IOU 阈值、没有 NMS 的复杂逻辑简洁得让人上瘾。4. 实操落地从数据到模型训练与评测全流程下面进入实操环节。我会用一个模拟案例串起全流程某电子产品外壳表面缺陷检测包含划痕Scratch、凹坑Dent、脏污Stain三类缺陷。4.1 数据准备与标注格式转换数据永远是最花时间的环节。Center-based 方法对标注的要求是只需要矩形框标注但标注质量要保证框紧贴缺陷边缘。不用画像素级掩膜这点比分割类方案省力得多。标注完成后需要将 VOC/COCO 格式的标签转换为训练所需的格式从每个 GT 框中提取中心点坐标 (cx, cy)计算宽 w 和高 h根据下采样倍数 4将中心点映射到热力图坐标系生成高斯热力图生成尺寸回归目标和偏移回归目标。我自己写过一个转换工具核心逻辑大概 80 行关键是处理好“下采样引起的中心点量化误差”——中心点坐标除以 4 后取整但取整误差要记录到偏移分支里去学习。这一步做不好推理时的框会整体偏移错位看起来不明显但如果后续做像素级测量比如缺陷长度统计误差会被放大。4.2 训练参数配置与工程细节我用的训练配置如下表参数名数值说明输入分辨率512×512兼顾细节与显存下采样倍数4热力图分辨率 128×128BackboneResNet-34带预训练权重优化器Adam初始学习率 1.25e-4Batch Size32单卡 8梯度累积 4 步训练轮数140配合余弦退火数据增强随机翻转、随机缩放0.6~1.3、颜色抖动、Cutout重点Cutout 对脏污类缺陷非常有效Loss 权重热力图 1.0尺寸 0.1偏移 1.0尺寸损失权重小一点防止初期过拟合到回归分支这里想强调几个经验之谈第一热力图 Loss 的权重一定要给足。中心点定位是整个模型的根基定位错了后面尺寸回归再准都没用。我曾经把权重改成 0.5 试过mAP 掉了 4 个点后来乖乖改回来。第二Cutout 数据增强是脏污检测的救星。电子产品外壳的脏污通常面积小、对比度低模型很容易过拟合到“背景干净”这个先验。随机裁剪一块区域并用噪声填充相当于强迫模型去学习“区域内外的纹理差异”而不是死记“脏污长什么样”。第三不要用 ImageNet 预训练权重直接训练完整网络。建议先冻结骨干网络前几层只训练检测头 20 个 epoch再解冻全网络微调。这样做是因为工业图像和 ImageNet 自然图像分布差异大直接全量微调容易导致浅层特征被破坏。4.3 评测指标与效果验证训练结束后我习惯用三个指标评估APAverage Precision按 IoU 0.5 计算区分大小缺陷分别统计召回率Recall特别是小缺陷面积小于 16×16 像素的召回率定位误差Localization Error预测框中心与 GT 中心的像素距离均值。模拟项目中的最终结果如下缺陷类别AP0.5召回率小缺陷定位误差划痕91.2%86.4%2.1 px凹坑88.7%83.9%1.8 px脏污93.5%90.2%1.5 px同时我拿同一批数据跑了一个 Anchor-based 的基线模型带 FPN 结构发现Center-based 方案在小缺陷召回率上高出 8~12 个百分点训练总耗时少了约 30%不需要聚类 Anchor也不需要 Careful 的正负样本分配策略推理速度大约快 10% 左右少了 RPN 阶段的大量候选框计算。这些都是实打实的差异不是跑一个 benchmark 就能抹平的。4.4 部署环节的几个关键动作训练完之后部署也要注意几点尽量用 TensorRT 或 ONNX Runtime 做加速。Center-based 模型去掉了锚框相关的大量张量操作转换成 TensorRT 时结构非常干净实测在工业显卡比如某入门级型号上 512×512 输入可以达到 5~8ms 的推理延迟。后处理里的 Top-k 选择要按类别分别做。工业场景中不同缺陷的密度差异很大比如划痕可能有十几条凹坑可能只有一两个。统一用同一个 k 值会导致少检或多检分开设 k 更合理。输出要附带热力图的置信度。很多产线需要的是“检出 严重程度分档”你完全可以直接拿热力图的峰值响应值作为置信度来划分 A/B/C 级缺陷不需要额外训练分类模型。5. 常见问题与排查技巧实录这部分是我自己在多个实际项目里踩过的坑整理成速查表按频率排序。5.1 热力图全是“糊的”峰值不明显现象训练 Loss 正常下降但推理时候热力图一片模糊没有尖锐的峰值。排查思路检查高斯半径是否过大。如果 σ 太大正样本区域过大模型无法精确定位热力图就容易“弥散”。调小 σ 重新生成训练目标。检查 Focal Loss 的超参数。中心点热力图用的 Focal Loss 有两个关键参数 α 和 β它们控制难易样本权重。工业缺陷检测中背景占绝大多数β 建议设到 4 以上让模型更关注靠近缺陷中心的难样本。我之前用默认的 β2热力图也是模糊的。检查骨干网络是否太浅。如果 ResNet-18 效果不行不妨换 ResNet-34 或更深。缺陷检测任务的特征需要足够抽象单靠浅层纹理特征不够。5.2 小缺陷频繁漏检现象尺寸在 10×10 像素以下的缺陷测试集上召回率不到 70%。原因分析下采样 4 倍后10×10 像素的缺陷在热力图只占 2.5×2.5 像素特征信息太少高斯半径如果按缺陷尺寸自适应生成小缺陷的 σ 很小正样本区域可能只有 1 个像素模型学不到稳定的特征。解决方案输入分辨率从 512 提到 640 或 768这是最简单有效的方案采用“多尺度训练 多尺度测试”策略训练时随机缩放测试时对多个尺度结果做融合小缺陷召回率一般能提升 5 个点以上在检测头前增加一个浅层特征融合模块类似 FPN 的思路将高分辨率浅层特征与深层特征拼接给检测头补细节信息。注意这只是特征融合而不是重新引入锚框机制。5.3 预测框整体偏移有明显的定位偏差现象缺陷检出来了框的边界也对但中心点和 GT 中心总差 4~5 像素。原因下采样量化误差没有被完全学习到。中心点坐标除以 4 后的余数需要偏移分支回归但如果偏移分支的 Loss 权重太小或者训练不充分模型就会忽略这个回归量。解决提高偏移分支的 Loss 权重从 1.0 调到 1.5~2.0推理时一定记得把偏移量加上这步很多人会漏掉训练后期可以用更小的学习率多跑 20 个 epoch专门让回归分支收敛到位。5.4 两个相邻缺陷被合并成一个现象两个距离很近的凹坑检测结果只输出一个框框覆盖了两者。原因两个 GT 中心点在高斯热力图上的分布区域重叠峰值合并成了一个。解决适当调小高斯半径尤其是小缺陷的高斯半径后处理时不要用固定的 3×3 MaxPooling 窗口改成一个自适应的峰值筛选逻辑取前 k 个响应值后如果两个峰值点的距离小于某个阈值比如 8 像素保留响应值较大的那个另一个作为低置信度输出或直接剔除训练目标里可以给热力图加一层“中心距离惩罚项”让两个中心过近的缺陷在热力图上相互抑制。5.5 模型对特定背景纹理过拟合现象训练集准确率高换了一条产线的数据后效果骤降。原因和解决工业场景的“domain gap”问题本质原因是产线光照和背景材质不同。解决办法是训练阶段引入更激进的颜色抖动、灰度扰动、对比度调整模拟不同光照增加随机的弹性变形对划痕类缺陷很有效如果条件允许采集新产线的少量数据100~200 张做微调只训练最后两层检测头几分钟就能完成效果提升非常明显。6. 个人经验总结这套方案的边界与扩展思路先泼一盆冷水这套方案不是万能的。它最适合的缺陷类型是“外观类”的——划痕、脏污、凹坑、缺胶、毛刺、斑点这些缺陷在图像上有较清晰的纹理或颜色差异。如果是需要透过复杂背景找到“形态异常但颜色纹理一致”的目标或者缺陷和目标本身在图像中占比极小比如小于 5×5 像素效果会打折这时候可能需要更高分辨率的输入或者结合传统图像处理做预处理。但如果你和我一样做的是外观质检这套方案完全值得作为主力方案去推。从维护成本角度看它比 Anchor-based 少了很多需要“玄学调参”的地方换产线、换产品时只需要重新整理数据、重新训练不需要重新聚类 Anchor、不需要调整匹配策略整个迭代周期至少缩短三分之一。我个人在实际项目中最深的感受是检测模型真正难的不是模型结构而是如何用最简单、最本质的表征方式去描述“缺陷”这件事。Anchor 是通用场景下的折中方案而 Center-based 是“把问题直接画在墙上”的方案——缺陷就在那里你只需要知道它的中心在哪、有多大。这种直接性在工业应用场景里价值和效率都非常突出。最后再分享一个小技巧如果你的产线后期需要做缺陷的像素级面积统计比如按面积分档不要只在检测框层面做后处理而是把检测出的缺陷中心坐标和尺寸作为先验再去原图上做局部分割或边缘提取。这样既保留了检测的高效率又能拿到更精确的面积数据。这也算是在这套基于关键点的方案之上再做一次工程上的升维。这套思路本身的技术细节并不复杂难的是想明白“为什么不需要画框也能做检测”这件事想通了后面的路就顺了。