def make_mesh_2d_indiv(all_lines, corners_XYZ, O, R, g, n_points_w=None): box_XYZ = Crop.from_points(corners_XYZ[:2]).expand(0.01) if lib.debug: print('box_XYZ:', box_XYZ) if n_points_w is None: # 90th percentile line width a good guess n_points_w = 1.2 * np.percentile(np.array([line.width() for line in all_lines]), 90) mesh_XYZ_x = np.linspace(box_XYZ.x0, box_XYZ.x1, 400) mesh_XYZ_z = g(mesh_XYZ_x) mesh_XYZ_xz_arc, total_arc = arc_length_points(mesh_XYZ_x, mesh_XYZ_z, int(n_points_w)) mesh_XYZ_x_arc, _ = mesh_XYZ_xz_arc # TODO: think more about estimation of aspect ratio for mesh n_points_h = n_points_w * box_XYZ.h / total_arc # n_points_h = n_points_w * 1.7 mesh_XYZ_y = np.linspace(box_XYZ.y0, box_XYZ.y1, n_points_h) mesh_XYZ = make_mesh_XYZ(mesh_XYZ_x_arc, mesh_XYZ_y, g) mesh_2d = gcs_to_image(mesh_XYZ, O, R) if lib.debug: print('mesh:', Crop.from_points(mesh_2d)) # make sure meshes are not reversed if mesh_2d[0, :, 0].mean() > mesh_2d[0, :, -1].mean(): mesh_2d = mesh_2d[:, :, ::-1] if mesh_2d[1, 0].mean() > mesh_2d[1, -1].mean(): mesh_2d = mesh_2d[:, ::-1, :] return mesh_2d.transpose(1, 2, 0)
def make_mesh_2d(all_lines, O, R, g, n_points_w=None): all_letters = np.concatenate([line.letters for line in all_lines]) corners_2d = np.concatenate([letter.corners() for letter in all_letters]).T assert corners_2d.shape[0] == 2 and corners_2d.shape[1] == 4 * len(all_letters) corners = image_to_focal_plane(corners_2d, O) assert corners.shape[0] == 3 t0s = np.full((corners.shape[1],), np.inf, dtype=np.float64) # Get the (X,Y,Z) on the GCS surface corners_t, corners_XYZ = newton.t_i_k(R, g, corners, t0s) corners_X, _, corners_Z = corners_XYZ relative_Z_error = np.abs(g(corners_X) - corners_Z) / corners_Z # Only leave corners that are not weird # such as: |g(X) - Z| should be close, |Z| should not be extremely large, t < 0 (the GCS should be in front of the camera) corners_XYZ = corners_XYZ[:, np.logical_and(relative_Z_error <= 0.02, abs(corners_Z) < 1e6, corners_t < 0)] corners_X, _, _ = corners_XYZ debug_print_points('corners.png', corners_2d) if lib.debug: try: import matplotlib.pyplot as plt ax = plt.axes() box_XY = Crop.from_points(corners_XYZ[:2]).expand(0.01) x_min, y_min, x_max, y_max = box_XY for y in np.linspace(y_min, y_max, 3): xs = np.linspace(x_min, x_max, 200) ys = np.full(200, y) zs = g(xs) points = np.stack([xs, ys, zs]) points_r = inv(R).dot(points) + Of[:, newaxis] ax.plot(points_r[0], points_r[2]) base_xs = np.array([corners[0].min(), corners[0].max()]) base_zs = np.array([-3270.5, -3270.5]) ax.plot(base_xs, base_zs) ax.set_aspect('equal') plt.savefig('dewarp/camera.png') except Exception as e: print(e) import IPython IPython.embed() if g.split(): meshes = [ make_mesh_2d_indiv(all_lines, corners_XYZ[:, corners_X <= g.T], O, R, g, n_points_w=n_points_w), make_mesh_2d_indiv(all_lines, corners_XYZ[:, corners_X > g.T], O, R, g, n_points_w=n_points_w), ] else: meshes = [make_mesh_2d_indiv(all_lines, corners_XYZ, O, R, g, n_points_w=n_points_w)] for i, mesh in enumerate(meshes): # debug_print_points('mesh{}.png'.format(i), mesh, step=20) pass return meshes
def make_mesh_2d_indiv(all_lines, corners_XYZ, O, R, g, n_points_w=None): # Bound the text region by min and max over x, y axis and then expand the axis-aligned bounding boxes a little bit box_XYZ = Crop.from_points(corners_XYZ[:2]).expand(0.01) if lib.debug: print('box_XYZ:', box_XYZ) # n_points_w == how many discrete points for width if n_points_w is None: # 90th percentile line width a good guess n_points_w = 1.2 * np.percentile(np.array([line.width() for line in all_lines]), 90) n_points_w = max(n_points_w, 1800) mesh_XYZ_x = np.linspace(box_XYZ.x0, box_XYZ.x1, 400) mesh_XYZ_z = g(mesh_XYZ_x) # total_arc will be the true page width (computed from integration using finite difference method) mesh_XYZ_xz_arc, total_arc = arc_length_points(mesh_XYZ_x, mesh_XYZ_z, int(n_points_w)) # we actually only need x, because z can be easily computed from g (i.e. g(x) = z) mesh_XYZ_x_arc, _ = mesh_XYZ_xz_arc assert len(mesh_XYZ_x_arc) == int(n_points_w) # TODO: think more about estimation of aspect ratio for mesh # compute the discrete points for height (show follow the aspect ratio (i.e. box_XYZ.h / total_arc) n_points_h = int(n_points_w * box_XYZ.h / total_arc) # n_points_h = n_points_w * 1.7 mesh_XYZ_y = np.linspace(box_XYZ.y0, box_XYZ.y1, n_points_h) # (3, n_points_h, n_points_w) mesh_XYZ = make_mesh_XYZ(mesh_XYZ_x_arc, mesh_XYZ_y, g) assert mesh_XYZ.shape[0] == 3 # mesh_2d[:, i, j] == a coordinate (x, y) on the original image mesh_2d = gcs_to_image(mesh_XYZ, O, R) if lib.debug: print('mesh:', Crop.from_points(mesh_2d)) # make sure meshes are not reversed # (Note: I think the upside down issue is caused by rotation) # fix left-right reversed (I think it will happen why rotation axis is (0, 1, 0) and rotation degree is pi) # by making sure the first x coordinate is bigger than if mesh_2d[0, :, 0].mean() > mesh_2d[0, :, -1].mean(): mesh_2d = mesh_2d[:, :, ::-1] # fix upside down if mesh_2d[1, 0].mean() > mesh_2d[1, -1].mean(): mesh_2d = mesh_2d[:, ::-1, :] return mesh_2d.transpose(1, 2, 0) # height, width, 2(x,y)