说说soft-nms和nms那些事
前言
今天来介绍下非极大抑制。
什么是非极大抑制?
目标检测算法会输出多个检测边框,尤其是在真实目标周围会有很多置信度高的检测边框。为了去除重复的检测边框,达到每个物体有且只有一个检测结果的目的。非极大值抑制(Non-maximum suppression,NMS)是一种获取局部最大值,抑制非极大值的算法,在计算机视觉中有着广泛的应用。其核心思想是一个迭代-遍历-消除的过程,重叠率大于固定阈值的低分框会被高分框抑制。
1、首先设置IOU阈值
2、对种类进行循环,
3、对同一种类类别而言对候选框依据类别得分进行排序,选中类别得分最高的候选框,遍历其余的候选框
4、如果和当前最类别得分最高的候选框的IOU大于IOU阈值,将其剔除
5、未处理的边框中继续选一个类别得分最高的,重复2-5上述过程,直到处理完所有的边框为止。保留下来的候选框即为检测结果。
def detection_out(self, predictions, mbox_priorbox, background_label_id=0, keep_top_k=200, confidence_threshold=0.4): # 网络预测的结果 mbox_loc = predictions[0] # 置信度 mbox_conf = predictions[1] # 先验框 mbox_priorbox = mbox_priorbox results = [] # 对每一个图片进行处理 for i in range(len(mbox_loc)): decode_bbox = self.decode_boxes(mbox_loc[i], mbox_priorbox) bs_class_conf = mbox_conf[i] class_conf = np.expand_dims(np.max(bs_class_conf, 1),-1) class_pred = np.expand_dims(np.argmax(bs_class_conf, 1),-1) conf_mask = (class_conf >= confidence_threshold)[:,0] detections = np.concatenate((decode_bbox[conf_mask], class_conf[conf_mask], class_pred[conf_mask]), 1) unique_class = np.unique(detections[:,-1]) best_box = [] if len(unique_class) == 0: results.append(best_box) continue # 对种类进行循环, # 非极大抑制的作用是筛选出一定区域内属于同一种类得分最大的框, # 对种类进行循环可以帮助我们对每一个类分别进行非极大抑制。 for c in unique_class: cls_mask = detections[:,-1] == c detection = detections[cls_mask] scores = detection[:,4] # 根据得分对该种类进行从大到小排序。 arg_sort = np.argsort(scores)[::-1] detection = detection[arg_sort] while np.shape(detection)[0]>0: # 每次取出得分最大的框,计算其与其它所有预测框的重合程度,重合程度过大的则剔除。 best_box.append(detection[0]) if len(detection) == 1: break ious = iou(best_box[-1],detection[1:]) detection = detection[1:][ious<self._nms_thresh] results.append(best_box) # 获得,在所有预测结果里面,置信度比较高的框 # 还有,利用先验框和retinanet的预测结果,处理获得了真实框(预测框)的位置 return results
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
传统的非极大抑制产生的问题?
如果一个物体在另一个物体重叠区域出现,即当两个目标框接近时,分数更低的框就会因为与之重叠面积过大而被删掉,从而导致对该物体的检测失败并降低了算法的平均检测率,如下图所示,检测算法本来应该输出两个检测框,但是传统的非极大值抑制算由于绿框的得分较低且绿框和红框的IOU大于设定的阈值,因此会被过滤掉,导致只检测出一匹马,显然这样的算法设计是不合理的。
soft-nms
NMS直接粗暴的将和得分最大的box的IOU大于阈值的box的得分置零,那么有没有缓和(soft)一点的方式,这就引出了soft-nms,简言之soft-nms是用一个稍微小一点的分数替代原有的分数,而非直接粗暴的置零。
传统的非极大值抑制算法,当前检测框和最高得分检测框的IOU大于阈值时,直接将该检测框的得分置零。
其中 Si 表示当前检测框的得分, Nt为IOU的阈值,M为得分最高的检测框。
将当前检测框得分乘以一个权重函数,该函数会衰减与最高得分检测框M有重叠的相邻检测框分数,越是与M框高度重叠的检测框,其得分衰减越严重,为此我们选择高斯函数为权重函数,从而修改其删除检测框的规则。高斯权重函数如下所示:
代码对比:
传统nms:
while np.shape(detection)[0]>0: # 6、每次取出得分最大的框,计算其与其它所有预测框的重合程度,重合程度过大的则剔除。 best_box.append(detection[0]) if len(detection) == 1: break ious = iou(best_box[-1],detection[1:]) detection = detection[1:][ious<nms_thres]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
sotf-nms:
while np.shape(detection)[0]>0: best_box.append(detection[0]) if len(detection) == 1: break ious = iou(best_box[-1],detection[1:]) detection[1:,4] = np.exp(-(ious * ious) / sigma)*detection[1:,4] detection = detection[1:] scores = detection[:,4] arg_sort = np.argsort(scores)[::-1] detection = detection[arg_sort]
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
文章来源: blog.csdn.net,作者:快了的程序猿小可哥,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_35914625/article/details/108412140
- 点赞
- 收藏
- 关注作者
评论(0)