在目标检测里,区域建议(Region Proposal,也叫候选区域、候选框、RoI proposal)指的是:
在整张图像中,先找出一批"可能含有目标物体"的区域,再把这些区域送给后续网络判断"是什么类别"以及"边框该怎么微调"。
它的核心作用是:减少搜索空间。
1. 为什么需要区域建议?
目标检测要解决两个问题:
-
目标在哪里?
也就是预测边界框
bounding box。 -
目标是什么?
比如人、车、猫、狗、椅子等。
最朴素的方法是:把图像中所有可能的位置、大小、长宽比都试一遍。但这会产生海量候选框,计算量非常大。
例如一张图片里,目标可能在:
- 左上角、右下角、中心区域;
- 很大、很小、中等大小;
- 横向长框、竖向长框、接近正方形框。
如果暴力枚举,会有成千上万个甚至更多候选区域。
所以区域建议的目的就是:
用某种方法快速筛选出少量"比较可能有物体"的候选框。
这些候选框不一定准确,但应该尽量覆盖真实目标。
2. 区域建议具体是什么?
假设一张图中有一只猫和一辆车,区域建议算法可能会输出很多候选框,比如:
- 一个框大致包住猫;
- 一个框包住猫的头;
- 一个框包住车;
- 一个框包住车轮;
- 一些背景区域;
- 一些不太准确但接近目标的框。
这些框就是 region proposals。
每个区域建议通常包含:
text
(x1, y1, x2, y2)
也就是候选框左上角和右下角坐标。
有些方法还会给每个候选框一个分数:
text
objectness score
表示这个区域"像不像一个物体",但不关心它具体是什么类别。
3. 区域建议关心"有没有物体",不是"是什么物体"
这是一个很重要的点。
区域建议阶段通常只判断:
text
这个区域里是否可能有一个前景目标?
它不一定判断:
text
这是猫、狗、车,还是人?
也就是说,区域建议关注的是 objectness,即"物体性"。
例如一个区域建议网络看到一个框,可能判断:
text
这里很可能有物体,分数 0.91
但它不会在这个阶段直接说:
text
这是猫
类别判断通常交给后面的分类器完成。
4. 两阶段目标检测中的区域建议
区域建议最典型地出现在 两阶段目标检测器 中,比如:
- R-CNN
- Fast R-CNN
- Faster R-CNN
- Mask R-CNN
两阶段检测器大致流程是:
text
输入图像
↓
提取特征
↓
生成区域建议
↓
对每个候选区域分类
↓
边框回归微调
↓
输出最终检测结果
第一阶段:找可能有物体的区域。
第二阶段:判断这些区域的类别,并精修边界框。
5. 以 Faster R-CNN 为例
Faster R-CNN 里的区域建议由 RPN 生成。
RPN 的全称是:
text
Region Proposal Network
也就是区域建议网络。
它的工作方式大致是:
text
输入图像
↓
CNN 提取特征图
↓
在特征图每个位置放置多个 anchor
↓
判断每个 anchor 是否可能包含物体
↓
对 anchor 进行边框微调
↓
得到一批候选区域
6. Anchor 是什么?
在 Faster R-CNN 这类方法中,区域建议通常基于 anchor box。
Anchor 可以理解成:
预先设定好的一批参考框。
比如在特征图的每个位置,放置几个不同大小和比例的框:
text
小正方形框
大正方形框
横向长框
竖向长框
然后网络判断每个 anchor:
- 它里面有没有目标;
- 如果有,它应该怎么移动、缩放,才能更贴合真实目标。
例如某个 anchor 原本是:
text
位置稍微偏左,大小略大
网络可以预测一个偏移量,把它调整成更贴近真实物体的框。
7. RPN 会输出什么?
RPN 通常输出两类信息:
1. 前景/背景分类
也就是判断一个候选框是否可能包含物体:
text
foreground / background
或者:
text
object / not object
2. 边界框回归
也就是预测这个框应该如何调整:
text
dx, dy, dw, dh
含义大致是:
dx:中心点横向移动多少;dy:中心点纵向移动多少;dw:宽度如何缩放;dh:高度如何缩放。
最后,anchor 经过这些偏移量修正后,就变成了更准确的候选区域。
8. 区域建议数量通常很多吗?
是的,最开始会很多。
以 Faster R-CNN 为例,RPN 可能会产生上万个 anchor。然后经过筛选,保留分数较高的一部分候选框。
常见步骤包括:
- 去掉明显越界或太小的框;
- 根据 objectness score 排序;
- 使用 NMS 去掉高度重叠的框;
- 保留 Top-N 个候选区域。
训练或推理时,可能保留几百到几千个 proposal。
9. NMS 在区域建议中有什么作用?
NMS 是 Non-Maximum Suppression,中文常叫非极大值抑制。
因为区域建议阶段会产生很多高度重叠的框,比如一只猫周围可能有几十个相似框:
text
框 A:分数 0.95
框 B:分数 0.92
框 C:分数 0.89
这些框都包住同一只猫。为了避免重复,NMS 会:
- 选分数最高的框;
- 删除与它重叠度太高的其他框;
- 继续处理剩余框。
这样可以减少冗余 proposal。
10. 区域建议的评价标准是什么?
好的区域建议不一定要分类准确,因为它不负责分类。它主要看两个方面:
1. 召回率高
真实目标最好都能被某个 proposal 覆盖到。
例如图中有 10 个真实目标,区域建议至少应该给出 10 个接近它们的候选框。
如果某个真实目标在区域建议阶段就被漏掉了,后面的分类器再强也无法检测出来。
所以区域建议非常重视 recall。
2. 候选框数量少
如果 proposal 太多,后续分类和回归会很慢。
所以区域建议要在两者之间平衡:
text
尽量覆盖所有目标
同时尽量减少无用候选框
11. 区域建议和最终检测框有什么区别?
二者容易混淆。
| 项目 | 区域建议 | 最终检测框 |
|---|---|---|
| 作用 | 找可能有物体的区域 | 输出最终检测结果 |
| 是否分类 | 通常只判断前景/背景 | 判断具体类别 |
| 是否精确 | 不一定很精确 | 更精确 |
| 数量 | 通常较多 | 通常较少 |
| 例子 | "这里可能有物体" | "这里是一只猫,置信度 0.96" |
可以这样理解:
区域建议是"初筛",最终检测框是"确认结果"。
12. 传统区域建议方法
在深度学习早期,区域建议不是由神经网络生成的,而是由传统算法生成的。
典型方法包括:
Selective Search
R-CNN 和 Fast R-CNN 早期常用 Selective Search。
它会根据图像中的颜色、纹理、边缘、区域相似性,把图像分割成很多小区域,然后逐步合并,产生候选区域。
优点:
- 不需要训练;
- 能生成较合理的候选框。
缺点:
- 速度慢;
- 不能和检测网络端到端联合训练;
- 特征表达能力有限。
13. RPN 为什么重要?
Faster R-CNN 的关键改进就是引入 RPN,把区域建议也交给神经网络来做。
相比 Selective Search,RPN 的优点是:
-
速度更快
因为它共享 CNN 特征,不需要额外跑一个慢速传统算法。
-
可以端到端训练
区域建议和检测网络可以一起优化。
-
建议质量更高
网络可以学习什么样的区域更像目标。
这也是 Faster R-CNN 比 Fast R-CNN 更"Faster"的重要原因。
14. 区域建议在 Mask R-CNN 中的作用
Mask R-CNN 也是两阶段方法,它同样依赖区域建议。
流程大致是:
text
输入图像
↓
RPN 生成 proposals
↓
RoIAlign 提取每个 proposal 的特征
↓
分类分支:判断类别
↓
边框分支:精修框
↓
Mask 分支:预测实例分割掩码
这里的区域建议不仅用于目标检测,也为后续实例分割提供候选对象区域。
15. 一阶段检测器有没有区域建议?
一阶段检测器,比如:
- YOLO
- SSD
- RetinaNet
通常不显式生成 region proposals。
它们直接在特征图上预测:
text
类别 + 边界框
所以一般说:
- Faster R-CNN:两阶段,有区域建议;
- YOLO/SSD:一阶段,没有显式区域建议。
不过从思想上看,一阶段检测器中的 anchor 或预测位置也有点像"候选框",只是它们不会先单独生成 proposal,再送入第二阶段分类。
16. 一个直观类比
可以把目标检测想象成在照片里找人。
没有区域建议时:
你需要仔细检查照片中的每一个小区域,看它是不是人、车、猫、狗。
有区域建议时:
先有人帮你圈出几十个"看起来可能有东西"的地方,你只需要重点检查这些地方。
区域建议就像是一个"初筛助手"。
17. 总结
区域建议是目标检测中的候选目标区域,主要用于两阶段检测器。
它的核心目标是:
text
快速找出可能包含目标的区域
它通常不负责判断具体类别,而是判断区域是否像一个物体。后续检测头会对这些区域进行分类和边界框回归。
一句话概括:
区域建议就是目标检测中的"候选框初筛机制":先从整张图中找出可能有目标的区域,再让后续网络判断这些区域到底是什么以及边框是否准确。
二、它是如何做的呢?
它生成区域建议的方式有两大类:
- 传统方法:例如 Selective Search,根据颜色、纹理、边缘相似性合并区域。
- 深度学习方法:例如 Faster R-CNN 里的 RPN,用神经网络直接预测候选框。
现在主流理解区域建议,通常看 RPN:Region Proposal Network。下面重点讲它是怎么做的。
1. 整体流程
以 Faster R-CNN 为例:
text
输入图像
↓
CNN / Backbone 提取特征图
↓
RPN 在特征图上滑动
↓
每个位置生成多个 anchor
↓
判断每个 anchor 是否包含目标
↓
对 anchor 做边框修正
↓
筛选高质量候选框
↓
得到 region proposals
RPN 的本质就是:
在图像特征图上密集地放很多参考框,然后让网络判断哪些框像目标,并把它们调整得更准。
2. 第一步:提取特征图
原图先经过 CNN,例如 ResNet、VGG、ResNeXt 等 backbone。
假设输入图像是:
text
800 × 600 × 3
经过卷积网络后,得到一个更小的特征图,比如:
text
50 × 38 × 1024
这个特征图虽然尺寸变小了,但每个位置都包含原图某个区域的信息。
可以理解为:
text
原图上的一块区域
↓
对应到特征图上的一个点
RPN 不直接在原图上工作,而是在这个特征图上工作。
3. 第二步:在特征图每个位置放 anchor
RPN 会在特征图的每个位置放置多个预设框,这些框叫 anchor boxes。
比如每个位置放 9 个 anchor:
text
3 种尺度 × 3 种长宽比 = 9 个 anchor
常见长宽比:
text
1:1
1:2
2:1
常见尺度:
text
小框
中框
大框
所以在特征图某一个点上,可能会有这些参考框:
text
小正方形框
中正方形框
大正方形框
小横向框
中横向框
大横向框
小竖向框
中竖向框
大竖向框
这些 anchor 被映射回原图,就覆盖了不同位置、不同大小、不同形状的区域。
4. 第三步:RPN 对每个 anchor 做两个预测
对每个 anchor,RPN 输出两类结果。
4.1 Objectness 分数
判断这个 anchor 里面有没有目标。
它不是判断"是不是猫"或"是不是车",而是判断:
text
这里像不像一个物体?
输出可以理解为:
text
foreground score
background score
或者一个 objectness 分数:
text
这个框包含目标的概率 = 0.92
如果分数高,说明这个 anchor 可能包含某个目标。
4.2 边框回归偏移量
anchor 是预设框,位置和大小通常不够准确,所以 RPN 还会预测如何修正它。
对每个 anchor,网络会预测 4 个数:
text
dx, dy, dw, dh
含义是:
text
dx:中心点横向移动多少
dy:中心点纵向移动多少
dw:宽度缩放多少
dh:高度缩放多少
例如原始 anchor 可能是这样:
text
偏左、偏大、没有完全包住猫
RPN 会预测一组偏移量,把它调整成:
text
更贴近猫的候选框
所以区域建议不是简单地拿 anchor 当结果,而是:
text
anchor + 网络预测的偏移量 = proposal
5. RPN 的网络结构长什么样?
RPN 很轻量。它通常接在 backbone 的特征图后面。
简化结构如下:
text
共享特征图
↓
3×3 卷积
↓
两个并行分支:
├── 分类分支:判断前景 / 背景
└── 回归分支:预测边框偏移
如果每个特征点有 k 个 anchor:
分类分支输出:
text
2k 个分数
因为每个 anchor 有前景和背景两个类别。
回归分支输出:
text
4k 个数
因为每个 anchor 需要 dx, dy, dw, dh 四个偏移量。
例如 k = 9:
text
分类输出:18 个值
回归输出:36 个值
6. 它怎么知道哪些 anchor 是正样本?
训练 RPN 时,需要告诉它哪些 anchor 算"有目标",哪些算"背景"。
这通常依赖 IoU。
IoU 是预测框和真实框的重叠程度:
text
IoU = 两个框的交集面积 / 两个框的并集面积
训练时,每个 anchor 会和真实标注框,也就是 ground truth box,计算 IoU。
通常规则类似这样:
text
IoU ≥ 0.7:正样本
IoU ≤ 0.3:负样本
中间区域:忽略
比如:
text
anchor A 和真实猫框 IoU = 0.82
→ 正样本
anchor B 和所有真实框 IoU 都很低,比如 0.12
→ 负样本
anchor C 的 IoU = 0.45
→ 通常忽略,不参与训练
正样本训练 RPN 学会:
text
这个区域有目标,并且应该如何调整边框
负样本训练 RPN 学会:
text
这个区域是背景,不要作为候选目标
7. RPN 的损失函数
RPN 训练时同时优化两个目标:
7.1 分类损失
让网络学会判断 anchor 是前景还是背景。
text
object / not object
可以理解为二分类损失。
7.2 回归损失
让网络学会把 anchor 调整到更接近真实框。
text
anchor → ground truth box
只对正样本 anchor 计算边框回归损失,因为背景框没有对应的真实目标。
总体损失可以理解为:
text
RPN Loss = 分类损失 + 边框回归损失
也就是说,RPN 同时学习:
text
哪里有目标
目标框应该怎么修正
8. 推理阶段是怎么生成 proposals 的?
训练好之后,给一张新图像,RPN 会这样工作。
第一步:生成大量 anchor
假设特征图大小是:
text
50 × 38
每个位置 9 个 anchor,那么总 anchor 数量是:
text
50 × 38 × 9 = 17100
这意味着一开始会有一万多个候选参考框。
第二步:预测 objectness 和偏移量
RPN 对每个 anchor 输出:
text
objectness score
dx, dy, dw, dh
然后根据偏移量把 anchor 修正成 proposal。
第三步:删除不合理框
例如:
text
超出图像边界的框
太小的框
形状异常的框
这些会先被过滤掉。
第四步:按 objectness 分数排序
把所有 proposal 按"像不像目标"排序:
text
proposal 1:0.98
proposal 2:0.95
proposal 3:0.92
...
通常只保留前几千个。
第五步:NMS 去重
因为同一个物体周围会有很多相似框,所以要用 NMS 去掉重复框。
例如一只猫周围有 20 个框,它们都很接近:
text
A:0.96
B:0.94
C:0.91
D:0.88
NMS 会保留分数最高的 A,然后删除和 A 高度重叠的 B、C、D。
第六步:保留 Top-N
最后保留固定数量的 proposal,比如:
text
训练时保留 2000 个
测试时保留 300 个
这些 proposal 会送到后面的检测头,做具体类别分类和更精细的边框回归。
9. 一个具体例子
假设图中有一只狗。
RPN 在特征图上某个位置放了 9 个 anchor:
text
anchor 1:太小,只框住狗头
anchor 2:大小合适,但偏左
anchor 3:太大,包含很多背景
anchor 4:形状不匹配
...
网络预测后可能得到:
text
anchor 1:objectness 0.60
anchor 2:objectness 0.95
anchor 3:objectness 0.72
anchor 4:objectness 0.18
其中 anchor 2 分数最高,而且网络还预测:
text
向右移动一点
高度增加一点
宽度减少一点
于是 anchor 2 被修正成一个更准确的 proposal:
text
大致包住整只狗
后面的检测网络再判断:
text
这是狗,置信度 0.97
并进一步微调边框。
10. RPN 为什么快?
RPN 快的关键是:共享特征图。
早期 R-CNN 用 Selective Search 先在原图上生成候选框,然后每个候选框都要单独提特征,速度很慢。
Faster R-CNN 的做法是:
text
整张图只做一次 CNN 特征提取
RPN 和检测头共用这张特征图
所以它不是对每个候选区域重新跑一遍 CNN,而是在共享特征图上快速预测候选框。
11. Selective Search 是怎么做区域建议的?
如果不是 RPN,传统方法比如 Selective Search 是这样做的:
text
图像分割成很多小区域
↓
根据颜色、纹理、大小、形状相似性
↓
不断合并相似区域
↓
每次合并后的区域外接矩形作为候选框
它的思想是:
真实物体通常由颜色、纹理相似的小区域组成,把这些小区域合并,就可能得到完整物体区域。
例如一张狗的图片:
text
狗耳朵区域
狗身体区域
狗腿区域
这些区域在颜色、纹理上可能比较相似,Selective Search 会尝试把它们逐步合并,最终得到一个框住整只狗的候选区域。
但它的问题是:
text
慢
不能端到端训练
不利用深层语义特征
所以后来的 Faster R-CNN 用 RPN 替代了它。
12. 区域建议的核心思想总结
区域建议生成可以浓缩成一句话:
先在图像上密集放置大量参考框,然后用算法或网络判断哪些框可能包含目标,并对这些框进行修正和筛选。
以 RPN 为例,它具体做了这几件事:
text
1. CNN 提取特征图
2. 每个特征点放多个 anchor
3. 对每个 anchor 判断前景 / 背景
4. 对前景 anchor 预测边框偏移
5. 根据分数排序
6. 用 NMS 去重
7. 保留高质量 proposals
最终得到的是一批这样的候选区域:
text
这里可能有物体
那里可能有物体
这个框可能包住目标
那个框也可能包住目标
后面的检测头再负责判断:
text
这个物体具体是什么类别
最终边框应该在哪里