← 返回学习笔记

Lecture 6:目标检测

408 学习笔记:Lecture 6:目标检测。保留原有知识内容、公式与图示;有对应原件时提供查看和下载入口。

本页目录

描述:本节区分分类、定位、目标检测和分割,整理 Viola-Jones 的 Haar 特征、积分图与 AdaBoost,并系统说明边界框、IoU、锚框、NMS、R-CNN、Fast R-CNN、Faster R-CNN、SSD 和 YOLO。

6.1 视觉任务的区别

6.1.1 图像分类

输入整张图像,输出一个或多个类别,不要求目标位置。

6.1.2 分类与定位

图中通常假设只有一个主要目标,同时输出:

  • 类别。
  • 一个包围目标的边界框。

6.1.3 目标检测

图中可有多个目标,需要为每个实例输出:

  • 类别。
  • 置信度。
  • 边界框。

6.1.4 语义分割与实例分割

  • 语义分割:给每个像素分配语义类别,同类实例不区分。
  • 实例分割:既给像素分类,又区分同类的不同目标实例。

源课件说这些任务“都需要目标分割”,不准确。目标检测只要求边界框,不必先得到像素级分割;R-CNN 的 selective search 使用区域分割生成候选框,是某一历史方法,不是所有检测器的必要步骤。

6.2 滑动窗口检测

传统方法可在不同尺度上用窗口逐位置扫描图像:

  1. 选择固定大小窗口。
  2. 遍历所有空间位置。
  3. 改变图像或窗口尺度,重复扫描。
  4. 对每个窗口做目标/背景分类。

问题:

  • 窗口位置、尺度和长宽比组合非常多。
  • 相邻窗口高度重叠,重复计算严重。
  • 步长过大又容易漏检。

Viola-Jones 人脸检测通过积分图、AdaBoost 特征选择和级联分类器显著加速这一流程。

6.3 Haar-like 特征

Haar-like 特征由相邻白色/黑色矩形区域组成,特征值通常是白色区域像素和减去黑色区域像素和。

典型模式:

  • 两矩形水平或垂直差。
  • 三矩形中心与两侧差。
  • 四矩形对角差。

它们可描述人脸中的明暗对比,例如:

  • 眼睛区域通常比面颊暗。
  • 鼻梁区域与两侧存在亮度差。

在 $24\times24$ 检测窗口中,所有位置和尺度的 Haar-like 特征约有十六万多个,课件近似写为二十万。必须用快速方法计算。

6.4 积分图

定义积分图:

$$ I_{\Sigma}(x,y)

\sum_{u\leq x} \sum_{v\leq y} I(u,v). $$

它表示从左上角到 $(x,y)$ 的矩形像素和。

任意轴对齐矩形 $[x_1,x_2]\times[y_1,y_2]$ 的像素和可由四次查表得到:

$$ S

I_{\Sigma}(x_2,y_2) -I_{\Sigma}(x_1-1,y_2) -I_{\Sigma}(x_2,y_1-1) +I_{\Sigma}(x_1-1,y_1-1). $$

因此矩形和的计算复杂度与矩形面积无关,Haar 特征也可用少量加减快速获得。

6.5 AdaBoost 人脸检测

6.5.1 弱分类器

对 Haar 特征 $f(x)$:

$$ h(x;f,p,\theta)

\begin{cases} 1, & p f(x)<p\theta,\ 0, & \text{otherwise}, \end{cases} $$

其中:

  • $x$:图像窗口。
  • $f$:某个 Haar-like 特征。
  • $\theta$:阈值。
  • $p\in{-1,+1}$:极性,决定不等号方向。

对每个候选特征选择最佳 $p,\theta$,得到仅略好于随机猜测的弱分类器。

6.5.2 AdaBoost 的作用

课件示例训练数据约为 6000 张人脸和 7 万张非人脸。

AdaBoost:

  1. 初始化样本权重。
  2. 选择加权错误率最低的 Haar 弱分类器。
  3. 提高错分样本权重,降低正确样本权重。
  4. 继续选择新的弱分类器。
  5. 把多个弱分类器加权组合成强分类器。

