Source code for autocnet.transformation.homography

import numpy as np
import pandas as pd

from autocnet.utils.utils import make_homogeneous

try:
    import cv2
    cv2_avail = True
except:
    cv_avail = False

[docs]def compute_error(H, x, x1): """ Give this homography, compute the planar reprojection error between points a and b. x and x1 can be n, 2 or n,3 homogeneous coordinates. If only x, y coordinates, assume that z=1, e.g. x, y, 1 for all coordiantes. Parameters ---------- x : ndarray n,2 array of x,y coordinates x1 : ndarray n,2 array of x,y coordinates Returns ------- df : dataframe With columns for x_residual, y_residual, rmse, and error contribution. The dataframe also has cumulative x, t, and total RMS statistics accessible via df.x_rms, df.y_rms, and df.total_rms, respectively. """ if x.shape[1] == 2: x = make_homogeneous(x) if x1.shape[1] == 2: x1 = make_homogeneous(x1) z = np.empty(x.shape) # ToDo: Vectorize for performance for i, j in enumerate(x): z[i] = H.dot(j) z[i] /= z[i][-1] data = np.empty((x.shape[0], 4)) data[:, 0] = x_res = x1[:, 0] - z[:, 0] data[:, 1] = y_res = x1[:, 1] - z[:, 1] if data[:,:1].all() == 0: data[:] = 0.0 total_rms = x_rms = y_rms = 0 else: data[:, 2] = rms = np.sqrt(x_res**2 + y_res**2) total_rms = np.sqrt(np.mean(x_res**2 + y_res**2)) x_rms = np.sqrt(np.mean(x_res**2)) y_rms = np.sqrt(np.mean(y_res**2)) data[:, 3] = rms / total_rms df = pd.DataFrame(data, columns=['x_residuals', 'y_residuals', 'rmse', 'error_contribution']) df.total_rms = total_rms df.x_rms = x_rms df.y_rms = y_rms return df
[docs]def compute_homography(x1, x2, method='ransac', reproj_threshold=2.0): """ Compute a planar homography given two sets of keypoints Parameters ---------- x1 : ndarray (n, 2) of coordinates from the source image x2 : ndarray (n, 2) of coordinates from the destination image method : {'ransac', 'lmeds', 'normal'} The openCV algorithm to use for outlier detection reproj_threshold : float The maximum distances in pixels a reprojected points can be from the epipolar line to be considered an inlier Returns ------- H : ndarray (3,3) homography mask : ndarray Boolean mask for those values omitted from the homography. """ if method == 'ransac': method_ = cv2.RANSAC elif method == 'lmeds': method_ = cv2.LMEDS elif method == 'normal': method_ = 0 # Normal method else: raise ValueError("Unknown outlier detection method. Choices are: 'ransac', 'lmeds', or 'normal'.") H, mask = cv2.findHomography(x1, x2, method_, reproj_threshold) if mask is not None: mask = mask.astype(bool) return H, mask