跳到主要内容

2D感知算法与任务

摘要:本文整理图像感知任务、数据集与检测评价方法,在 R-CNN 系列基础上补充 YOLO 与 CenterNet,重点理解网络预测什么、如何解码为检测框,以及不同检测思路的联系。

2D感知任务​

输入:相机生成的单帧或连续图像数据

  • 单张图像
  • 图像序列

输出:

  • 稀疏:物体的位置,大小,速度等
  • 稠密:每个像素点的类别标签

算法:

  • 物体检测
  • 物体跟踪
  • 语义分割

数据库和基准测试​

通用数据库

  • PASCAL-VOC,MS COCO,MOT等

自动驾驶数据库

  • KITTI,NuScenes,Waymo

两者的区别

  • 采集场景不同
  • 采集环境不同
  • 物体类别不同
  • 物体位置分布不同
  • 标注信息不同

数据集的对比

数据集的划分

  • 训练集、验证集和测试集
  • 测试集:不同难度的子集(比如按照遮挡程度,物体大小)

性能指标

  • 算法输出与手工标注的重合程度:Intersection over Union(IoU)
  • 阈值设定:高于阈值则为正确检测,否则为无效检测
  • True Positive(TP),False Positive(FP),False Negative(FN)
  • Precision(P),Recall(R),PR曲线
  • Average Precision(AP)
  • mean AP(mAP)

性能指标

物体检测算法​

检测方法可以从候选区域、密集预测、中心点表示和集合预测等思路理解:R-CNN 系列逐步发展候选区域检测;YOLO 系列直接进行密集预测;本文的 CenterNet 用中心点表示目标;DETR 等方法使用 Transformer 进行集合预测。Anchor、后处理与运行速度取决于具体版本和实现,不能简单认为 YOLO 都使用 Anchor,或 Transformer 检测器都无法实时。

传统物体检测

候选窗口:滑动窗口(稠密),显著性图(稀疏)

特征提取:Haar特征,HOG特征

分类器:AdaBoost,Decision,SVM

问题:针对不同任务,需要手工设计不同的特征,选择不同的分类器

R-CNN算法

  • 选择性搜索替代滑动窗口
  • 卷积神经网络提取图像特征(ImageNet上预训练)
  • 窗口特征采用SVM进行分类

R-CNN

问题:窗口数量重叠太多,导致特征提取的冗余,影响算法的运行效率(20s)

Fast R-CNN

  • CNN提取全图的特征,避免冗余计算
  • 在候选框中进行ROI Pooling
  • 全连接网络进行分类和边框回归

Fast R-CNN

问题:通过选择性搜索来得到候选区域,整个过程依然比较慢(2s)

FPN(Feature Pyramid Network)

  • 特征提取阶段进行优化
  • 金字塔结构提取多尺度信息
  • 适应不同大小的物体

上述算法改进对比:

上述算法改进对比

YOLO:将目标检测转为密集预测​

YOLO(You Only Look Once)的核心思路是通过一次网络前向计算预测类别与边界框,避免对大量候选区域分别提取图像特征。这里的“一次”不代表无需图像预处理、输出解码或后处理。参考:YOLO 原论文。

image-20261018093744965

1. 先分清 YOLO 的不同版本​

YOLO 是一系列检测方法,不是一套始终不变的输出格式。学习时应先注明版本,再讨论 Anchor、损失函数与 NMS。

方法目标表示的特点需要避免的误解
YOLOv1将图像分为网格,预测边界框与类别不能用它的输出布局解释所有版本
YOLOv2 / YOLOv3使用 Anchor,围绕预设框预测位置和尺寸Anchor 是先验框,不是最终结果
YOLOv8 检测模型使用 Anchor-free 检测头Anchor-free 不等于没有特征网格或参考点

YOLOv8 的结构说明见 Ultralytics 官方文档。不同版本的训练标签分配、分类分数含义与框解码方式可能不同,不能拿同一段后处理代码直接套用。

2. 从输入图像到检测框​

常见处理链可以概括为:

  1. 预处理:调整输入尺寸、填充边缘并归一化,保存缩放比例和填充量。
  2. Backbone:提取边缘、纹理以及更高层的语义特征。
  3. Neck:融合不同分辨率的特征,帮助处理不同尺寸的目标;具体结构依版本而定。
  4. Head:在特征位置预测类别、位置及版本相关的其他输出。
  5. 解码与筛选:恢复框坐标,按分数过滤,并按实现需要执行 NMS。
  6. 坐标还原:去除填充影响,映射回原始图像。