这同时实现:

  • 从海量 Haar 特征中选出少量有判别力特征。
  • 把多个弱阈值分类器集成为强分类器。

标准 AdaBoost 直接使用样本权重;按权重重采样是可选实现,不是必须步骤。

6.5.3 级联分类器

Viola-Jones 把多个强分类器串成级联:

  • 前级使用少量简单特征,快速排除大量明显非人脸窗口。
  • 只有通过前级的候选才进入更复杂的后级。
  • 多姿态检测可训练不同姿态分支,再组成树状/级联结构。

检测时可固定检测窗口并构建图像金字塔:每轮把图像按约 $1/1.2$ 下采样,在每层滑动同一窗口;当缩放后的图像任一必要尺寸小于检测窗口时停止。等价地,也可在原图上逐步放大检测窗口,直到窗口超过图像范围。缩放方向与停止条件必须成对说明,不能写成“窗口小于最小检测尺寸”。

6.6 CNN 分类与单目标定位

图中只有一个目标时,可共享 CNN 特征,再接两个输出头:

  1. 分类头:输出类别 logits,使用交叉熵损失。
  2. 定位头:输出四个框参数,使用 L1、Smooth L1 或 IoU 类回归损失。

总损失:

$$ L

L_{cls} +\lambda L_{box}. $$

四个参数可以是 $(x_{min},y_{min},x_{max},y_{max})$,也可以是中心点和宽高 $(c_x,c_y,w,h)$。

多目标图像中目标数和位置不固定,需要候选区域或密集预测机制。

6.7 边界框表示与代码

6.7.1 两种表示

角点式:

$$ (x_1,y_1,x_2,y_2). $$

中心式:

$$ (c_x,c_y,w,h), $$

其中:

$$ c_x=\frac{x_1+x_2}{2}, \qquad c_y=\frac{y_1+y_2}{2}, $$

$$ w=x_2-x_1, \qquad h=y_2-y_1. $$

6.7.2 正确转换代码

import torch


def box_corner_to_center(boxes):
    x1, y1, x2, y2 = (
        boxes[:, 0],
        boxes[:, 1],
        boxes[:, 2],
        boxes[:, 3],
    )
    cx = (x1 + x2) / 2
    cy = (y1 + y2) / 2
    w = x2 - x1
    h = y2 - y1
    return torch.stack((cx, cy, w, h), dim=-1)


def box_center_to_corner(boxes):
    cx, cy, w, h = (
        boxes[:, 0],
        boxes[:, 1],
        boxes[:, 2],
        boxes[:, 3],
    )
    x1 = cx - w / 2
    y1 = cy - h / 2
    x2 = cx + w / 2
    y2 = cy + h / 2
    return torch.stack((x1, y1, x2, y2), dim=-1)

源代码中的 axis=-1 在 PyTorch 中可用,但统一写 dim=-1 更符合 PyTorch 接口习惯;绘图函数还漏了逗号,应修正后使用。

6.8 目标检测数据集

典型标注每个实例一行或一个对象记录:

图片标识, 类别, x_min, y_min, x_max, y_max

COCO 检测任务常用口径:

  • 80 个常用目标类别。
  • 约 33 万张图像。
  • 超过 150 万个目标实例。
  • 还包含实例分割、关键点和图像描述等标注。

具体训练/验证/测试数量应按使用的 COCO 年份和 split 说明。

6.9 锚框与框回归

6.9.1 锚框

锚框(anchor)是预设的参考框。检测器在特征图位置上生成不同:

  • 尺度。
  • 长宽比。

网络预测:

  • 锚框是否包含目标及其类别。
  • 从锚框到真实框的坐标偏移。

6.9.2 训练标记

根据锚框与真实框的 IoU:

  • 高于正阈值:正样本,匹配一个真实框。
  • 低于负阈值:背景样本。
  • 中间区域:可忽略,避免模糊监督。

