-
NMS:常用于目标检测中,将候选框中与高分候选框重合度大于某一阈值的候选框去掉。
-
算法流程:
- 令filter_boxes为待筛选的候选框的集合,初始化为所有候选框。令chosen_boxes为已经入选的候选框集合,初始化为空。对filter_boxes根据预测概率从高到底进行排序。
- 遍历filter_boxes
- 将filter_boxes中概率最高的filter_boxes[0]放入chosen_boxes。
- 计算filter_boxes[0]与filter_boxes剩余候选框的IoU,将重合度大于阈值的框去除。为什么只计算与filter_boxes[0]的IoU呢,因此与其他已经进入chosen_boxes的候选框已经进行过筛选了。
- 调回1直到filter_boxes为空。
-
code(python)
import numpy as np
# boxes contain the coordinates and scores (x1, y1, x2, y2, score) of the boxes
def NMS(boxes, thres):
x1 = boxes[:, 0]
y1 = boxes[:, 1]
x2 = boxes[:, 2]
y2 = boxes[:, 3]
scores = boxes[:, 4]
areas = (x2-x1+1)*(y2-y1+1)
filter_idxes = scores.argsort()[::-1] #sort the indexes according to the score in descending order
chosen_idxes = [] #将chosen_boxes的下标初始化为空
while filter_idxes.size() > 0:
c_idx = filter_idxes[0]
chosen_idxes.append(c_idx)
filter_idxes = filter_idxes[1:]
interaction_x1 = np.maximum(x1[c_idx], x1[filter_idxes])
interaction_y1 = np.maximum(y1[c_idx], y1[filter_idxes])
interaction_x2 = np.minimum(x2[c_idx], x2[filter_idxes])
interaction_y2 = np.minimum(y2[c_idx], y2[filter_idxes])
w = np.maximum(0., interaction_x2-interaction_x1+1) # 当两个候选框没有交集的时候,interaction_x2-interaction_x1<0
h = np.maximum(0., interaction_y2-interaction_y1+1)
interaction = h * w
union = area[c_idx] + area[filter_idxes] - interaction
IoU = interaction / union
remain_idx = np.where(IoU <= thres)[0] #选出在filter_idxes中IoU小于阈值的下标,这个下标是filter_idxes的下标!
filter_idxes = filter_idxes[remain_idx]
return chosen_idxes