Spaces:
Sleeping
Sleeping
| 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 | |