多尺度预测有助于兼顾大目标和小目标,但并不保证远处小物体一定能检出。输入分辨率、特征步长、遮挡和训练样本都会影响结果。

3. Anchor-based 是如何解码框的​

以 YOLOv3 常见的框参数化为例,某个网格位置为 (cx,cy)(c_x,c_y),Anchor 尺寸为 (aw,ah)(a_w,a_h),网络输出为 (tx,ty,tw,th)(t_x,t_y,t_w,t_h):

bx=σ(tx)+cx,by=σ(ty)+cy,bw=awetw,bh=aheth.\begin{aligned} b_x &= \sigma(t_x)+c_x,\\ b_y &= \sigma(t_y)+c_y,\\ b_w &= a_w e^{t_w},\\ b_h &= a_h e^{t_h}. \end{aligned}

其中 σ\sigma 是 Sigmoid。中心位置使用特征网格单位时,还要乘以对应步长;Anchor 的宽高也必须使用一致单位。该公式解释的是特定版本的 Anchor 解码,不能直接用于 YOLOv8 等其他检测头。参考:YOLOv3 论文。

在带独立 objectness 输出的实现中,常用检测分数可以写为:

sc=P(object)P(c∣object).s_c=P(\mathrm{object})P(c\mid\mathrm{object}).

这说明“框里是否有目标”和“它属于哪个类别”可以分别预测。并非每个 YOLO 版本都输出独立 objectness;实际分数计算应以模型导出格式为准。

4. 为什么需要 NMS​

同一个物体附近可能产生多个候选框。传统 NMS 按分数从高到低保留框,并抑制与已选框高度重叠的其他候选,通常按类别处理。

IoU⁡(A,B)=∣A∩B∣∣A∪B∣.\operatorname{IoU}(A,B)=\frac{|A\cap B|}{|A\cup B|}.

NMS 的 IoU 阈值越低,抑制通常越强,可能误删相邻或重叠目标;阈值越高,可能留下更多重复框。置信度阈值筛选低分预测,NMS 阈值处理重复预测,二者作用不同。还有采用其他去重或端到端输出设计的版本,不能将 NMS 当成所有 YOLO 的必需步骤。

系列算法对比:

image-20261018093835784

CenterNet:将目标表示为中心点​

本文的 CenterNet 指 Objects as Points,不要与其他同名方法混淆。它将每个目标表示为边界框中心,并预测宽高与中心偏移,从而恢复完整边界框。参考:CenterNet 原论文。

1. 网络需要预测什么​

设输入图像大小为 H×WH\times W,输出步长为 RR,类别数为 CC:

输出分支常见形状(忽略 batch)含义
中心热力图C×H/R×W/RC\times H/R\times W/R各类别中心位置的响应
宽高2×H/R×W/R2\times H/R\times W/R目标框宽度与高度
中心偏移2×H/R×W/R2\times H/R\times W/R补偿中心量化到整数网格带来的误差

表中为常见的类别共享宽高配置,具体实现也可能使用类别相关宽高。三个分支共用特征,输出的是互补信息:热力图决定“在哪里、是什么”,宽高决定“有多大”,偏移细化中心位置。

2. 训练时如何表示中心​

image-20261018094122576

设目标框中心为 p=(px,py)p=(p_x,p_y),在输出特征图中的连续位置为 p/Rp/R,量化后的整数网格位置为:

p~=⌊pR⌋,o=pR−p~.\tilde{p}=\left\lfloor\frac{p}{R}\right\rfloor,\qquad o=\frac{p}{R}-\tilde{p}.

oo 是偏移监督。热力图在对应类别中心处设置峰值,并在附近绘制高斯分布,以表达中心周围位置的训练权重;宽高和偏移主要在真实目标的中心位置计算回归损失。

总损失可以概括为:

L=Lheatmap+λsizeLsize+λoffsetLoffset.L=L_{\mathrm{heatmap}}+ \lambda_{\mathrm{size}}L_{\mathrm{size}}+ \lambda_{\mathrm{offset}}L_{\mathrm{offset}}.

