def filter_matches_epipolar_constraint(F, matches, thresh): """ Discards matches that are not consistent with the epipolar constraint. Args: F: fundamental matrix matches: list of pairs of 2D points, stored as a Nx4 numpy array thresh: maximum accepted distance between a point and its matched epipolar line Returns: the list of matches that satisfy the constraint. It is a sub-list of the input list. """ out = [] mask = np.zeros((len(matches), 1)) # for debug only for i in range(len(matches)): x = np.array([matches[i, 0], matches[i, 1], 1]) xx = np.array([matches[i, 2], matches[i, 3], 1]) l = np.dot(F.T, xx) ll = np.dot(F, x) d1 = evaluation.distance_point_to_line(x, l) d2 = evaluation.distance_point_to_line(xx, ll) d = max(d1, d2) if (d < thresh): out.append(matches[i, :]) mask[i] = 1 # for debug only # for debug only np.savetxt('%s/sift_F_msk' % cfg['temporary_dir'], mask, '%d') return np.array(out)
def filter_matches_epipolar_constraint(F, matches, thresh): """ Discards matches that are not consistent with the epipolar constraint. Args: F: fundamental matrix matches: list of pairs of 2D points, stored as a Nx4 numpy array thresh: maximum accepted distance between a point and its matched epipolar line Returns: the list of matches that satisfy the constraint. It is a sub-list of the input list. """ out = [] if not matches.size: return np.array(out) for i in range(len(matches)): x = np.array([matches[i, 0], matches[i, 1], 1]) xx = np.array([matches[i, 2], matches[i, 3], 1]) l = np.dot(F.T, xx) ll = np.dot(F, x) d1 = evaluation.distance_point_to_line(x, l) d2 = evaluation.distance_point_to_line(xx, ll) d = max(d1, d2) if (d < thresh): out.append(matches[i, :]) return np.array(out)
def test_infinite_distances(): x = np.array([1, 1, 0]) l = np.array([0, 1, 0]) assert_equals(evaluation.distance_point_to_line(x, l), np.finfo(float).max) x = np.array([1, 1, -7]) l = np.array([0, 0, 2.3]) assert_equals(evaluation.distance_point_to_line(x, l), np.finfo(float).max)
def test_finite_distances(): x = np.array([1, 1, 1]) l = np.array([0, 1, 0]) assert_equals(evaluation.distance_point_to_line(x, l), 1) x = np.array([-1, -1, -1]) l = np.array([0, 1, 0]) assert_equals(evaluation.distance_point_to_line(x, l), 1) x = np.array([1, 1, 1]) l = np.array([3, 2, -1]) assert_equals(evaluation.distance_point_to_line(x, l), 4 / np.sqrt(13))
def test_finite_distances(): x = np.array([1, 1, 1]) l = np.array([0, 1, 0]) assert_equals(evaluation.distance_point_to_line(x, l), 1) x = np.array([-1, -1, -1]) l = np.array([0, 1, 0]) assert_equals(evaluation.distance_point_to_line(x, l), 1) x = np.array([1, 1, 1]) l = np.array([3, 2, -1]) assert_equals(evaluation.distance_point_to_line(x, l), 4/np.sqrt(13))
def evaluation_from_estimated_F(im1, im2, rpc1, rpc2, x, y, w, h, A=None, matches=None): """ Measures the pointing error on a Pleiades' pair of images, affine approx. Args: im1, im2: paths to the two Pleiades images (usually jp2 or tif) rpc1, rpc2: two instances of the rpc_model.RPCModel class x, y, w, h: four integers defining the rectangular ROI in the first image. (x, y) is the top-left corner, and (w, h) are the dimensions of the rectangle. A (optional): 3x3 numpy array containing the pointing error correction for im2. matches (optional): Nx4 numpy array containing a list of matches to use to compute the pointing error Returns: the mean pointing error, in the direction orthogonal to the epipolar lines. This error is measured in pixels, and computed from an approximated fundamental matrix. """ if not matches: matches = sift.matches_on_rpc_roi(im1, im2, rpc1, rpc2, x, y, w, h) p1 = matches[:, 0:2] p2 = matches[:, 2:4] print '%d sift matches' % len(matches) # apply pointing correction matrix, if available if A is not None: p2 = common.points_apply_homography(A, p2) # estimate the fundamental matrix between the two views rpc_matches = rpc_utils.matches_from_rpc(rpc1, rpc2, x, y, w, h, 5) F = estimation.affine_fundamental_matrix(rpc_matches) # compute the mean displacement from epipolar lines d_sum = 0 for i in range(len(p1)): x = np.array([p1[i, 0], p1[i, 1], 1]) xx = np.array([p2[i, 0], p2[i, 1], 1]) ll = F.dot(x) #d = np.sign(xx.dot(ll)) * evaluation.distance_point_to_line(xx, ll) d = evaluation.distance_point_to_line(xx, ll) d_sum += d return d_sum / len(p1)
def filter_matches_epipolar_constraint(F, matches, thresh): """ Discards matches that are not consistent with the epipolar constraint. Args: F: fundamental matrix matches: list of pairs of 2D points, stored as a Nx4 numpy array thresh: maximum accepted distance between a point and its matched epipolar line Returns: the list of matches that satisfy the constraint. It is a sub-list of the input list. """ out = [] for match in matches: x = np.array([match[0], match[1], 1]) xx = np.array([match[2], match[3], 1]) d1 = evaluation.distance_point_to_line(x, np.dot(F.T, xx)) d2 = evaluation.distance_point_to_line(xx, np.dot(F, x)) if max(d1, d2) < thresh: out.append(match) return np.array(out)
def evaluation_from_estimated_F(im1, im2, rpc1, rpc2, x, y, w, h, A=None, matches=None): """ Measures the pointing error on a Pleiades' pair of images, affine approx. Args: im1, im2: paths to the two Pleiades images (usually jp2 or tif) rpc1, rpc2: two instances of the rpc_model.RPCModel class x, y, w, h: four integers defining the rectangular ROI in the first image. (x, y) is the top-left corner, and (w, h) are the dimensions of the rectangle. A (optional): 3x3 numpy array containing the pointing error correction for im2. matches (optional): Nx4 numpy array containing a list of matches to use to compute the pointing error Returns: the mean pointing error, in the direction orthogonal to the epipolar lines. This error is measured in pixels, and computed from an approximated fundamental matrix. """ if matches is None: matches = filtered_sift_matches_roi(im1, im2, rpc1, rpc2, x, y, w, h) p1 = matches[:, 0:2] p2 = matches[:, 2:4] print '%d sift matches' % len(matches) # apply pointing correction matrix, if available if A is not None: p2 = common.points_apply_homography(A, p2) # estimate the fundamental matrix between the two views rpc_matches = rpc_utils.matches_from_rpc(rpc1, rpc2, x, y, w, h, 5) F = estimation.affine_fundamental_matrix(rpc_matches) # compute the mean displacement from epipolar lines d_sum = 0 for i in range(len(p1)): x = np.array([p1[i, 0], p1[i, 1], 1]) xx = np.array([p2[i, 0], p2[i, 1], 1]) ll = F.dot(x) #d = np.sign(xx.dot(ll)) * evaluation.distance_point_to_line(xx, ll) d = evaluation.distance_point_to_line(xx, ll) d_sum += d return d_sum/len(p1)