密集锚框中背景远多于前景,可用:

  • 正负样本采样。
  • 难例挖掘。
  • Focal Loss。
  • 适当类别权重。

6.10 IoU

两个边界框 $A,B$ 的交并比:

$$ \operatorname{IoU}(A,B)

\frac{|A\cap B|}{|A\cup B|}. $$

  • 无重叠时为 0。
  • 完全重合时为 1。
  • 用于锚框匹配、评估和 NMS。

若交集宽或高小于等于零,交集面积为 0。实现时要注意像素闭区间和连续坐标两种约定,不能混用 +1。

6.11 非极大值抑制

同一目标常产生多个重叠预测框。标准 NMS 对每个类别分别执行:

  1. 选择当前置信度最高的框,加入输出。
  2. 计算它与其余同类框的 IoU。
  3. 删除 IoU 大于阈值 $\theta$ 的框。
  4. 重复直到没有候选框。

NMS 是“保留一个、抑制其他”,不是把框坐标直接合并。Soft-NMS 则降低重叠框分数而不是立即删除。

若不按类别执行,可能错误压制空间重叠但类别不同的目标。

6.12 R-CNN

6.12.1 流程

  1. 用 selective search 生成约 2000 个候选区域。
  2. selective search 先做图像过分割,再按颜色、纹理、大小等相似度合并相邻区域,形成多尺度 region proposals。
  3. 把每个候选区域裁剪/缩放到固定尺寸。
  4. 每个候选区域独立经过预训练 CNN 提取特征。
  5. 用类别 SVM 分类。
  6. 用线性回归修正边界框。

6.12.2 缺点

  • 每个候选框都独立经过 CNN,重复计算严重。
  • selective search 不可学习,是单独的耗时阶段。
  • 多阶段训练和磁盘特征缓存复杂。
  • 早期实现单张图像可能需要几十秒,接近课件所说的一分钟。

6.13 RoI Pooling

给定特征图上的任意大小 RoI:

  1. 把 RoI 划分成固定 $H\times W$ 个网格。
  2. 每个网格内做最大池化。
  3. 输出固定大小 $H\times W\times C$ 特征。

例如 $2\times2$ RoI Pooling 总是输出每通道 4 个值,无论原 RoI 多大。

RoI Pooling 要量化边界,可能产生坐标误差。Mask R-CNN 后来的 RoIAlign 使用双线性插值,避免粗量化。

6.14 Fast R-CNN

Fast R-CNN 的关键改进:

  1. 整张图像只经过一次 CNN,得到共享特征图。
  2. 把外部候选框映射到特征图。
  3. 对每个候选框做 RoI Pooling,得到固定长度特征。
  4. 共享全连接特征,同时预测类别和边界框偏移。
  5. 用多任务损失端到端训练检测头。

它消除了 R-CNN 对每个候选框重复卷积的问题。

重要纠错:Fast R-CNN 仍使用 selective search 等外部 proposal;课件放在 Fast R-CNN 下的“每个特征点生成 9 个 anchors”属于 Faster R-CNN 的 RPN,不是 Fast R-CNN 本身。

6.15 Faster R-CNN

6.15.1 Region Proposal Network

Faster R-CNN 用 RPN 替代外部启发式候选区域算法。

对共享特征图的每个位置,传统实现常放置:

  • 3 种尺度。
  • 3 种长宽比,例如 $1:1$、$1:2$、$2:1$。
  • 共 $3\times3=9$ 个锚框。

RPN 对每个锚框预测:

  • 前景/背景 objectness。
  • 4 个边界框偏移。

然后经 NMS 得到 proposal,送入 RoI Pooling/头部网络。

6.15.2 四类训练目标

Faster R-CNN 联合优化:

  1. RPN 前景/背景分类损失。
  2. RPN 边界框回归损失。
  3. 最终目标类别分类损失。
  4. 最终边界框回归损失。

RPN 和检测头共享主干特征,候选区域生成也可以学习,速度和精度都优于 R-CNN/Fast R-CNN 的外部候选流程。

6.15.3 两阶段检测器

