R-CNN是最初深度神经网络为基础的物体检测的模型 之一,在VOC2007数据集上平均精度达到66%,后续的SPPNet、Fast R-CNN、Faster R-CNN等模型均是按照这个思路。
模型框架如下:
简要的讲一下算法流程:
使用SS算法 来寻找候选框,首先将每个像素作为一组。然后,计算每一组的纹理,并将两个最接近的组结合起来。但是为了避免单个区域吞噬其他区域,我们首先对较小的组进行分组。我们继续合并区域,直到所有区域都结合在一起。
使用SS算法在一张图片提取大约2000个候选区域,但是,这些 候选区域的长宽是不固定的。
由于传统的CNN的输入需要固定大小,所以使用Crop和Wrap来讲候选区域的尺寸统一成固定大小
将这2000个统一大小的候选区域,送入预训练的CNN网络中提取特征,并将这些特征保存到磁盘中(这些特征才是真正的要训练的数据)
假设一张图片的2000个侯选区域,那么提取出来的就是2000 x 4096这样的特征向量(R-CNN当中默认CNN层输出4096特征向量)。那么最后需要对这些特征进行分类,R-CNN选用SVM进行二分类。假设检测20个类别,那么会提供20个不同类别的SVM分类器,每个分类器都会对2000个候选区域的特征向量分别判断一次,这样得出[2000, 20]的得分矩阵,如下图所示
假设有滑动窗口A、B、C、D、E共5个候选框:
NMS代码
import numpy as np
import matplotlib.pyplot as plt
def plot_bbox(dets, c='k'):
x1 = dets[:,0]
y1 = dets[:,1]
x2 = dets[:,2]
y2 = dets[:,3]
plt.plot([x1,x2], [y1,y1], c)
plt.plot([x1,x1], [y1,y2], c)
plt.plot([x1,x2], [y2,y2], c)
plt.plot([x2,x2], [y1,y2], c)
def py_cpu_nms(dets, thresh):
"""
dets: (m, 5)
dets[0] = [x1, y1, x2, y2, score]
thresh: IOU阈值
"""
x1 = dets[:, 0]
y1 = dets[:, 1]
x2 = dets[:, 2]
y2 = dets[:, 3]
scores = dets[:, 4]
areas = (x2 - x1 + 1) * (y2 - y1 + 1)
keep = [] # 用来保存筛选出的候选框
# argsort(): 返回数组值从小到大的索引
index = scores.argsort()[::-1] # index为scores中值从大到小的索引
while index.size>0:
i = index[0] # 每次循环中剩余bbox得分最大值的索引
keep.append(i)
# 重叠区域的坐标
x11 = np.maximum(x1[i], x1[index[1:]])
y11 = np.maximum(y1[i], y1[index[1:]])
x22 = np.minimum(x2[i], x2[index[1:]])
y22 = np.minimum(y2[i], y2[index[1:]])
# 重叠区域的宽高
w = np.maximum(0, x22-x11+1)
h = np.maximum(0, y22-y11+1)
# 重叠区域面积
overlaps = w * h
ious = overlaps / (areas[i]+areas[index[1:]]-overlaps)
idx = np.where(ious<=thresh)[0]
index = index[idx+1]
return keep
对于SS算法得到的候选区域并非是非常准确的,所以需要对其进行修正
训练流程:正负样本准备+预训练+微调网络+训练SVM+训练边框回归
对于训练集的所有图像,使用SS算法得到候选区域,对于1张图像得到2000个候选区域,但是每个图像不是所有的候选区域都会拿去训练。通常保证正负样本比例为1:3
拿别人已经训练好的模型拿过来,比如在ImageNet数据集上已经训练好的AlexNet模型
将上一步CNN网络输出的特征向量保存下来,用于训练SVM分类器,每个类别训练一个SVM分类器
1、训练阶段多:步骤繁琐: 微调网络+训练SVM+训练边框回归器。
2、训练耗时:占用磁盘空间大:5000张图像产生几百G的特征文件。(VOC数据集的检测结果,因为SVM的存在)
3、处理速度慢: 使用GPU, VGG16模型处理一张图像需要47s。
4、图片形状变化:候选区域要经过crop/warp进行固定大小,无法保证图片不变形
参考文献:
[1] 非极大值抑制的几种实现
[2] 一文读懂目标检测:R-CNN、Fast R-CNN、Faster R-CNN、YOLO、SSD