def approximate_rpc_as_projective(rpc_model, col_range, lin_range, alt_range, verbose=False): """ Returns a least-square approximation of the RPC functions as a projection matrix. The approximation is optimized on a sampling of the 3D region defined by the altitudes in alt_range and the image tile defined by col_range and lin_range. """ ### step 1: generate cartesian coordinates of 3d points used to fit the ### best projection matrix # get mesh points and convert them to geodetic then to geocentric # coordinates cols, lins, alts = generate_point_mesh(col_range, lin_range, alt_range) lons, lats, alts = rpc_model.direct_estimate(cols, lins, alts) x, y, z = geographiclib.geodetic_to_geocentric(lats, lons, alts) ### step 2: estimate the camera projection matrix from corresponding # 3-space and image entities world_points = np.vstack([x, y, z]).T image_points = np.vstack([cols, lins]).T P = estimation.camera_matrix(world_points, image_points) ### step 3: for debug, test the approximation error if verbose: # compute the projection error made by the computed matrix P, on the # used learning points colPROJ = np.zeros(len(x)) linPROJ = np.zeros(len(x)) for i in xrange(len(x)): v = np.dot(P, [[x[i]], [y[i]], [z[i]], [1]]) colPROJ[i] = v[0] / v[2] linPROJ[i] = v[1] / v[2] print 'approximate_rpc_as_projective: (min, max, mean)' print_distance_between_vectors(cols, colPROJ, 'cols') print_distance_between_vectors(lins, linPROJ, 'rows') return P
def inverse_estimate(self, lon, lat, alt): """ computes the projection location (col, lin) of the 3D point (lon,lat,alt), on the image. For symmetry, this function returns a triplet (col, lin, alt). The value of alt is just a copy of the one given in input. """ # convert the geodetic coordinates (lat, lon, alt) to cartesian (x, y, z) # WARNING: the convention used by CartConvert is (lat, lon, alt), while # we use (lon, lat, alt) x, y, z = geographiclib.geodetic_to_geocentric(lat, lon, alt) # project the 3D point, represented as homogeneous cartesian coordinates p0 = self.P[0, :] p1 = self.P[1, :] p2 = self.P[2, :] col = p0[0] * x + p0[1] * y + p0[2] * z + p0[3]; lin = p1[0] * x + p1[1] * y + p1[2] * z + p1[3]; n = p2[0] * x + p2[1] * y + p2[2] * z + p2[3]; # homogeneous normalization return col/n, lin/n, alt
def world_to_image_correspondences_from_rpc(rpc, x, y, w, h, n): """ Uses RPC functions to generate a set of world to image correspondences. Args: rpc: an instance of the rpc_model.RPCModel class x, y, w, h: four integers defining a rectangular region of interest (ROI) in the image. (x, y) is the top-left corner, and (w, h) are the dimensions of the rectangle. The correspondences will be located in that ROI. n: cube root of the desired number of correspondences. Returns: an array of correspondences, one per line, expressed as X, Y, Z, x, y. """ m, M = altitude_range(rpc, x, y, w, h, 100, -100) lon, lat, alt = ground_control_points(rpc, x, y, w, h, m, M, n) x, y, h = rpc.inverse_estimate(lon, lat, alt) X, Y, Z = geographiclib.geodetic_to_geocentric(lat, lon, alt) return np.vstack([X, Y, Z]).T, np.vstack([x, y]).T
def inverse_estimate(self, lon, lat, alt): """ computes the projection location (col, lin) of the 3D point (lon,lat,alt), on the image. For symmetry, this function returns a triplet (col, lin, alt). The value of alt is just a copy of the one given in input. """ # convert the geodetic coordinates (lat, lon, alt) to cartesian (x, y, z) # WARNING: the convention used by CartConvert is (lat, lon, alt), while # we use (lon, lat, alt) x, y, z = geographiclib.geodetic_to_geocentric(lat, lon, alt) # project the 3D point, represented as homogeneous cartesian coordinates p0 = self.P[0, :] p1 = self.P[1, :] p2 = self.P[2, :] col = p0[0] * x + p0[1] * y + p0[2] * z + p0[3] lin = p1[0] * x + p1[1] * y + p1[2] * z + p1[3] n = p2[0] * x + p2[1] * y + p2[2] * z + p2[3] # homogeneous normalization return col / n, lin / n, alt
def approximate_rpc_as_projective(rpc_model, col_range, lin_range, alt_range, verbose=False): """ Returns a least-square approximation of the RPC functions as a projection matrix. The approximation is optimized on a sampling of the 3D region defined by the altitudes in alt_range and the image tile defined by col_range and lin_range. """ ### step 1: generate cartesian coordinates of 3d points used to fit the ### best projection matrix # get mesh points and convert them to geodetic then to geocentric # coordinates cols, lins, alts = generate_point_mesh(col_range, lin_range, alt_range) lons, lats, alts = rpc_model.direct_estimate(cols, lins, alts) x, y, z = geographiclib.geodetic_to_geocentric(lats, lons, alts) ### step 2: estimate the camera projection matrix from corresponding # 3-space and image entities world_points = np.vstack([x, y, z]).T image_points = np.vstack([cols, lins]).T P = estimation.camera_matrix(world_points, image_points) ### step 3: for debug, test the approximation error if verbose: # compute the projection error made by the computed matrix P, on the # used learning points colPROJ = np.zeros(len(x)) linPROJ = np.zeros(len(x)) for i in xrange(len(x)): v = np.dot(P, [[x[i]],[y[i]],[z[i]],[1]]) colPROJ[i] = v[0]/v[2] linPROJ[i] = v[1]/v[2] print 'approximate_rpc_as_projective: (min, max, mean)' print_distance_between_vectors(cols, colPROJ, 'cols') print_distance_between_vectors(lins, linPROJ, 'rows') return P