目标检测算法¶
目标检测(Object Detection)是计算机视觉的核心任务之一:给定一张图像,找出其中所有感兴趣的物体,输出每个物体的类别和位置(边界框)。
一、任务定义¶
输入与输出¶
- 输入:一张 RGB 图像 \(I \in \mathbb{R}^{H \times W \times 3}\)
- 输出:一组检测结果 \(\{(c_i, s_i, b_i)\}_{i=1}^{N}\),其中:
- \(c_i\):类别标签(如"猫"、"车")
- \(s_i\):置信度分数(模型对这个检测有多确定)
- \(b_i = (x, y, w, h)\):边界框(Bounding Box),表示物体的位置和大小
与相关任务的区别¶
| 任务 | 输出粒度 | 输出内容 |
|---|---|---|
| 图像分类 | 图像级 | 整图一个类别标签 |
| 目标检测 | 物体级 | 每个物体的类别 + 边界框 |
| 图像分割 | 像素级 | 每个像素的类别标签 |
二、核心概念¶
1. 交并比(IoU)¶
IoU(Intersection over Union)是衡量两个边界框重叠程度的核心指标:
- \(\text{IoU} = 1\):两个框完全重合
- \(\text{IoU} = 0\):两个框没有重叠
- 通常 \(\text{IoU} \geq 0.5\) 被认为是一个"正确"的检测
2. 非极大值抑制(NMS)¶
检测模型通常会对同一个物体输出多个重叠的边界框,NMS 用于去重:
- 将所有检测框按置信度从高到低排序
- 选取置信度最高的框,将其加入最终结果
- 删除所有与它 IoU > 阈值(如 0.5)的其他框
- 对剩余的框重复步骤 2-3,直到没有框剩余
graph LR
A[所有检测框] --> B[按置信度排序]
B --> C[选最高分框]
C --> D[删除高IoU重叠框]
D --> E{还有框?}
E -->|是| C
E -->|否| F[输出最终结果]
3. Anchor(锚框)¶
Anchor 是预设的一组不同大小和宽高比的参考框,检测模型在每个位置基于 anchor 做两件事:
- 分类:这个 anchor 位置有没有物体?是什么类别?
- 回归:边界框需要怎样调整才能更准确地框住物体?
其中 \((a_x, a_y, a_w, a_h)\) 是 anchor 参数,\((t_x, t_y, t_w, t_h)\) 是网络预测的偏移量。
4. 评价指标¶
Precision 与 Recall¶
- Precision(精确率):检测出的物体中有多少是对的?\(P = \frac{TP}{TP + FP}\)
- Recall(召回率):所有真实物体中有多少被检测到?\(R = \frac{TP}{TP + FN}\)
AP 与 mAP¶
- AP(Average Precision):某一类别的 Precision-Recall 曲线下面积
- mAP(mean AP):所有类别 AP 的平均值,是目标检测最常用的评价指标
三、两阶段检测器(Two-Stage Detectors)¶
两阶段方法先生成候选区域(Region Proposals),再对每个候选区域做分类和框回归。精度高但速度相对较慢。
R-CNN 系列演进¶
graph LR
A[R-CNN<br/>2014] --> B[Fast R-CNN<br/>2015]
B --> C[Faster R-CNN<br/>2015]
C --> D[Mask R-CNN<br/>2017]
R-CNN(2014)¶
开山之作,首次将 CNN 引入目标检测。
流程:
- 使用 Selective Search 在图像中生成约 2000 个候选区域
- 将每个候选区域缩放到固定大小,送入 CNN 提取特征
- 用 SVM 分类器判断类别
- 用线性回归器微调边界框位置
R-CNN 的缺点
- 每张图要对约 2000 个区域分别做 CNN 前向传播,极其缓慢(一张图约 47 秒)
- 多阶段训练(CNN → SVM → 回归器),流程复杂
- 特征需要存储到磁盘,占用大量空间
Fast R-CNN(2015)¶
核心改进:整张图只做一次 CNN 前向传播,用 RoI Pooling 从共享特征图上提取各候选区域的特征。
RoI Pooling 原理:
- 将候选区域映射到特征图上的对应位置
- 将该区域均匀分成 \(H \times W\) 个网格(如 \(7 \times 7\))
- 对每个网格做 max pooling,得到固定大小的特征
相比 R-CNN 的提升
- 速度提升约 25 倍(特征共享,不用重复计算)
- 端到端训练(分类和回归联合优化)
- 但候选区域生成(Selective Search)仍然很慢
Faster R-CNN(2015)¶
核心创新:用 RPN(Region Proposal Network) 替代 Selective Search,完全用神经网络生成候选区域。
graph TB
A[输入图像] --> B[Backbone CNN]
B --> C[共享特征图]
C --> D[RPN<br/>生成候选区域]
C --> E[RoI Pooling]
D --> E
E --> F[分类 + 回归]
RPN 的工作方式¶
- 在特征图的每个位置放置 \(k\) 个不同大小和宽高比的 anchor
- 对每个 anchor,输出两个值:
- 前景/背景分数:这里有没有物体?
- 边界框偏移:anchor 需要怎样调整?
- 经过 NMS 后,保留得分最高的若干候选框
Faster R-CNN 的地位
Faster R-CNN 是两阶段检测器的奠基之作,其"backbone + RPN + detection head"的架构范式影响了后续几乎所有检测模型。
FPN(特征金字塔网络,2017)¶
解决的问题:小物体检测效果差,因为深层特征图分辨率太低。
核心思想:自顶向下构建多尺度特征金字塔,融合低层的高分辨率信息和高层的强语义信息。
graph LR
subgraph 自底向上
A1[C1] --> A2[C2] --> A3[C3] --> A4[C4] --> A5[C5]
end
subgraph 自顶向下 + 横向连接
A5 --> B5[P5]
B5 --> B4[P4]
A4 -.-> B4
B4 --> B3[P3]
A3 -.-> B3
B3 --> B2[P2]
A2 -.-> B2
end
FPN 在不同层级的特征图上分别检测不同大小的物体:P2 检测小物体,P5 检测大物体。
四、单阶段检测器(One-Stage Detectors)¶
单阶段方法直接在特征图上预测类别和边界框,跳过候选区域生成步骤。速度快,适合实时应用。
YOLO 系列¶
You Only Look Once——整张图只看一次就完成检测。
YOLOv1(2016)¶
核心思想:将检测视为一个回归问题。
- 将图像划分为 \(S \times S\) 的网格(如 \(7 \times 7\))
- 每个网格预测 \(B\) 个边界框和 \(C\) 个类别概率
- 每个边界框包含 5 个值:\((x, y, w, h, \text{confidence})\)
- 网络输出维度:\(S \times S \times (B \times 5 + C)\)
YOLOv1 的突破
- 速度极快:45 FPS(Fast YOLO 达 155 FPS),而 Faster R-CNN 只有约 7 FPS
- 全局推理:看到整张图再做决策,背景误检率低
YOLOv1 的局限
- 每个网格只预测 2 个框,对密集物体效果差
- 对小物体检测能力弱
- 定位精度不如两阶段方法
YOLOv2/v3 的改进¶
| 版本 | 关键改进 |
|---|---|
| YOLOv2 | 引入 anchor、Batch Normalization、多尺度训练、Darknet-19 |
| YOLOv3 | 三个尺度检测(FPN 思想)、Darknet-53、多标签分类 |
YOLOv5/v8 的现代化¶
| 特性 | 说明 |
|---|---|
| 架构 | CSPNet backbone + PANet neck + 解耦检测头 |
| 训练技巧 | Mosaic 数据增强、自适应 anchor、CIoU 损失 |
| 部署 | 支持 ONNX、TensorRT、CoreML 等多种推理框架 |
| Anchor-free | YOLOv8 采用 anchor-free 设计,简化流程 |
SSD(Single Shot MultiBox Detector,2016)¶
核心思想:在多个不同尺度的特征图上同时检测不同大小的物体。
与 YOLO 的区别:SSD 在 6 个不同尺度的特征图上放置 anchor 并预测,对小物体更友好。
与两阶段方法的对比¶
| 维度 | 两阶段(Faster R-CNN) | 单阶段(YOLO/SSD) |
|---|---|---|
| 速度 | 慢(~7 FPS) | 快(~45+ FPS) |
| 精度 | 高 | 略低(但差距在缩小) |
| 适用场景 | 精度优先(医学影像) | 实时性优先(自动驾驶) |
| 候选区域 | 需要 RPN | 不需要 |
五、Anchor-Free 检测器¶
传统检测器依赖预设的 anchor,anchor 的设计(大小、宽高比、数量)需要大量调参。Anchor-free 方法直接预测目标的关键点或中心点。
CenterNet(2019)¶
核心思想:将目标检测视为关键点检测——只需找到物体中心点,然后回归宽高。
- 用网络输出一张热力图,每个位置的值表示"这里是某类物体中心"的概率
- 在热力图上找到峰值点(局部最大值)
- 对每个峰值点回归物体的宽高
优点:无需 anchor,无需 NMS(峰值点天然不重复),简洁优雅。
FCOS(Fully Convolutional One-Stage,2019)¶
核心思想:特征图上每个位置直接回归到边界框四条边的距离 \((l, t, r, b)\)。
加入 Center-ness 分支抑制低质量检测框。
六、基于 Transformer 的检测器¶
DETR(Detection Transformer,2020)¶
Facebook 提出的端到端目标检测方法,用 Transformer 替代了 anchor + NMS。
核心流程:
graph LR
A[图像] --> B[CNN Backbone]
B --> C[Transformer Encoder]
C --> D[Transformer Decoder]
D --> E[FFN 预测头]
E --> F[类别 + 边界框]
- 用 CNN 提取特征图,展平为序列
- Transformer Encoder 做全局自注意力
- Transformer Decoder 使用 \(N\) 个可学习的 Object Query,每个 query 负责检测一个物体
- 用匈牙利匹配(二分图匹配) 在训练时将预测结果与 ground truth 做一一匹配
DETR 的突破与局限
突破:完全去除 anchor 和 NMS,真正端到端。
局限:训练收敛慢(需要 500 epoch),小物体检测效果差。
后续改进:Deformable DETR(可变形注意力,加速收敛)、DAB-DETR、DINO 等。
七、损失函数¶
目标检测的损失函数通常有三部分:
分类损失 \(L_{\text{cls}}\)¶
常用交叉熵损失或 Focal Loss:
Focal Loss 解决了什么问题?
在单阶段检测器中,绝大多数 anchor 都是负样本(背景),正负样本比例极度不平衡。Focal Loss 通过 \((1-p_t)^\gamma\) 项给简单样本(模型已经很确定的)降权,让模型更关注困难样本。
回归损失 \(L_{\text{reg}}\)¶
| 损失 | 公式 | 特点 |
|---|---|---|
| Smooth L1 | $\begin{cases}0.5x^2 & | x |
| IoU Loss | \(1 - \text{IoU}\) | 直接优化评价指标 |
| GIoU | $1 - \text{IoU} + \frac{ | C \setminus (A \cup B) |
| CIoU | GIoU + 中心距离 + 宽高比 | 更快更稳定的收敛 |
八、总结与选型建议¶
graph TB
A{需求场景} -->|精度优先| B[Faster R-CNN + FPN]
A -->|速度优先| C[YOLOv8 / YOLOv5]
A -->|端到端简洁| D[DETR / RT-DETR]
A -->|小物体多| E[加 FPN / 多尺度检测]
A -->|密集物体| F[Anchor-free 方法]
| 场景 | 推荐方法 | 理由 |
|---|---|---|
| 实时检测(自动驾驶、视频监控) | YOLOv8 | 速度快、精度好、部署方便 |
| 高精度检测(医学影像) | Faster R-CNN + FPN | 两阶段精度更高 |
| 科研 / 新范式探索 | DETR 系列 | 端到端,便于扩展 |
| 边缘设备部署 | YOLOv5-nano / v8-nano | 轻量化设计 |