-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathANMS.py
102 lines (91 loc) · 3.58 KB
/
ANMS.py
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import math
import numpy as np
def ssc(keypoints, num_ret_points, tolerance, cols, rows):
exp1 = rows + cols + 2 * num_ret_points
exp2 = (
4 * cols
+ 4 * num_ret_points
+ 4 * rows * num_ret_points
+ rows * rows
+ cols * cols
- 2 * rows * cols
+ 4 * rows * cols * num_ret_points
)
exp3 = math.sqrt(exp2)
exp4 = num_ret_points - 1
sol1 = -round(float(exp1 + exp3) / exp4) # first solution
sol2 = -round(float(exp1 - exp3) / exp4) # second solution
high = (
sol1 if (sol1 > sol2) else sol2
) # binary search range initialization with positive solution
low = math.floor(math.sqrt(len(keypoints) / num_ret_points))
prev_width = -1
selected_keypoints = np.empty((0, 3))
result_list = []
result = []
complete = False
k = num_ret_points
k_min = round(k - (k * tolerance))
k_max = round(k + (k * tolerance))
while not complete:
width = low + (high - low) / 2
if (
width == prev_width or low > high
): # needed to reassure the same radius is not repeated again
result_list = result # return the keypoints from the previous iteration
break
c = width / 2 # initializing Grid
num_cell_cols = int(math.floor(cols / c))
num_cell_rows = int(math.floor(rows / c))
covered_vec = [
[False for _ in range(num_cell_cols + 1)] for _ in range(num_cell_rows + 1)
]
result = []
for i in range(len(keypoints)):
row = int(
math.floor(keypoints[i, 0] / c)
# math.floor(keypoints[i].pt[1] / c)
) # get position of the cell current point is located at
col = int(
math.floor(keypoints[i, 1] / c)
# math.floor(keypoints[i].pt[0] / c)
)
if not covered_vec[row][col]: # if the cell is not covered
result.append(i)
# get range which current radius is covering
row_min = int(
(row - math.floor(width / c))
if ((row - math.floor(width / c)) >= 0)
else 0
)
row_max = int(
(row + math.floor(width / c))
if ((row + math.floor(width / c)) <= num_cell_rows)
else num_cell_rows
)
col_min = int(
(col - math.floor(width / c))
if ((col - math.floor(width / c)) >= 0)
else 0
)
col_max = int(
(col + math.floor(width / c))
if ((col + math.floor(width / c)) <= num_cell_cols)
else num_cell_cols
)
for row_to_cover in range(row_min, row_max + 1):
for col_to_cover in range(col_min, col_max + 1):
if not covered_vec[row_to_cover][col_to_cover]:
# cover cells within the square bounding box with width w
covered_vec[row_to_cover][col_to_cover] = True
if k_min <= len(result) <= k_max: # solution found
result_list = result
complete = True
elif len(result) < k_min:
high = width - 1 # update binary search range
else:
low = width + 1
prev_width = width
for i in range(len(result_list)):
selected_keypoints = np.vstack((selected_keypoints, keypoints[result_list[i]]))
return selected_keypoints