一文看懂目标检测之RCNN(NMS和Soft-NMS算法)

目标检测之RCNN

1. RCNN:Regions with CNN features[2014 Ross]

RCNN.md.png

  1. 图片输入
  2. 区域建议(region proposal)
  3. 特征提取(feature extraction)
  4. 分类+2次定位(classification(SVM) + detection(线性模型Linear 正则化项))

2. 区域建议

  • 算法:selective search前景分割,将纹理、形状、颜色相似的合在一起,目前比较少人用,数学公式复杂,难用,效果还不太好,不建议看
  • 大概2K多个候选框,包括很多感兴趣尽可能囊括到候选框,粗筛
  • 2k个候选框的图片,每个做resize到固定大小,固定大小里有无物体,进入分类网络判断

selective-search.md.png

3. 特征提取

feature-extration.png

  • a.在数据集ILSVRC2012 dataset上预训练好的分类网络(AlexNet)直接拿来用,将大约2k个图片一个个送到分类网络(backbone),只拿了特征提取层,扔掉了最后的1*1000的分类层。
  • b.在真实数据集上finetune微调,主要更新后两层全连接dense层
  • c.训练样本正样本和负样本比例为1:3
  • c.IOU小于0.5,给定比较宽松的限制条件,对应较为复杂的网络,样本才不会显得过于少
  • 提取CNN特征前必须resize到统一大小,因为后面有FC层,参数是固定的
  • 问题:resize后改变了图片本身信息——长方形的旗杆resize压缩成成正方形后,他还是旗杆吗?这个仍然需要改善

4. SVM分类器分类 + NMS算法筛选 + 边界框回归(BBox Regression)

4.1. SVM分类(少样本模型)

  • 给每个样本做分类
  • 正样本:Groud True
  • 负样本:IOU < 0.3[others ignored]
  • Q:和AlexNet网络训练相比,svm分类时IOU的阈值threshould为什么不一样?A:训练CNN需要更多数据样本,更多数据样本不一定质量高,svm分类时需要质量高数据样本
  • Q:为什么用SVM,为什么不直接用AlexNet最后的softmax?A:AlexNet专注于分类, 不好用少数样本来做定位。数据多,质量差;数据少,质量高,数据少时用SVM相对好一些

4.2. NMS(Non-Maximum Suppression)非极大值抑制算法(很重要)

NMS广泛应用于目标检测算法中。其目的是为了消除多余的候选框,找到最佳的物体检测位置。

  1. 每个类别置信程度score越高,越能说明物体在框里面
  2. 取score值最高的一个框,将其他的框和他的iou越大,越可能是同一个物体,所以去掉其他和该框iou高于某一阀值候选框
  3. 代码实现
import numpy as np

def NMS(lists, thre):
    if len(lists) == 0:
        return {}
    lists = np.array(lists)
    res = []
    #取得第i列,第0列为x1,第1列为y1...
    x1, y1, x2, y2, score = [lists[:, i] for i in range(5)]

    area = (x2 - x1 + 1) * (y2 - y1 + 1)

    # get sorted index in ascending order
    idxs = np.argsort(score)

    while len(idxs) > 0:
        last = len(idxs) - 1
        i = idxs[last]
        res.append(i)

        xmin = np.maximum(x1[i], x1[idxs[:last]])
        ymin = np.maximum(y1[i], y1[idxs[:last]])
        xmax = np.minimum(x2[i], x2[idxs[:last]])
        ymax = np.minimum(y2[i], y2[idxs[:last]])
        w = xmax - xmin + 1
        h = ymax - ymin + 1
        inner_area = w * h
        # 其他所有边界框bbox和得分score最高的bbox做iou计算
        iou = inner_area / (area[i] + area[idxs[:last]] - inner_area)

        # 去除iou计算阈值大于指定值的bbox
        idxs = np.delete(idxs,
                         np.concatenate(([last],
                                         np.where(iou > thre)[0])))
                                         # here "where" will return us a tuple idxs==>[0 3]
                                         # [0] means to extract array from a tuple
    return lists[res]
    
if __name__ == '__main__':
    boxes = np.array([[1, 2, 3, 4], [1, 3, 3, 4], [1, 3, 4, 4], [1, 1, 4, 4], [1, 1, 4, 4]], dtype=np.float32)
    scores = np.array([0.4, 0.5, 0.72, 0.90, 45], dtype=np.float32)
    thre = 0.5
    
    scores1 = scores[:, np.newaxis]
    lists = np.hstack((boxes, scores1))
    
    result_boxes_scores = NMS(lists, thre)
    print(result_boxes_scores)

  1. 问题:
  • 当图片中物体比较密集的情况下,会出现新的问题
  • 下图中,两个不一样的对象,在NMS算法中可能就输出一个对象,哪个score高输出哪个,去掉另外一个;很显然,和我们两个对象都要保存输出的真实结果是违背的

    NMS_rethink.md.png

4.3. NMS发展历史/种类

1.Soft-NMS[2017]
NMS-SOFT.md.png

  • B表示原始没有经过过滤的BBox边界框,S表示每个边界框的分数score,Nt表示NMS的阈值
  • 设置一个空集D={}表示我们要用NMS筛选后输出的检测框
  • 取分数S最高的对应的边界框M,加入到集合D中,同时B集合中把边界框M去除(循环)
  • NMS:做一个遍历,所有B中的边界框和M做IOU计算,当计算结果大于某一阈值时,把B集合中对应的边界框B和分数S都删除
    • 其数学语言可以表达为:

      NMS-math-formulate.md.png
    • 如上图,相比于下图的Soft-NMS,NMS硬的地方体现在阈值高于某设定值时,score值简单粗暴地设置为0
      NMS-SOFT-formula.png
  1. IoU-Net[2018]

  2. soft-NMS[2019]

  3. NMS总结

    • 算法复杂,用cpu计算,不能用gpu加速,影响运行速度
    • 阈值的确认依赖经验,较难确认
    • soft-NMS不需要设定IOU阈值,训练时不用,测试时用提升较为明显

4.4. Bbox Regression(Bbox回归)

  1. 回归的目标,偏移量(dx,dy,dw,dh)
  2. 坐标需要归一化

5. RCNN总结

  • 慢:做了2k个区域建议,resize到固定尺寸,将固定尺寸的图输入到CNN网络中,在做分类和位置回归,每个区域建议的图都要做卷积
  • SVM和回归方法不太合适,SVM和CNN混合较为奇怪,训练较为复杂,过程较为臃肿

最后

原文链接

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值