Faster R-CNN 是两阶段检测器:

  1. 第一阶段生成少量候选区域。
  2. 第二阶段对候选区域精细分类和回归。

它通常强调精度;Mask R-CNN 在此基础上加入掩码分支和 RoIAlign,实现实例分割。

6.16 SSD

SSD 是单阶段检测器:

  • 在多个尺度的特征图上放置 default boxes/anchors。
  • 一次前向传播直接预测类别和框偏移。
  • 多尺度特征图负责不同大小目标。

密集默认框确实会大量重叠,需要匹配、困难负样本挖掘和 NMS,但这不是 YOLO 与 SSD 的唯一或本质差别。

6.17 YOLO

6.17.1 原始 YOLO 思想

原始 YOLO 把图像划分为 $S\times S$ 网格:

  • 目标中心落在哪个网格,该网格负责预测目标。
  • 每个网格预测 $B$ 个边界框、objectness 和类别信息。
  • 一次网络前向完成全部预测,因此速度快。

输出框数量量级为:

$$ S^2B. $$

6.17.2 课件中的错误理解

  • 网格单元互不相交,但预测边界框可以跨越网格并彼此重叠。
  • 不能说“YOLO 生成的框全部不相交,所以没有重复计算”。
  • 原始 YOLO 反而不擅长同一网格中有多个目标中心的情况,因为一个网格的类别和框容量有限。
  • 后续 YOLO 版本有锚框式和 anchor-free 等不同设计,不能用初代描述概括全部版本。

6.17.3 一阶段与两阶段

一阶段检测器 两阶段检测器
YOLO、SSD 等 Faster R-CNN 等
密集直接预测 先 proposal,再精分类/回归
通常速度更快 通常精度和小目标处理更强

具体速度/精度取决于版本、主干、输入分辨率和部署硬件,不能只按算法家族绝对判断。

6.18 易错点

  • 语义分割给像素分类,目标检测输出实例框;检测不一定先做分割。
  • 积分图只用四次查表即可求轴对齐矩形和。
  • AdaBoost 在 Viola-Jones 中既挑选 Haar 特征,也组合弱分类器;标准算法不要求重采样。
  • 分类与定位通常假设一个主要目标,多目标检测需要可变数量预测。
  • 边界框角点式与中心式不能混用;宽高应保证非负。
  • IoU 是交集面积除以并集面积,不是交集除以两框面积和。
  • 锚框可标为正、负或忽略;不能强迫每个锚框都属于某个目标或背景。
  • NMS 抑制同类重叠框,不是坐标合并,也通常不能跨类别盲目压制。
  • R-CNN 每个 proposal 独立卷积;Fast R-CNN 共享整图卷积,但仍使用外部 proposals。
  • 锚框和 RPN 属于 Faster R-CNN,不属于原始 Fast R-CNN。
  • RoI Pooling 有量化误差,RoIAlign 用插值改善定位。
  • YOLO 网格互不相交不代表预测框互不相交;现代 YOLO 也不都采用同一种锚框方案。

相关知识

6.19 本节复盘

  • 分类只给类别,定位给单目标类别和框,检测给多个实例框,分割给像素标签。
  • Viola-Jones 用 Haar 特征描述明暗差,用积分图常数时间求矩形和,用 AdaBoost 选特征,再以级联快速排除背景。
  • 目标检测常用角点式或中心式边界框,IoU 衡量两个框的重叠程度。
  • 锚框提供参考位置和尺度,网络预测类别/objectness 与坐标偏移;密集背景需要采样或损失重加权。
  • NMS 依次保留高分框并抑制高 IoU 同类框。
  • R-CNN 用 selective search 加逐 proposal CNN;Fast R-CNN 共享整图特征;Faster R-CNN 再用 RPN 学习候选区域。
  • RoI Pooling 把任意候选区域变为固定特征,RoIAlign 进一步减少坐标量化误差。
  • SSD/YOLO 直接做密集单阶段预测,速度快;Faster R-CNN 属于两阶段检测器,通常更强调精细候选处理。