SerpentineZoneSampling / grid_optim.py
dilithjay's picture
Add dependencies
760889f
import numpy as np
import math
from tqdm import tqdm
def meters_to_latitude(m_dist: float):
return 0.00001 / 1.11 * m_dist
def degrees_to_radians(angle_deg: float):
return angle_deg / 180 * math.pi
def radians_to_degrees(angle_deg: float):
return angle_deg / math.pi * 180
def plot_line(offset: tuple, start: tuple, indices: list, size: tuple):
while (start[0] < 0 or start[1] < 0) and (
start[0] < size[0] and start[1] < size[1]
):
start = (round(start[0] + offset[0]), round(start[1] + offset[1]))
cur_h = start
while cur_h[0] < size[0] and cur_h[1] < size[1]:
indices.append(cur_h)
cur_h = (round(cur_h[0] + offset[0]), round(cur_h[1] + offset[1]))
return start
def get_grid_score(
angle: float, side_len: float, seg_result: np.ndarray, threshold: float = 0.5
):
h, w = seg_result.shape
offset = (int(side_len * math.sin(angle)), int(side_len * math.cos(angle)))
s_offset_1 = (
int(side_len * math.sin(math.pi / 3 + angle)),
int(side_len * math.cos(math.pi / 3 + angle)),
)
s_offset_2 = (
int(side_len * math.sin(math.pi / 3 - angle)),
-int(side_len * math.cos(math.pi / 3 - angle)),
)
cur = (0, 0)
i = 0
indices = []
# Lower triangle
while cur[0] < h and cur[1] < w:
cur = plot_line(offset, cur, indices, (h, w))
s_offset = s_offset_1 if i % 2 else s_offset_2
cur = (round(cur[0] + s_offset[0]), round(cur[1] + s_offset[1]))
i += 1
# Upper triangle
cur = (0, 0)
for j in range(i + 3):
cur = plot_line(offset, cur, indices, (h, w))
s_offset = s_offset_1 if j % 2 else s_offset_2
cur = (round(cur[0] - s_offset[0]), round(cur[1] - s_offset[1]))
j += 1
indices = np.array(indices)
seg_result = (seg_result > threshold) * seg_result
max_score = 0
best_start = tuple()
best_indices = None
for s_1 in np.arange(0, side_len, side_len // 5):
for s_2 in np.arange(0, side_len, side_len // 5):
indices_new = indices + np.array([s_1, s_2])
indices_new = indices_new[
np.logical_and(indices_new[:, 0] < h, indices_new[:, 1] < w)
].astype(int)
result = np.zeros((h, w))
result[indices_new[:, 0], indices_new[:, 1]] = seg_result[
indices_new[:, 0], indices_new[:, 1]
]
score = result.sum()
if score > max_score:
max_score = score
best_start = (s_1, s_2)
x, y = np.where(result > threshold)
best_indices = np.array([x, y]).T
# plt.imshow(grid)
# plt.show()
# plt.imshow(result)
# plt.show()
return max_score, best_start, np.array([best_indices[:, 1], best_indices[:, 0]]).T
def get_optimal_grid(mask: np.ndarray, side_len: float, display_progress: bool = False):
angle_range = (0, degrees_to_radians(60))
angle_res = degrees_to_radians(10)
max_score = 0
max_config = tuple()
best_indices = None
for angle in tqdm(
np.arange(angle_range[0], angle_range[1], angle_res), disable=True
):
score, start, indices = get_grid_score(angle, side_len, mask, 0.8)
if score > max_score:
max_score = score
max_config = (angle, side_len, start)
best_indices = indices
return best_indices, max_config