-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathssc.py
executable file
·70 lines (59 loc) · 3.02 KB
/
ssc.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
import math
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 = []
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_cols + 1)]
result = []
for i in range(len(keypoints)):
row = int(math.floor(keypoints[i].pt[1] / c)) # get position of the cell current point is located at
col = int(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 rowToCov in range(row_min, row_max + 1):
for colToCov in range(col_min, col_max + 1):
if not covered_vec[rowToCov][colToCov]:
# cover cells within the square bounding box with width w
covered_vec[rowToCov][colToCov] = 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.append(keypoints[result_list[i]])
return selected_keypoints