1
+
2
+ # import the necessary packages
3
+ import numpy as np
4
+
5
+ # Felzenszwalb et al.
6
+ def non_max_suppression_slow (boxes , overlapThresh ):
7
+ # if there are no boxes, return an empty list
8
+ if len (boxes ) == 0 :
9
+ return []
10
+
11
+ # initialize the list of picked indexes
12
+ pick = []
13
+
14
+ # grab the coordinates of the bounding boxes
15
+ x1 = boxes [:,0 ]
16
+ y1 = boxes [:,1 ]
17
+ x2 = boxes [:,2 ]
18
+ y2 = boxes [:,3 ]
19
+
20
+ # compute the area of the bounding boxes and sort the bounding
21
+ # boxes by the bottom-right y-coordinate of the bounding box
22
+ area = (x2 - x1 + 1 ) * (y2 - y1 + 1 )
23
+ idxs = np .argsort (y2 )
24
+
25
+ # keep looping while some indexes still remain in the indexes
26
+ # list
27
+ while len (idxs ) > 0 :
28
+ # grab the last index in the indexes list, add the index
29
+ # value to the list of picked indexes, then initialize
30
+ # the suppression list (i.e. indexes that will be deleted)
31
+ # using the last index
32
+ last = len (idxs ) - 1
33
+ i = idxs [last ]
34
+ pick .append (i )
35
+ suppress = [last ]
36
+
37
+ # loop over all indexes in the indexes list
38
+ for pos in range (0 , last ):
39
+ # grab the current index
40
+ j = idxs [pos ]
41
+
42
+ # find the largest (x, y) coordinates for the start of
43
+ # the bounding box and the smallest (x, y) coordinates
44
+ # for the end of the bounding box
45
+ xx1 = max (x1 [i ], x1 [j ])
46
+ yy1 = max (y1 [i ], y1 [j ])
47
+ xx2 = min (x2 [i ], x2 [j ])
48
+ yy2 = min (y2 [i ], y2 [j ])
49
+
50
+ # compute the width and height of the bounding box
51
+ w = max (0 , xx2 - xx1 + 1 )
52
+ h = max (0 , yy2 - yy1 + 1 )
53
+
54
+ # compute the ratio of overlap between the computed
55
+ # bounding box and the bounding box in the area list
56
+ overlap = float (w * h ) / area [j ]
57
+
58
+ # if there is sufficient overlap, suppress the
59
+ # current bounding box
60
+ if overlap > overlapThresh :
61
+ suppress .append (pos )
62
+
63
+ # delete all indexes from the index list that are in the
64
+ # suppression list
65
+ idxs = np .delete (idxs , suppress )
66
+
67
+ # return only the bounding boxes that were picked
68
+ return boxes [pick ]
69
+
70
+ def non_max_suppression_fast (boxes , probs = None , overlapThresh = 0.3 ):
71
+
72
+ # if there are no boxes, return an empty list
73
+ if len (boxes ) == 0 :
74
+ return []
75
+
76
+ # if the bounding boxes are integers, convert them to floats -- this
77
+ # is important since we'll be doing a bunch of divisions
78
+ if boxes .dtype .kind == "i" :
79
+ boxes = boxes .astype ("float" )
80
+
81
+ # initialize the list of picked indexes
82
+ pick = []
83
+
84
+ # grab the coordinates of the bounding boxes
85
+ x1 = boxes [:, 0 ]
86
+ y1 = boxes [:, 1 ]
87
+ x2 = boxes [:, 2 ]
88
+ y2 = boxes [:, 3 ]
89
+
90
+ # compute the area of the bounding boxes and grab the indexes to sort
91
+ # (in the case that no probabilities are provided, simply sort on the
92
+ # bottom-left y-coordinate)
93
+ area = (x2 - x1 + 1 ) * (y2 - y1 + 1 )
94
+ idxs = y2
95
+
96
+ # if probabilities are provided, sort on them instead
97
+ if probs is not None :
98
+ idxs = probs
99
+
100
+ # sort the indexes
101
+ idxs = np .argsort (idxs )
102
+
103
+ # keep looping while some indexes still remain in the indexes list
104
+ while len (idxs ) > 0 :
105
+ # grab the last index in the indexes list and add the index value
106
+ # to the list of picked indexes
107
+ last = len (idxs ) - 1
108
+ i = idxs [last ]
109
+ pick .append (i )
110
+
111
+ # find the largest (x, y) coordinates for the start of the bounding
112
+ # box and the smallest (x, y) coordinates for the end of the bounding
113
+ # box
114
+ xx1 = np .maximum (x1 [i ], x1 [idxs [:last ]])
115
+ yy1 = np .maximum (y1 [i ], y1 [idxs [:last ]])
116
+ xx2 = np .minimum (x2 [i ], x2 [idxs [:last ]])
117
+ yy2 = np .minimum (y2 [i ], y2 [idxs [:last ]])
118
+
119
+ # compute the width and height of the bounding box
120
+ w = np .maximum (0 , xx2 - xx1 + 1 )
121
+ h = np .maximum (0 , yy2 - yy1 + 1 )
122
+
123
+ # compute the ratio of overlap
124
+ overlap = (w * h ) / area [idxs [:last ]]
125
+
126
+ # delete all indexes from the index list that have overlap greater
127
+ # than the provided overlap threshold
128
+ idxs = np .delete (idxs , np .concatenate (([last ],
129
+ np .where (overlap > overlapThresh )[0 ])))
130
+
131
+ # return only the bounding boxes that were picked
132
+ return boxes [pick ].astype ("int" )
0 commit comments