1 # coding:utf-8
2 import numpy as np
3 def py_cpu_nms(dets, thresh):
4 """Pure Python NMS baseline."""
5 # 所有图片的坐标信息
6 x1 = dets[:, 0]
7 y1 = dets[:, 1]
8 x2 = dets[:, 2]
9 y2 = dets[:, 3]
10 scores = dets[:, 4]
11
12 areas = (x2 - x1 + 1) * (y2 - y1 + 1) # 计算出所有图片的面积
13 order = scores.argsort()[::-1] # 图片评分按升序排序
14
15 keep = [] # 用来存放最后保留的图片的相应评分
16 while order.size > 0:
17 i = order[0] # i 是还未处理的图片中的最大评分
18 keep.append(i) # 保留改图片的值
19 # 矩阵操作,下面计算的是图片i分别与其余图片相交的矩形的坐标22 xx1 = np.maximum(x1[i], x1[order[1:]])
23 yy1 = np.maximum(y1[i], y1[order[1:]])
24 xx2 = np.minimum(x2[i], x2[order[1:]])
25 yy2 = np.minimum(y2[i], y2[order[1:]])
26
27 # 计算出各个相交矩形的面积
28 w = np.maximum(0.0, xx2 - xx1 + 1)
29 h = np.maximum(0.0, yy2 - yy1 + 1)
30 inter = w * h
31 # 计算重叠比例
32 ovr = inter / (areas[i] + areas[order[1:]] - inter)
33
34 # 只保留比例小于阙值的图片,然后继续处理
35 inds = np.where(ovr <= thresh)[0]
36 indsd= inds+1
37 order = order[inds + 1]
38
39 return keep
40 boxes = np.array([[100, 100, 150, 168, 0.63],[166, 70, 312, 190, 0.55],[221, 250, 389, 500, 0.79],[12, 190, 300, 399, 0.9],[28, 130, 134, 302, 0.3]])
41 thresh = 0.1
42 keep = py_cpu_nms(boxes, thresh)
43 print(keep)
# coding:utf-8
import numpy as np
def soft_nms(boxes, sigma=0.5, Nt=0.1, threshold=0.001, method=1):
N = boxes.shape[0]
pos = 0
maxscore = 0
maxpos = 0
# boxes = np.array([[100, 100, 150, 168, 0.63], [166, 70, 312, 190, 0.55], [
# 221, 250, 389, 500, 0.79], [12, 190, 300, 399, 0.9], [28, 130, 134, 302, 0.3]])
for i in range(N):
maxscore = boxes[i, 4]
maxpos = i
tx1 = boxes[i, 0]
ty1 = boxes[i, 1]
tx2 = boxes[i, 2]
ty2 = boxes[i, 3]
ts = boxes[i, 4]
pos = i + 1
# get max box
while pos < N:
if maxscore < boxes[pos, 4]:
maxscore = boxes[pos, 4]
maxpos = pos
pos = pos + 1
# add max box as a detection
boxes[i, 0] = boxes[maxpos, 0]
boxes[i, 1] = boxes[maxpos, 1]
boxes[i, 2] = boxes[maxpos, 2]
boxes[i, 3] = boxes[maxpos, 3]
boxes[i, 4] = boxes[maxpos, 4]
# swap ith box with position of max box
boxes[maxpos, 0] = tx1
boxes[maxpos, 1] = ty1
boxes[maxpos, 2] = tx2
boxes[maxpos, 3] = ty2
boxes[maxpos, 4] = ts
tx1 = boxes[i, 0]
ty1 = boxes[i, 1]
tx2 = boxes[i, 2]
ty2 = boxes[i, 3]
ts = boxes[i, 4]
pos = i + 1
# NMS iterations, note that N changes if detection boxes fall below threshold
while pos < N:
x1 = boxes[pos, 0]
y1 = boxes[pos, 1]
x2 = boxes[pos, 2]
y2 = boxes[pos, 3]
s = boxes[pos, 4]
area = (x2 - x1 + 1) * (y2 - y1 + 1)
iw = (min(tx2, x2) - max(tx1, x1) + 1)
if iw > 0:
ih = (min(ty2, y2) - max(ty1, y1) + 1)
if ih > 0:
ua = float((tx2 - tx1 + 1) *
(ty2 - ty1 + 1) + area - iw * ih)
ov = iw * ih / ua # iou between max box and detection box
if method == 1: # linear
if ov > Nt:
weight = 1 - ov
else:
weight = 1
elif method == 2: # gaussian
weight = np.exp(-(ov * ov)/sigma)
else: # original NMS
if ov > Nt:
weight = 0
else:
weight = 1
boxes[pos, 4] = weight*boxes[pos, 4]
print(boxes[:, 4])
# if box score falls below threshold, discard the box by swapping with last box
# update N
if boxes[pos, 4] < threshold:
boxes[pos, 0] = boxes[N-1, 0]
boxes[pos, 1] = boxes[N-1, 1]
boxes[pos, 2] = boxes[N-1, 2]
boxes[pos, 3] = boxes[N-1, 3]
boxes[pos, 4] = boxes[N-1, 4]
N = N - 1
pos = pos - 1
pos = pos + 1
keep = [i for i in range(N)]
return keep
boxes = np.array([[100, 100, 150, 168, 0.63], [166, 70, 312, 190, 0.55], [
221, 250, 389, 500, 0.79], [12, 190, 300, 399, 0.9], [28, 130, 134, 302, 0.3]])
keep = soft_nms(boxes)
print(keep)