- 滑窗(SW):其基本原理就是采用不同大小和比例(宽高比)的窗口在整张图片上以一定的步长进行滑动,然后对这些窗口对应的区域做图像分类,这样就可以实现对整张图片的检测了。
缺点:致命的缺点就是你并不知道要检测的目标大小是什么规模,所以你要设置不同大小和比例的窗口去滑动,而且还要选取合适的步长。但是这样会产生很多的子区域,并且都要经过分类器去做预测,这需要很大的计算量,所以你的分类器不能太复杂,因为要保证速度。
2.CNN:实现更高效的滑动窗口方法,网络中用卷积层代替了全连接层,一次CNN计算就可以实现窗口滑 动的所有子区域的分类预测,图片的空间位置信息的不变性,尽管卷积过程中图片大小减少,但是位置对应关系还是保存的。
缺点:固定大小与步长的窗口,定位不够准确,定位框形状固定。
3.YOLO算法:把图像划分为NXN个小区域,以小区域为单位给目标设定一个(BX5+C)个值的标签,5包括:置信度,x,y,w,h;C是要检测的目标类别。最后卷积产生形状为NXNX(BX5+C)大小的张量来拟合各个小区域的目标标签。解决了定位框大小固定的问题。
缺点:一个单元格内存在多个目标,这时候Yolo算法就只能选择其中一个来训练;Yolo各个单元格仅仅预测两个边界框,而且属于一个类别;对于小物体,Yolo的表现会不如人意。这方面的改进可以看SSD,其采用多尺度单元格。也可以看Faster R-CNN,其采用了anchor boxes。Yolo对于在物体的宽高比方面泛化率低,就是无法定位不寻常比例的物体。当然Yolo只使用NXN的网格,定位不准确也是很大的问题。
4.区域连通分析(CC):对象是一张二值化后的图像。
有两种方法:Two-Pass和Seed-Filling。Seed-Filling:
1)扫描图像,直到当前像素点B(x,y) == 1:
a、将B(x,y)作为种子(像素位置),并赋予其一个label,然后将该种子相邻的所有前景像素都压入栈中;
b、弹出栈顶像素,赋予其相同的label,然后再将与该栈顶像素相邻的所有前景像素都压入栈中;
c、重复b步骤,直到栈为空;
此时,便找到了图像B中的一个连通区域,该区域内的像素值被标记为label;
2)重复第(1)步,直到扫描结束;
扫描结束后,就可以得到图像B中所有的连通区域;
5.多尺度候选区域的方法:
R-CNN:Selective Search得到大小不以的候选区域-->针对每个候选区域做warp缩放成统一大小的候选区域-->针对每个区域做CNN提取特征,并保存到硬盘-->SVM对各个候选区域特征做分类。
缺点:非端到端,做warp图像失真,Selective Search和对每一个候选区域做CNN导致速度慢。
Fast R-CNN:Selective Search得到大小不以的候选区域-->针对原图做CNN提取全图特征-->全图特征对候选区做映射,得到各个候选区特征-->针对大小不一的候选区做ROI Pooling(SPP Net)将候选区特征大小统一-->Linear+softmax分类+Bounding-box regression。
ROI pooling具体操作如下:
(1)根据输入image,将ROI映射到feature map对应位置;
(2)将映射后的区域划分为相同大小的sections(sections数量与输出的维度相同);
(3)对每个sections进行max pooling操作;
缺点:Selective Search仍然慢
6.YOLO的回归思想速度快但定位精度不算高,候选区方法(Region Proposal)精度高但速度不是特别快,把两者结合-->SSD,精度高VOC2007上mAP达到72.1%,在GPU上58帧每秒。
SSD算法步骤:
1. 输入一幅图片(200x200),将其输入到预训练好的分类网络中来获得不同大小的特征映射,修改了传统的VGG16网络;将VGG16的FC6和FC7层转化为卷积层,如图1上的Conv6和Conv7;去掉所有的Dropout层和FC8层;添加了Atrous算法(hole算法);将Pool5从2x2-S2变换到3x3-S1;
- 抽取Conv4_3、Conv7、Conv8_2、Conv9_2、Conv10_2、Conv11_2层的feature map,然后分别在这些feature map层上面的每一个点构造6个不同尺度大小的BB,然后分别进行检测和分类,生成多个BB,如图1所示;
3. 将不同feature map获得的BB结合起来,经过NMS(非极大值抑制)方法来抑制掉一部分重叠或者不正确的BB,生成最终的BB集合(即检测结果);
训练过程中:
1.数据增强:旋转,放大,缩小等;
Hard Negative Mining技术
一般情况下negative default boxes数量是远大于positive default boxes数量,如果随机选取样本训练会导致网络过于重视负样本(因为抽取到负样本的概率值更大一些),这会使得loss不稳定。因此需要平衡正负样本的个数,我们常用的方法就是Hard Ngative Mining,即依据confidience score对default box进行排序,挑选其中confidience高的box进行训练,将正负样本的比例控制在positive:negative=1:3,这样会取得更好的效果。如果我们不加控制的话,很可能会出现Sample到的所有样本都是负样本(即让网络从这些负样本中找正确目标,这显然是不可以的),这样就会使得网络的性能变差。匹配策略(即如何重多个default box中找到和ground truth最接近的box)
首先,寻找与每一个ground truth有最大的IoU的default box,这样就能保证ground truth至少有default box匹配;SSD之后又将剩余还没有配对的default box与任意一个ground truth尝试配对,只要两者之间的IoU大于阈值(SSD 300 阈值为0.5),就认为match;配对到ground truth的default box就是positive,没有配对的default box就是negative。
总之,一个ground truth可能对应多个positive default box,而不再像MultiBox那样只取一个IoU最大的default box。其他的作为负样本(每个default box要么是正样本box要么是负样本box)。
SSD论文贡献:
1. 引入了一种单阶段的检测器,比以前的算法YOLO更准更快,并没有使用RPN和Pooling操作;
2. 使用一个小的卷积滤波器应用在不同的feature map层从而预测BB的类别的BB偏差;
3. 可以在更小的输入图片中得到更好的检测效果(相比Faster-rcnn);
4. 在多个数据集(PASCAL、VOC、COCO、ILSVRC)上面的测试结果表明,它可以获得更高的mAp值;
Faster-rcnn与SSD比较:
如图所示,对于BB的生成,Faster-rcnn和SSD有不同的策略,但是都是为了同一个目的,产生不同尺度,不同形状的BB,用来检测物体。对于Faster-rcnn而言,其在特定层的Feature map上面的每一点生成9个预定义好的BB,然后进行回归和分类操作进行初步检测,然后进行ROI Pooling和检测获得相应的BB;而SSD则在不同的特征层的feature map上的每个点同时获取6个不同的BB(6种滑窗),然后将这些BB结合起来,最后经过NMS处理获得最后的BB。
非极大值抑制的方法是:先假设有6个矩形框,根据分类器的类别分类概率做排序,假设从小到大属于车辆的概率 分别为A、B、C、D、E、F。
(1)从最大概率矩形框F开始,分别判断A~E与F的重叠度IOU是否大于某个设定的阈值;
(2)假设B、D与F的重叠度超过阈值,那么就扔掉B、D;并标记第一个矩形框F,是我们保留下来的。
(3)从剩下的矩形框A、C、E中,选择概率最大的E,然后判断E与A、C的重叠度,重叠度大于一定的阈值,那么就扔掉;并标记E是我们保留下来的第二个矩形框。
就这样一直重复,找到所有被保留下来的矩形框。