def create_submodels(self, clusters, no_symlinks=False): data = DataSet(self.data_path) for i, cluster in enumerate(clusters): # create sub model dirs submodel_path = self._submodel_path(i) submodel_images_path = self._submodel_images_path(i) io.mkdir_p(submodel_path) io.mkdir_p(submodel_images_path) # link images and create image list file image_list_path = os.path.join(submodel_path, 'image_list.txt') with io.open_wt(image_list_path) as txtfile: for image in cluster: src = data.image_files[image] dst = os.path.join(submodel_images_path, image) if not os.path.isfile(dst): os.symlink(src, dst) dst_relpath = os.path.relpath(dst, submodel_path) txtfile.write(dst_relpath + "\n") # copy config.yaml if exists config_file_path = os.path.join(self.data_path, 'config.yaml') if os.path.exists(config_file_path): shutil.copyfile(config_file_path, os.path.join(submodel_path, 'config.yaml')) if no_symlinks: reference_file_path = os.path.join(self.data_path, 'reference_lla.json') if os.path.exists(reference_file_path): shutil.copyfile(reference_file_path, os.path.join(submodel_path, 'reference_lla.json')) else: # create symlinks to metadata files for symlink_path in ['camera_models.json', 'reference_lla.json', 'exif', 'features', 'matches']: self._create_symlink(submodel_path, symlink_path)
def main(): args = parse_args() logging.basicConfig( format="%(asctime)s %(levelname)s %(name)s: %(message)s", level=logging.DEBUG) data = dataset.DataSetBase(args.dataset) reconstruction = data.load_reconstruction()[0] gcps = data.load_ground_control_points() with io.open_wt(data.data_path + '/gcp.ply') as fout: fout.write(gcp_to_ply(gcps)) for gcp in gcps: for i, observation in enumerate(gcp.observations): image = data.load_image(observation.shot_id) shot = reconstruction.shots[observation.shot_id] reprojected = shot.project(gcp.coordinates) annotated = observation.shot_coordinates rpixel = pix_coords(reprojected, image) apixel = pix_coords(annotated, image) n = (len(gcp.observations) + 3) / 4 plt.subplot(n, 4, i + 1) plt.imshow(image) plt.scatter(rpixel[0], rpixel[1]) plt.scatter(apixel[0], apixel[1]) plt.show()
def create_submodels(self, clusters): data = DataSet(self.data_path) for i, cluster in enumerate(clusters): # create sub model dirs submodel_path = self._submodel_path(i) submodel_images_path = self._submodel_images_path(i) io.mkdir_p(submodel_path) io.mkdir_p(submodel_images_path) # create image list file image_list_path = os.path.join(submodel_path, 'image_list.txt') with io.open_wt(image_list_path) as txtfile: for image in cluster: src = data.image_files[image] dst = os.path.join(submodel_images_path, image) src_relpath = os.path.relpath(src, submodel_images_path) if not os.path.isfile(dst): os.symlink(src_relpath, dst) dst_relpath = os.path.relpath(dst, submodel_path) txtfile.write(dst_relpath + "\n") # copy config.yaml if exists config_file_path = os.path.join(self.data_path, 'config.yaml') if os.path.exists(config_file_path): shutil.copyfile(config_file_path, os.path.join(submodel_path, 'config.yaml')) # create symlinks to additional files filenames = ['camera_models.json', 'reference_lla.json', 'exif', 'features', 'matches', 'masks', 'mask_list.txt', 'segmentations'] for filename in filenames: self._create_symlink(submodel_path, filename)
def export_points_reconstruction(data, path, images_map, binary=False): reconstructions = data.load_reconstruction() tracks_manager = data.load_tracks_manager() points_map = {} if binary: fout = open(os.path.join(path, "points3D.bin"), "wb") n_points = 0 for reconstruction in reconstructions: n_points += len(reconstruction.points) fout.write(pack("<Q", n_points)) else: fout = io.open_wt(os.path.join(path, "points3D.txt")) i = 0 for reconstruction in reconstructions: for point in reconstruction.points.values(): c = point.coordinates cl = point.color format_line = "%d %f %f %f %d %d %d %f " format_tuple = [ int(i), c[0], c[1], c[2], int(cl[0]), int(cl[1]), int(cl[2]), 0.0, ] if binary: fout.write(pack("<Q", int(i))) fout.write(pack("<3d", c[0], c[1], c[2])) # Position fout.write(pack("<3B", *[int(i) for i in cl])) # Color fout.write(pack("<d", 0.0)) # Error track_tuple = [] for image, obs in tracks_manager.get_track_observations( point.id).items(): if image not in reconstruction.shots: continue format_line += "%d %d " track_tuple += [images_map[image], obs.id] format_line += "\n" if binary: fout.write(pack("<Q", len(track_tuple) // 2)) # Track length for el in track_tuple: fout.write(pack("<i", el)) # Track else: fout.write(format_line % tuple(format_tuple + track_tuple)) points_map[point.id] = i i += 1 fout.close() return points_map
def save_ply(self, reconstruction, filename=None, no_cameras=False, no_points=False): """Save a reconstruction in PLY format.""" ply = io.reconstruction_to_ply(reconstruction, no_cameras, no_points) with io.open_wt(self._ply_file(filename)) as fout: fout.write(ply)
def clean_depthmap(arguments): """Clean depthmap by checking consistency with neighbors.""" log.setup() data, neighbors, shot, file_pathx, self_compute, self_path = arguments if data.clean_depthmap_exists(shot.id): logger.info("Using precomputed clean depthmap {}".format(shot.id)) return logger.info("Cleaning depthmap for image {}".format(shot.id)) dc = csfm.DepthmapCleaner() dc.set_same_depth_threshold(data.config['depthmap_same_depth_threshold']) dc.set_min_consistent_views(data.config['depthmap_min_consistent_views']) add_views_to_depth_cleaner(data, neighbors, dc, self_compute) depth = dc.clean() # Save and display results get_raw = None if self_compute: udata = opensfm_interface.UndistortedDataSet(data.path, data.config, 'undistorted') get_raw = udata.load_raw_depthmap(shot.id) else: get_raw = data.load_raw_depthmap(shot.id) print('here in for data load get raw depth map') raw_depth, raw_plane, raw_score, raw_nghbr, nghbrs = get_raw #raw_depth, raw_plane, raw_score, raw_nghbr, nghbrs = data.load_raw_depthmap(shot.id) data.save_clean_depthmap(shot.id, depth, raw_plane, raw_score) if data.config['depthmap_save_debug_files']: image = data.load_undistorted_image(shot.id) image = scale_down_image(image, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, image) with io.open_wt(data._depthmap_file(shot.id, 'clean.npz.ply')) as fout: fout.write(ply) if data.config.get('interactive'): import matplotlib.pyplot as plt plt.figure() plt.suptitle("Shot: " + shot.id) plt.subplot(2, 2, 1) plt.imshow(raw_depth) plt.colorbar() plt.subplot(2, 2, 2) plt.imshow(depth) plt.colorbar() plt.show()
def merge_depthmaps_from_provider(data, shot_ids, depthmap_provider, output): """Merge depthmaps into a single point cloud.""" logger.info("Merging depthmaps") if not shot_ids: logger.warning("Depthmaps contain no points. Try using more images.") return points, normals, colors, labels, detections = aggregate_depthmaps( shot_ids, depthmap_provider) with io.open_wt(output) as fp: point_cloud_to_ply(points, normals, colors, labels, detections, fp)
def save_ply( self, reconstruction, tracks_manager, filename=None, no_cameras=False, no_points=False, point_num_views=False, ): """Save a reconstruction in PLY format.""" ply = io.reconstruction_to_ply(reconstruction, tracks_manager, no_cameras, no_points, point_num_views) with io.open_wt(self._ply_file(filename)) as fout: fout.write(ply)
def save_ply( self, reconstruction: types.Reconstruction, tracks_manager: pysfm.TracksManager, filename: Optional[str] = None, no_cameras: bool = False, no_points: bool = False, point_num_views: bool = False, ): """Save a reconstruction in PLY format.""" ply = io.reconstruction_to_ply(reconstruction, tracks_manager, no_cameras, no_points, point_num_views) with io.open_wt(self._ply_file(filename)) as fout: fout.write(ply)
def create_submodels(self, clusters): data = DataSet(self.data_path) for i, cluster in enumerate(clusters): # create sub model dirs submodel_path = self._submodel_path(i) submodel_images_path = self._submodel_images_path(i) io.mkdir_p(submodel_path) io.mkdir_p(submodel_images_path) # create image list file image_list_path = os.path.join(submodel_path, "image_list.txt") with io.open_wt(image_list_path) as txtfile: for image in cluster: src = data.image_files[image] dst = os.path.join(submodel_images_path, image) if not os.path.isfile(dst): if sys.platform == 'win32': os.link(src, dst) else: os.symlink(os.path.relpath(src, submodel_images_path), dst) dst_relpath = os.path.relpath(dst, submodel_path) txtfile.write(dst_relpath + "\n") # copy config.yaml if exists config_file_path = os.path.join(self.data_path, "config.yaml") if os.path.exists(config_file_path): shutil.copyfile( config_file_path, os.path.join(submodel_path, "config.yaml") ) # Create reports folder io.mkdir_p(os.path.join(submodel_path, "reports")) # create symlinks to additional files filepaths = [ "camera_models.json", "reference_lla.json", "exif", "features", "matches", "masks", "mask_list.txt", "segmentations", os.path.join("reports", "features"), os.path.join("reports", "features.json"), os.path.join("reports", "matches.json"), ] for filepath in filepaths: self._create_symlink(submodel_path, filepath)
def _transform_dense_point_cloud(udata, transformation, output_path): """Apply a transformation to the merged point cloud.""" A, b = transformation[:3, :3], transformation[:3, 3] input_path = udata.point_cloud_file() with io.open_rt(input_path) as fin: with io.open_wt(output_path) as fout: for i, line in enumerate(fin): if i < 13: fout.write(line) else: x, y, z, nx, ny, nz, red, green, blue = line.split() x, y, z = np.dot(A, map(float, [x, y, z])) + b nx, ny, nz = np.dot(A, map(float, [nx, ny, nz])) fout.write("{} {} {} {} {} {} {} {} {}\n".format( x, y, z, nx, ny, nz, red, green, blue))
def merge_depthmaps(data, reconstruction): """Merge depthmaps into a single point cloud.""" logger.info("Merging depthmaps") shot_ids = [s for s in reconstruction.shots] if not shot_ids: logger.warning("Depthmaps contain no points. Try using more images.") return points = [] normals = [] colors = [] labels = [] detections = [] for shot_id in shot_ids: p, n, c, l, d = data.load_pruned_depthmap(shot_id) points.append(p) normals.append(n) colors.append(c) labels.append(l) detections.append(d) points = np.concatenate(points) normals = np.concatenate(normals) colors = np.concatenate(colors) labels = np.concatenate(labels) detections = np.concatenate(detections) with io.open_wt(data._depthmap_path() + '/merged.ply') as fp: point_cloud_to_ply(points, normals, colors, labels, detections, fp) print('available memory== ', memory_available()) print("current memory usage==", current_memory_usage()) ply= io.reconstruction_to_ply(data.reconstructions_as_json) with io.open_wt(data._depthmap_path() + '/SLAM.ply') as fout: fout.write(ply)
def _transform_dense_point_cloud(self, udata, transformation, output_path): """Apply a transformation to the merged point cloud.""" A, b = transformation[:3, :3], transformation[:3, 3] input_path = os.path.join(udata._depthmap_path(), 'merged.ply') with io.open_rt(input_path) as fin: with io.open_wt(output_path) as fout: for i, line in enumerate(fin): if i < 15: fout.write(line) else: x, y, z, nx, ny, nz, red, green, blue, e1, e2 = line.split( ) x, y, z = np.dot(A, list(map(float, [x, y, z]))) + b nx, ny, nz = np.dot(A, list(map(float, [nx, ny, nz]))) fout.write("{} {} {} {} {} {} {} {} {} {} {}\n".format( x, y, z, nx, ny, nz, red, green, blue, e1, e2))
def _transform_dense_point_cloud(self, data, transformation, output): """Apply a transformation to the merged point cloud.""" A, b = transformation[:3, :3], transformation[:3, 3] input_path = os.path.join(data._depthmap_path(), 'merged.ply') output_path = os.path.join(data.data_path, output) with io.open_rt(input_path) as fin: with io.open_wt(output_path) as fout: for i, line in enumerate(fin): if i < 13: fout.write(line) else: x, y, z, nx, ny, nz, red, green, blue = line.split() x, y, z = np.dot(A, map(float, [x, y, z])) + b nx, ny, nz = np.dot(A, map(float, [nx, ny, nz])) fout.write( "{} {} {} {} {} {} {} {} {}\n".format( x, y, z, nx, ny, nz, red, green, blue))
def export(self, reconstruction, graph, data): lines = ['NVM_V3', '', str(len(reconstruction.shots))] for shot in reconstruction.shots.values(): q = tf.quaternion_from_matrix(shot.pose.get_rotation_matrix()) o = shot.pose.get_origin() words = [ self.image_path(shot.id, data), shot.camera.focal * max(shot.camera.width, shot.camera.height), q[0], q[1], q[2], q[3], o[0], o[1], o[2], '0', '0', ] lines.append(' '.join(map(str, words))) lines += ['0', '', '0', '', '0'] with io.open_wt(data.data_path + '/reconstruction.nvm') as fout: fout.write('\n'.join(lines))
def merge_depthmaps(data, reconstruction): """Merge depthmaps into a single point cloud.""" logger.info("Merging depthmaps") shot_ids = [s for s in reconstruction.shots if data.pruned_depthmap_exists(s)] if not shot_ids: logger.warning("Depthmaps contain no points. Try using more images.") return points = [] normals = [] colors = [] labels = [] detections = [] for shot_id in shot_ids: p, n, c, l, d = data.load_pruned_depthmap(shot_id) # convert local coordinate to lla point_count = p.shape[0] logger.info("Adding shot:{}, point count:{} for depthmaps".format(shot_id, point_count)) if data.reference_lla_exists(): reference = data.load_reference() for i in range(point_count): x = float(p[i][0]) y = float(p[i][1]) z = float(p[i][2]) reference.to_lla(x, y, z) lat, lon, alt = [reference.lat, reference.lon, reference.alt] p[i][0] = lon p[i][1] = lat p[i][2] = alt points.append(p) normals.append(n) colors.append(c) labels.append(l) detections.append(d) logger.info("Finish Adding shot:{}".format(shot_id)) points = np.concatenate(points) normals = np.concatenate(normals) colors = np.concatenate(colors) labels = np.concatenate(labels) detections = np.concatenate(detections) with io.open_wt(data._depthmap_path() + '/merged.ply') as fp: point_cloud_to_ply(points, normals, colors, labels, detections, fp)
def compute_depthmap(arguments): """Compute depthmap for a single shot.""" log.setup() data, neighbors, min_depth, max_depth, shot = arguments method = data.config['depthmap_method'] if data.raw_depthmap_exists(shot.id): logger.info("Using precomputed raw depthmap {}".format(shot.id)) return logger.info("Computing depthmap for image {0} with {1}".format( shot.id, method)) de = csfm.DepthmapEstimator() de.set_depth_range(min_depth, max_depth, 100) de.set_patchmatch_iterations(data.config['depthmap_patchmatch_iterations']) de.set_patch_size(data.config['depthmap_patch_size']) de.set_min_patch_sd(data.config['depthmap_min_patch_sd']) add_views_to_depth_estimator(data, neighbors, de) if (method == 'BRUTE_FORCE'): depth, plane, score, nghbr = de.compute_brute_force() elif (method == 'PATCH_MATCH'): depth, plane, score, nghbr = de.compute_patch_match() elif (method == 'PATCH_MATCH_SAMPLE'): depth, plane, score, nghbr = de.compute_patch_match_sample() else: raise ValueError( 'Unknown depthmap method type ' '(must be BRUTE_FORCE, PATCH_MATCH or PATCH_MATCH_SAMPLE)') good_score = score > data.config['depthmap_min_correlation_score'] depth = depth * (depth < max_depth) * good_score # Save and display results neighbor_ids = [i.id for i in neighbors[1:]] data.save_raw_depthmap(shot.id, depth, plane, score, nghbr, neighbor_ids) if data.config['depthmap_save_debug_files']: image = data.load_undistorted_image(shot.id) image = scale_down_image(image, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, image) with io.open_wt(data._depthmap_file(shot.id, 'raw.npz.ply')) as fout: fout.write(ply)
def clean_depthmap(arguments): """Clean depthmap by checking consistency with neighbors.""" log.setup() data: UndistortedDataSet = arguments[0] neighbors = arguments[1] shot = arguments[2] if data.clean_depthmap_exists(shot.id): logger.info("Using precomputed clean depthmap {}".format(shot.id)) return logger.info("Cleaning depthmap for image {}".format(shot.id)) dc = pydense.DepthmapCleaner() dc.set_same_depth_threshold(data.config["depthmap_same_depth_threshold"]) dc.set_min_consistent_views(data.config["depthmap_min_consistent_views"]) add_views_to_depth_cleaner(data, neighbors, dc) depth = dc.clean() # Save and display results raw_depth, raw_plane, raw_score, raw_nghbr, nghbrs = data.load_raw_depthmap( shot.id) data.save_clean_depthmap(shot.id, depth, raw_plane, raw_score) if data.config["depthmap_save_debug_files"]: image = data.load_undistorted_image(shot.id) image = scale_down_image(image, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, image) with io.open_wt(data.depthmap_file(shot.id, "clean.npz.ply")) as fout: fout.write(ply) if data.config.get("interactive"): import matplotlib.pyplot as plt plt.figure() plt.suptitle("Shot: " + shot.id) plt.subplot(2, 2, 1) plt.imshow(raw_depth) plt.colorbar() plt.subplot(2, 2, 2) plt.imshow(depth) plt.colorbar() plt.show()
def main(): args = parse_args() logging.basicConfig( format="%(asctime)s %(levelname)s %(name)s: %(message)s", level=logging.DEBUG) data = dataset.DataSet(args.dataset) reconstruction = data.load_reconstruction()[0] gcps = data.load_ground_control_points() with io.open_wt(data.data_path + '/gcp.ply') as fout: fout.write(gcp_to_ply(gcps, reconstruction)) for gcp in gcps: plt.suptitle("GCP '{}'".format(gcp.id)) if gcp.lla: coordinates = reconstruction.reference.to_topocentric(*gcp.lla_vec) else: coordinates = orec.triangulate_gcp(gcp, reconstruction.shots) if coordinates is None: logger.warning( "Could not compute the 3D position of GCP '{}'".format(gcp.id)) continue for i, observation in enumerate(gcp.observations): image = data.load_image(observation.shot_id) shot = reconstruction.shots[observation.shot_id] reprojected = shot.project(coordinates.value) annotated = observation.projection rpixel = pix_coords(reprojected, image) apixel = pix_coords(annotated, image) n = (len(gcp.observations) + 3) / 4 ax = plt.subplot(n, min(len(gcp.observations), 4), i + 1) plt.imshow(image) ax.title.set_text("{}".format(observation.shot_id)) plt.scatter(rpixel[0], rpixel[1]) plt.scatter(apixel[0], apixel[1]) plt.show()
def run(self, args): data = dataset.DataSet(args.dataset) reconstructions = data.load_reconstruction() no_cameras = args.no_cameras no_points = args.no_points if reconstructions: data.save_ply(reconstructions[0], None, no_cameras, no_points) if args.depthmaps and reconstructions: for id, shot in reconstructions[0].shots.items(): rgb = data.load_undistorted_image(id) for t in ('clean', 'raw'): path_depth = data._depthmap_file(id, t + '.npz') if not os.path.exists(path_depth): continue depth = np.load(path_depth)['depth'] rgb = scale_down_image(rgb, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, rgb) with io.open_wt(data._depthmap_file(id, t + '.ply')) as fout: fout.write(ply)
def merge_depthmaps(data, graph, reconstruction, neighbors): """Merge depthmaps into a single point cloud.""" logger.info("Merging depthmaps") shot_ids = [s for s in neighbors if data.pruned_depthmap_exists(s)] points = [] normals = [] colors = [] for shot_id in shot_ids: p, n, c = data.load_pruned_depthmap(shot_id) points.append(p) normals.append(n) colors.append(c) points = np.concatenate(points) normals = np.concatenate(normals) colors = np.concatenate(colors) ply = point_cloud_to_ply(points, normals, colors) with io.open_wt(data._depthmap_path() + '/merged.ply') as fout: fout.write(ply)
def merge_depthmaps(data, graph, reconstruction, neighbors): """Merge depthmaps into a single point cloud.""" logger.info("Merging depthmaps") shot_ids = [s for s in neighbors if data.pruned_depthmap_exists(s)] points = [] normals = [] colors = [] for shot_id in shot_ids: p, n, c = data.load_pruned_depthmap(shot_id) points.append(p) normals.append(n) colors.append(c) points = np.concatenate(points) normals = np.concatenate(normals) colors = np.concatenate(colors) ply = point_cloud_to_ply(points, normals, colors) with io.open_wt(data._depthmap_path() + '/merged.ply') as fout: fout.write(ply)
def create_submodels(self, clusters, no_symlinks=False): data = DataSet(self.data_path) for i, cluster in enumerate(clusters): # create sub model dirs submodel_path = self._submodel_path(i) submodel_images_path = self._submodel_images_path(i) io.mkdir_p(submodel_path) io.mkdir_p(submodel_images_path) # link images and create image list file image_list_path = os.path.join(submodel_path, 'image_list.txt') with io.open_wt(image_list_path) as txtfile: for image in cluster: src = data.image_files[image] dst = os.path.join(submodel_images_path, image) if not os.path.isfile(dst): os.symlink(src, dst) dst_relpath = os.path.relpath(dst, submodel_path) txtfile.write(dst_relpath + "\n") # copy config.yaml if exists config_file_path = os.path.join(self.data_path, 'config.yaml') if os.path.exists(config_file_path): shutil.copyfile(config_file_path, os.path.join(submodel_path, 'config.yaml')) if no_symlinks: reference_file_path = os.path.join(self.data_path, 'reference_lla.json') if os.path.exists(reference_file_path): shutil.copyfile( reference_file_path, os.path.join(submodel_path, 'reference_lla.json')) else: # create symlinks to metadata files for symlink_path in [ 'camera_models.json', 'reference_lla.json', 'exif', 'features', 'matches' ]: self._create_symlink(submodel_path, symlink_path)
def export_shots_reconstruction(data, db, path, camera_map, images_map, features_map, points_map): reconstructions = data.load_reconstruction() tracks_manager = data.load_tracks_manager() with io.open_wt(os.path.join(path, 'images.txt')) as fout: for reconstruction in reconstructions: for shot_id, shot in reconstruction.shots.items(): colmap_camera_id = camera_map[shot.camera.id] colmap_shot_id = images_map[shot_id] t = shot.pose.translation q = angle_axis_to_quaternion(shot.pose.rotation) format_line = '%d %f %f %f %f %f %f %f %d %s\n' format_tuple = [ colmap_shot_id, q[0], q[1], q[2], q[3], t[0], t[1], t[2], colmap_camera_id, shot_id ] point_per_feat = { obs.id: k for k, obs in tracks_manager.get_shot_observations( shot_id).items() } for feature_id in range(len(features_map[shot_id])): colmap_point_id = -1 if feature_id in point_per_feat: point_id = point_per_feat[feature_id] if point_id in points_map: colmap_point_id = points_map[point_id] x, y = features_map[shot_id][feature_id] format_line += '%f %f %d ' format_tuple += [x, y, colmap_point_id] format_line += '\n' format_tuple = tuple(format_tuple) fout.write(format_line % format_tuple)
def clean_depthmap(arguments): """Clean depthmap by checking consistency with neighbors.""" log.setup() data, udata, neighbors, shot = arguments # if udata.clean_depthmap_exists(shot.id): # logger.info("Using precomputed clean depthmap {}".format(shot.id)) # return logger.info("Cleaning depthmap for image {}".format(shot.id)) dc = pydense.DepthmapCleaner() dc.set_same_depth_threshold(udata.config['depthmap_same_depth_threshold']) dc.set_min_consistent_views(udata.config['depthmap_min_consistent_views']) add_views_to_depth_cleaner(data,udata, neighbors, dc) depth = dc.clean() # Save and display results raw_depth, raw_plane, raw_score, raw_nghbr, nghbrs = data.load_raw_depthmap(shot.id) udata.save_clean_depthmap(shot.id, depth, raw_plane, raw_score) depthmap={} depthmap.update({'depth':depth}) depthmap.update({'plane':raw_plane}) depthmap.update({'score':raw_score}) data.save_clean_depthmap(shot.id, depthmap) #cleaned_depthmap.update({shot.id:depthmap}) if udata.config['depthmap_save_debug_files']: image = data.udata_image[shot.id]#load_undistorted_image(shot.id) # opencv는 BGR로 받아서 계산 image = scale_down_image(image, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, image) data.save_clean_ply(shot.id,ply) #cleaned_ply.update({shot.id:ply}) with io.open_wt(udata._depthmap_file(shot.id, 'clean.npz.ply')) as fout: fout.write(ply) print('available memory== ', memory_available()) print("current memory usage==", current_memory_usage())
def prune_depthmap(arguments): """Prune depthmap to remove redundant points.""" log.setup() data, neighbors, shot = arguments if data.pruned_depthmap_exists(shot.id): logger.info("Using precomputed pruned depthmap {}".format(shot.id)) return logger.info("Pruning depthmap for image {}".format(shot.id)) dp = csfm.DepthmapPruner() dp.set_same_depth_threshold(data.config['depthmap_same_depth_threshold']) add_views_to_depth_pruner(data, neighbors, dp) points, normals, colors, labels, detections = dp.prune() # Save and display results data.save_pruned_depthmap(shot.id, points, normals, colors, labels, detections) if data.config['depthmap_save_debug_files']: with io.open_wt(data._depthmap_file(shot.id, 'pruned.npz.ply')) as fp: point_cloud_to_ply(points, normals, colors, labels, detections, fp)
def clean_depthmap(arguments): """Clean depthmap by checking consistency with neighbors.""" log.setup() data, neighbors, shot = arguments if data.clean_depthmap_exists(shot.id): logger.info("Using precomputed clean depthmap {}".format(shot.id)) return logger.info("Cleaning depthmap for image {}".format(shot.id)) dc = csfm.DepthmapCleaner() dc.set_same_depth_threshold(data.config['depthmap_same_depth_threshold']) dc.set_min_consistent_views(data.config['depthmap_min_consistent_views']) add_views_to_depth_cleaner(data, neighbors, dc) depth = dc.clean() # Save and display results raw_depth, raw_plane, raw_score, raw_nghbr, nghbrs = data.load_raw_depthmap(shot.id) data.save_clean_depthmap(shot.id, depth, raw_plane, raw_score) if data.config['depthmap_save_debug_files']: image = data.undistorted_image_as_array(shot.id) image = scale_down_image(image, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, image) with io.open_wt(data._depthmap_file(shot.id, 'clean.npz.ply')) as fout: fout.write(ply) if data.config.get('interactive'): import matplotlib.pyplot as plt plt.figure() plt.suptitle("Shot: " + shot.id) plt.subplot(2, 2, 1) plt.imshow(raw_depth) plt.colorbar() plt.subplot(2, 2, 2) plt.imshow(depth) plt.colorbar() plt.show()
def run(self, file_path, opensfm_config, self_compute = False, self_path=''): #data = dataset.DataSet(args.dataset) reconstructions = opensfm_interface.load_reconstruction(file_path) no_cameras = True no_points = False if reconstructions: self.save_ply(file_path, reconstructions[0], None, no_cameras, no_points) if False and reconstructions: udata = opensfm_interface.UndistortedDataSet(file_path, opensfm_config, 'undistorted', self_compute, self_path) for id, shot in reconstructions[0].shots.items(): rgb = udata.load_undistorted_image(id) for t in ('clean', 'raw'): path_depth = udata._depthmap_file(id, t + '.npz') if not os.path.exists(path_depth): continue depth = np.load(path_depth)['depth'] rgb = scale_down_image(rgb, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, rgb) with io.open_wt(udata._depthmap_file(id, t + '.ply')) as fout: fout.write(ply)
def export_cameras_reconstruction(data, db, path, camera_map): reconstructions = data.load_reconstruction() with io.open_wt(os.path.join(path, 'cameras.txt')) as fout: for reconstruction in reconstructions: for camera_id, camera in reconstruction.cameras.items(): w = camera.width h = camera.height normalizer = max(w, h) colmap_id = camera_map[camera_id] colmap_type = COLMAP_TYPES_MAP[camera.projection_type] if camera.projection_type == 'perspective': f = camera.focal * normalizer k1 = camera.k1 k2 = camera.k2 fout.write('%d %s %d %d %f %f %f %f %f\n' % (colmap_id, colmap_type, w, h, f, w * 0.5, h * 0.5, k1, k2)) elif camera.projection_type == 'brown': f_x = camera.focal_x * normalizer f_y = camera.focal_y * normalizer c_x = (w - 1) * 0.5 + normalizer * camera.c_x c_y = (h - 1) * 0.5 + normalizer * camera.c_y k1 = camera.k1 k2 = camera.k2 k3 = camera.k3 p1 = camera.p1 p2 = camera.p2 fout.write( '%d %s %d %d %f %f %f %f %f %f %f %f %f %f %f %f\n' % (colmap_id, colmap_type, w, h, f_x, f_y, c_x, c_y, k1, k2, p1, p2, k3, 0.0, 0.0, 0.0)) elif camera.projection_type == 'fisheye': f = camera.focal * normalizer k1 = camera.k1 k2 = camera.k2 fout.write('%d %s %d %d %f %f %f %f %f\n' % (colmap_id, colmap_type, w, h, f, w * 0.5, h * 0.5, k1, k2))
def merge_depthmaps(data, reconstruction): """Merge depthmaps into a single point cloud.""" logger.info("Merging depthmaps") shot_ids = [s for s in reconstruction.shots if data.pruned_depthmap_exists(s)] points = [] normals = [] colors = [] labels = [] for shot_id in shot_ids: p, n, c, l = data.load_pruned_depthmap(shot_id) points.append(p) normals.append(n) colors.append(c) labels.append(l) points = np.concatenate(points) normals = np.concatenate(normals) colors = np.concatenate(colors) labels = np.concatenate(labels) with io.open_wt(data._depthmap_path() + '/merged.ply') as fp: point_cloud_to_ply(points, normals, colors, labels, fp)
def run(self, args): data = dataset.DataSet(args.dataset) reconstructions = data.load_reconstruction() no_cameras = args.no_cameras no_points = args.no_points if reconstructions: data.save_ply(reconstructions[0], None, no_cameras, no_points) if args.depthmaps and reconstructions: udata = dataset.UndistortedDataSet(data, 'undistorted') for id, shot in reconstructions[0].shots.items(): rgb = udata.load_undistorted_image(id) for t in ('clean', 'raw'): path_depth = udata._depthmap_file(id, t + '.npz') if not os.path.exists(path_depth): continue depth = np.load(path_depth)['depth'] rgb = scale_down_image(rgb, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, rgb) with io.open_wt(udata._depthmap_file(id, t + '.ply')) as fout: fout.write(ply)
def prune_depthmap(arguments): """Prune depthmap to remove redundant points.""" log.setup() data, neighbors, shot = arguments if data.pruned_depthmap_exists(shot.id): logger.info("Using precomputed pruned depthmap {}".format(shot.id)) return logger.info("Pruning depthmap for image {}".format(shot.id)) dp = csfm.DepthmapPruner() dp.set_same_depth_threshold(data.config['depthmap_same_depth_threshold']) add_views_to_depth_pruner(data, neighbors, dp) points, normals, colors = dp.prune() # Save and display results data.save_pruned_depthmap(shot.id, points, normals, colors) if data.config['depthmap_save_debug_files']: ply = point_cloud_to_ply(points, normals, colors) with io.open_wt(data._depthmap_file(shot.id, 'pruned.npz.ply')) as fout: fout.write(ply)
def run_dataset(data: DataSet, no_cameras, no_points, depthmaps, point_num_views): """Export reconstruction to PLY format Args: no_cameras: do not save camera positions no_points: do not save points depthmaps: export per-image depthmaps as pointclouds point_num_views: Export the number of views associated with each point """ reconstructions = data.load_reconstruction() tracks_manager = data.load_tracks_manager() no_cameras = no_cameras no_points = no_points point_num_views = point_num_views if reconstructions: data.save_ply(reconstructions[0], tracks_manager, None, no_cameras, no_points, point_num_views) if depthmaps: udata = dataset.UndistortedDataSet(data) urec = udata.load_undistorted_reconstruction()[0] for shot in urec.shots.values(): rgb = udata.load_undistorted_image(shot.id) for t in ("clean", "raw"): path_depth = udata.depthmap_file(shot.id, t + ".npz") if not os.path.exists(path_depth): continue depth = np.load(path_depth)["depth"] rgb = scale_down_image(rgb, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, rgb) with io.open_wt(udata.depthmap_file(shot.id, t + ".ply")) as fout: fout.write(ply)
def save_tracks_graph(self, graph, filename=None): with io.open_wt(self._tracks_graph_file(filename)) as fout: save_tracks_graph(fout, graph)
def save_ply(self, reconstruction, filename=None, no_cameras=False, no_points=False): """Save a reconstruction in PLY format.""" ply = io.reconstruction_to_ply(reconstruction, no_cameras, no_points) with io.open_wt(self._ply_file(filename)) as fout: fout.write(ply)
def save_clusters_geojson(self, geojson): filepath = self._clusters_geojson_path() with io.open_wt(filepath) as fout: io.json_dump(geojson, fout)
def save_report(self, report_str, path): """Save report string to a file.""" filepath = os.path.join(self._report_path(), path) io.mkdir_p(os.path.dirname(filepath)) with io.open_wt(filepath) as fout: return fout.write(report_str)
def save_navigation_graph(self, navigation_graphs): with io.open_wt(self._navigation_graph_file()) as fout: io.json_dump(navigation_graphs, fout)
def save_camera_models_overrides(self, camera_models): """Save camera models overrides data""" with io.open_wt(self._camera_models_overrides_file()) as fout: obj = io.cameras_to_json(camera_models) io.json_dump(obj, fout)
def create_image_list(self, ills): with io.open_wt(self._image_list_path()) as csvfile: for image, lat, lon in ills: csvfile.write(u'{}\t{}\t{}\n'.format(image, lat, lon))
def export_images_reconstruction(data, path, camera_map, images_map, features_map, points_map, binary=False): reconstructions = data.load_reconstruction() tracks_manager = data.load_tracks_manager() if binary: fout = open(os.path.join(path, 'images.bin'), 'wb') n_ims = 0 for reconstruction in reconstructions: n_ims += len(reconstruction.shots) fout.write(pack('<Q', n_ims)) else: fout = io.open_wt(os.path.join(path, 'images.txt')) for reconstruction in reconstructions: for shot_id, shot in reconstruction.shots.items(): colmap_camera_id = camera_map[shot.camera.id] colmap_shot_id = images_map[shot_id] t = shot.pose.translation q = angle_axis_to_quaternion(shot.pose.rotation) if binary: fout.write(pack('<I', colmap_shot_id)) fout.write(pack('<7d', *(list(q) + list(t)))) fout.write(pack('<I', colmap_camera_id)) for char in shot_id: fout.write(pack('<c', char.encode("utf-8"))) fout.write(pack('<c', b"\x00")) format_line = '%d %f %f %f %f %f %f %f %d %s\n' format_tuple = [ colmap_shot_id, q[0], q[1], q[2], q[3], t[0], t[1], t[2], colmap_camera_id, shot_id ] point_per_feat = { obs.id: k for k, obs in tracks_manager.get_shot_observations( shot_id).items() } points_tuple = [] for feature_id in range(len(features_map[shot_id])): colmap_point_id = -1 if feature_id in point_per_feat: point_id = point_per_feat[feature_id] if point_id in points_map: colmap_point_id = points_map[point_id] if colmap_point_id != -1: x, y = features_map[shot_id][feature_id] format_line += '%f %f %d ' points_tuple += [x, y, colmap_point_id] format_line += '\n' if binary: fout.write(pack('<Q', len(points_tuple) // 3)) for i in range(0, len(points_tuple), 3): x, y, colmap_point_id = points_tuple[i:i + 3] fout.write(pack('<2d', x, y)) fout.write(pack('<Q', colmap_point_id)) else: fout.write(format_line % tuple(format_tuple + points_tuple)) fout.close()
def _write_transformation(self, transformation, filename): """Write the 4x4 matrix transformation to a text file.""" with io.open_wt(filename) as fout: for row in transformation: fout.write(u' '.join(map(str, row))) fout.write(u'\n')
def save_reconstructions(reconstructions): with io.open_wt('reconstruction_aligned.json') as fout: io.json_dump(io.reconstructions_to_json(reconstructions), fout, False)
def compute_depthmap(arguments): """Compute depthmap for a single shot.""" log.setup() data, neighbors, min_depth, max_depth, shot = arguments method = data.config['depthmap_method'] if data.raw_depthmap_exists(shot.id): logger.info("Using precomputed raw depthmap {}".format(shot.id)) return logger.info("Computing depthmap for image {0} with {1}".format( shot.id, method)) de = csfm.DepthmapEstimator() de.set_depth_range(min_depth, max_depth, 100) de.set_patchmatch_iterations(data.config['depthmap_patchmatch_iterations']) de.set_patch_size(data.config['depthmap_patch_size']) de.set_min_patch_sd(data.config['depthmap_min_patch_sd']) add_views_to_depth_estimator(data, neighbors, de) if (method == 'BRUTE_FORCE'): depth, plane, score, nghbr = de.compute_brute_force() elif (method == 'PATCH_MATCH'): depth, plane, score, nghbr = de.compute_patch_match() elif (method == 'PATCH_MATCH_SAMPLE'): depth, plane, score, nghbr = de.compute_patch_match_sample() else: raise ValueError( 'Unknown depthmap method type ' '(must be BRUTE_FORCE, PATCH_MATCH or PATCH_MATCH_SAMPLE)') good_score = score > data.config['depthmap_min_correlation_score'] depth = depth * (depth < max_depth) * good_score # Save and display results neighbor_ids = [i.id for i in neighbors[1:]] data.save_raw_depthmap(shot.id, depth, plane, score, nghbr, neighbor_ids) #load #print('load the raw depthmap ') #data.load_raw_depthmap(shot.id) if data.config['depthmap_save_debug_files']: image = data.load_undistorted_image(shot.id) image = scale_down_image(image, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, image) with io.open_wt(data._depthmap_file(shot.id, 'raw.npz.ply')) as fout: fout.write(ply) if data.config.get('interactive'): import matplotlib.pyplot as plt plt.figure() plt.suptitle("Shot: " + shot.id + ", neighbors: " + ', '.join(neighbor_ids)) plt.subplot(2, 3, 1) plt.imshow(image) plt.subplot(2, 3, 2) plt.imshow(color_plane_normals(plane)) plt.subplot(2, 3, 3) plt.imshow(depth) plt.colorbar() plt.subplot(2, 3, 4) plt.imshow(score) plt.colorbar() plt.subplot(2, 3, 5) plt.imshow(nghbr) plt.colorbar() plt.show()
def save_reconstruction(self, reconstruction, filename=None, minify=False): with io.open_wt(self._reconstruction_file(filename)) as fout: io.json_dump(io.reconstructions_to_json(reconstruction), fout, minify)
def export_cameras_reconstruction(data, path, camera_map, binary=False): reconstructions = data.load_reconstruction() cameras = {} for reconstruction in reconstructions: for camera_id, camera in reconstruction.cameras.items(): cameras[camera_id] = camera if binary: fout = open(os.path.join(path, 'cameras.bin'), 'wb') fout.write(pack('<Q', len(cameras))) else: fout = io.open_wt(os.path.join(path, 'cameras.txt')) for camera_id, camera in cameras.items(): w = camera.width h = camera.height normalizer = max(w, h) colmap_id = camera_map[camera_id] colmap_type = COLMAP_TYPES_MAP[camera.projection_type] if camera.projection_type == 'perspective': f = camera.focal * normalizer k1 = camera.k1 k2 = camera.k2 if binary: fout.write( pack('<2i', colmap_id, COLMAP_ID_MAP[camera.projection_type])) fout.write(pack('<2Q', w, h)) fout.write(pack('<5d', f, w * 0.5, h * 0.5, k1, k2)) else: fout.write('%d %s %d %d %f %f %f %f %f\n' % (colmap_id, colmap_type, w, h, f, w * 0.5, h * 0.5, k1, k2)) elif camera.projection_type == 'brown': f_x = camera.focal_x * normalizer f_y = camera.focal_y * normalizer c_x = (w - 1) * 0.5 + normalizer * camera.c_x c_y = (h - 1) * 0.5 + normalizer * camera.c_y k1 = camera.k1 k2 = camera.k2 k3 = camera.k3 p1 = camera.p1 p2 = camera.p2 if binary: fout.write( pack('<2i', colmap_id, COLMAP_ID_MAP[camera.projection_type])) fout.write(pack('<2Q', w, h)) fout.write( pack('<12d', f_x, f_y, c_x, c_y, k1, k2, p1, p2, k3, 0.0, 0.0, 0.0)) else: fout.write( '%d %s %d %d %f %f %f %f %f %f %f %f %f %f %f %f\n' % (colmap_id, colmap_type, w, h, f_x, f_y, c_x, c_y, k1, k2, p1, p2, k3, 0.0, 0.0, 0.0)) elif camera.projection_type == 'fisheye': f = camera.focal * normalizer k1 = camera.k1 k2 = camera.k2 if binary: fout.write( pack('<2i', colmap_id, COLMAP_ID_MAP[camera.projection_type])) fout.write(pack('<2Q', w, h)) fout.write(pack('<5d', f, w * 0.5, h * 0.5, k1, k2)) else: fout.write('%d %s %d %d %f %f %f %f %f\n' % (colmap_id, colmap_type, w, h, f, w * 0.5, h * 0.5, k1, k2)) fout.close()
def save_reference_lla(self, reference): with io.open_wt(self._reference_lla_path()) as fout: io.json_dump(reference, fout)
def export_ini_file(path, db_path, images_path): with io.open_wt(os.path.join(path, 'project.ini')) as fout: fout.write('log_to_stderr=false\nlog_level=2\n') fout.write('database_path=%s\n' % db_path) fout.write('image_path=%s\n' % images_path)
def create_image_list(self, ills): with io.open_wt(self._image_list_path()) as csvfile: w = self._create_csv_writer(csvfile) for image, lat, lon in ills: w.writerow([image, lat, lon])
def save_exif(self, image, data): io.mkdir_p(self._exif_path()) with io.open_wt(self._exif_file(image)) as fout: io.json_dump(data, fout)
def compute_depthmap(arguments): """Compute depthmap for a single shot.""" log.setup() data, neighbors, min_depth, max_depth, shot = arguments method = data.config['depthmap_method'] if data.raw_depthmap_exists(shot.id): logger.info("Using precomputed raw depthmap {}".format(shot.id)) return logger.info("Computing depthmap for image {0} with {1}".format(shot.id, method)) de = csfm.DepthmapEstimator() de.set_depth_range(min_depth, max_depth, 100) de.set_patchmatch_iterations(data.config['depthmap_patchmatch_iterations']) de.set_min_patch_sd(data.config['depthmap_min_patch_sd']) add_views_to_depth_estimator(data, neighbors, de) if (method == 'BRUTE_FORCE'): depth, plane, score, nghbr = de.compute_brute_force() elif (method == 'PATCH_MATCH'): depth, plane, score, nghbr = de.compute_patch_match() elif (method == 'PATCH_MATCH_SAMPLE'): depth, plane, score, nghbr = de.compute_patch_match_sample() else: raise ValueError( 'Unknown depthmap method type ' '(must be BRUTE_FORCE, PATCH_MATCH or PATCH_MATCH_SAMPLE)') good_score = score > data.config['depthmap_min_correlation_score'] depth = depth * (depth < max_depth) * good_score # Save and display results neighbor_ids = [i.id for i in neighbors[1:]] data.save_raw_depthmap(shot.id, depth, plane, score, nghbr, neighbor_ids) if data.config['depthmap_save_debug_files']: image = data.undistorted_image_as_array(shot.id) image = scale_down_image(image, depth.shape[1], depth.shape[0]) ply = depthmap_to_ply(shot, depth, image) with io.open_wt(data._depthmap_file(shot.id, 'raw.npz.ply')) as fout: fout.write(ply) if data.config.get('interactive'): import matplotlib.pyplot as plt plt.figure() plt.suptitle("Shot: " + shot.id + ", neighbors: " + ', '.join(neighbor_ids)) plt.subplot(2, 3, 1) plt.imshow(image) plt.subplot(2, 3, 2) plt.imshow(color_plane_normals(plane)) plt.subplot(2, 3, 3) plt.imshow(depth) plt.colorbar() plt.subplot(2, 3, 4) plt.imshow(score) plt.colorbar() plt.subplot(2, 3, 5) plt.imshow(nghbr) plt.colorbar() plt.show()