中心热力图使用修改的 Focal Loss 思路处理大量背景位置,宽高和偏移采用回归损失。损失权重决定不同分支的训练贡献,并不表示输出框对应的物理单位。

3. 推理时如何解码​

流程是:提取热力图局部峰值 → 选择高分候选 → 在对应位置读取偏移与宽高 → 恢复框坐标。

设峰值所在整数坐标为 (u,v)(u,v),偏移为 (ox,oy)(o_x,o_y):

xc=R(u+ox),yc=R(v+oy).x_c=R(u+o_x),\qquad y_c=R(v+o_y).

在原版常见实现中,宽高分支使用输出特征图尺度。设其预测为 (wf,hf)(w_f,h_f),先换算为网络输入像素单位:w=Rwfw=Rw_f、h=Rhfh=Rh_f,再恢复框:

xmin⁡=xc−w/2,ymin⁡=yc−h/2,xmax⁡=xc+w/2,ymax⁡=yc+h/2.\begin{aligned} x_{\min}&=x_c-w/2,& y_{\min}&=y_c-h/2,\\ x_{\max}&=x_c+w/2,& y_{\max}&=y_c+h/2. \end{aligned}

例如 R=4R=4,峰值为 (50,30)(50,30),偏移为 (0.25,0.5)(0.25,0.5),特征图尺度宽高为 (20,10)(20,10)(换算后为 (80,40)(80,40)),则中心为 (201,122)(201,122),检测框为 (161,102,241,142)(161,102,241,142)。这些是网络输入坐标,还需根据缩放或仿射变换恢复到原始图像。

下面的 NumPy 风格片段只解释单个峰值的解码,假设热力图筛选已完成、宽高与偏移均为通道在前的数组:

# u、v 是选出的整数峰值坐标;stride 是输出步长。
ox, oy = offset[:, v, u]
wf, hf = size[:, v, u] # 原版常见实现:特征图尺度
w, h = stride * wf, stride * hf
cx = stride * (u + ox)
cy = stride * (v + oy)
box = [cx - w / 2, cy - h / 2, cx + w / 2, cy + h / 2]

偏移用于补偿网格量化,不是预测目标相对上一帧的运动。若另一个实现直接回归网络输入像素尺度的宽高,就不应再次乘步长;应核对标签生成、解码和后续坐标变换,避免重复缩放。官方实现可参考 CenterNet 解码代码。

4. CenterNet 不使用传统框 NMS,为什么仍有筛选​

原版中心点检测通常通过热力图局部最大值筛选和 Top-K 提取候选,不依赖传统的逐框 IoU NMS。这并不代表没有任何后处理,也不能将热力图峰值抑制与框 NMS 混为一谈。

中心点表示减少了预设框相关设计,但仍需选择输出步长、峰值筛选规则、分数阈值和损失权重。密集目标中心过于接近、严重遮挡或小目标中心响应较弱时,仍可能漏检。

YOLO 与 CenterNet 放在一起理解​

比较项YOLO 系列本文的 CenterNet
核心表示随版本变化,包含 Anchor 框和 Anchor-free 设计目标框中心点、宽高与偏移
主要输出类别与框位置等,具体布局依版本而定中心热力图、尺寸、偏移
重复候选处理许多版本采用框 NMS,也存在其他设计热力图局部峰值与 Top-K
学习重点特征融合、标签分配、框解码与后处理中心监督、尺度单位、峰值解码

二者都可以通过一次前向计算生成目标预测,区别不能简单概括为“YOLO 有 Anchor、CenterNet 没有”。比较速度时还应统一硬件、输入尺寸、模型规模、精度和后处理范围;不能只看不同论文中各自报告的 FPS。

image-20261018094204821

实践中建议检查的几个问题​

  1. 训练标签和推理结果采用的是像素坐标还是归一化坐标?
  2. 图像是直接缩放、等比例填充,还是做了仿射变换?框如何恢复?
  3. 当前版本的分数是否包含 objectness,是否需要 Sigmoid?
  4. 框宽高位于原图、网络输入还是特征图尺度,是否重复乘了步长?
  5. 漏检来自低分筛选、重复抑制,还是模型本身没有预测目标?

先用一张图像逐项检查,再扩展到视频和跟踪,更容易区分模型效果与后处理错误。

本篇文章受 CC BY-NC-SA 4.0 协议保护,转载请注明出处。