| | import numpy as np |
| |
|
| |
|
| | def line_to_border(line, size): |
| | |
| | |
| | H, W = size[1], size[0] |
| | a, b, c = line[0], line[1], line[2] |
| | epsa = 1e-8 if a >= 0 else -1e-8 |
| | epsb = 1e-8 if b >= 0 else -1e-8 |
| | intersection_list = [] |
| |
|
| | y_left = -c / (b + epsb) |
| | y_right = (-c - a * (W - 1)) / (b + epsb) |
| | x_top = -c / (a + epsa) |
| | x_down = (-c - b * (H - 1)) / (a + epsa) |
| |
|
| | if y_left >= 0 and y_left <= H - 1: |
| | intersection_list.append([0, y_left]) |
| | if y_right >= 0 and y_right <= H - 1: |
| | intersection_list.append([W - 1, y_right]) |
| | if x_top >= 0 and x_top <= W - 1: |
| | intersection_list.append([x_top, 0]) |
| | if x_down >= 0 and x_down <= W - 1: |
| | intersection_list.append([x_down, H - 1]) |
| | if len(intersection_list) != 2: |
| | return None |
| | intersection_list = np.asarray(intersection_list) |
| | return intersection_list |
| |
|
| |
|
| | def find_point_in_line(end_point): |
| | x_span, y_span = ( |
| | end_point[1, 0] - end_point[0, 0], |
| | end_point[1, 1] - end_point[0, 1], |
| | ) |
| | mv = np.random.uniform() |
| | point = np.asarray([end_point[0, 0] + x_span * mv, end_point[0, 1] + y_span * mv]) |
| | return point |
| |
|
| |
|
| | def epi_line(point, F): |
| | homo = np.concatenate([point, np.ones([len(point), 1])], axis=-1) |
| | epi = np.matmul(homo, F.T) |
| | return epi |
| |
|
| |
|
| | def dis_point_to_line(line, point): |
| | homo = np.concatenate([point, np.ones([len(point), 1])], axis=-1) |
| | dis = line * homo |
| | dis = dis.sum(axis=-1) / (np.linalg.norm(line[:, :2], axis=-1) + 1e-8) |
| | return abs(dis) |
| |
|
| |
|
| | def SGD_oneiter(F1, F2, size1, size2): |
| | H1, W1 = size1[1], size1[0] |
| | factor1 = 1 / np.linalg.norm(size1) |
| | factor2 = 1 / np.linalg.norm(size2) |
| | p0 = np.asarray([(W1 - 1) * np.random.uniform(), (H1 - 1) * np.random.uniform()]) |
| | epi1 = epi_line(p0[np.newaxis], F1)[0] |
| | border_point1 = line_to_border(epi1, size2) |
| | if border_point1 is None: |
| | return -1 |
| |
|
| | p1 = find_point_in_line(border_point1) |
| | epi2 = epi_line(p0[np.newaxis], F2) |
| | d1 = dis_point_to_line(epi2, p1[np.newaxis])[0] * factor2 |
| | epi3 = epi_line(p1[np.newaxis], F2.T) |
| | d2 = dis_point_to_line(epi3, p0[np.newaxis])[0] * factor1 |
| | return (d1 + d2) / 2 |
| |
|
| |
|
| | def compute_SGD(F1, F2, size1, size2): |
| | np.random.seed(1234) |
| | N = 1000 |
| | max_iter = N * 10 |
| | count, sgd = 0, 0 |
| | for i in range(max_iter): |
| | d1 = SGD_oneiter(F1, F2, size1, size2) |
| | if d1 < 0: |
| | continue |
| | d2 = SGD_oneiter(F2, F1, size1, size2) |
| | if d2 < 0: |
| | continue |
| | count += 1 |
| | sgd += (d1 + d2) / 2 |
| | if count == N: |
| | break |
| | if count == 0: |
| | return 1 |
| | else: |
| | return sgd / count |
| |
|
| |
|
| | def compute_inlier_rate(x1, x2, size1, size2, F_gt, th=0.003): |
| | t1, t2 = np.linalg.norm(size1) * th, np.linalg.norm(size2) * th |
| | epi1, epi2 = epi_line(x1, F_gt), epi_line(x2, F_gt.T) |
| | dis1, dis2 = dis_point_to_line(epi1, x2), dis_point_to_line(epi2, x1) |
| | mask_inlier = np.logical_and(dis1 < t2, dis2 < t1) |
| | return mask_inlier.mean() if len(mask_inlier) != 0 else 0 |
| |
|