def export_openmvg_structure( kapture_points_3d: kapture.Points3d, kapture_to_openmvg_view_ids: Dict[str, int], kapture_observations: Optional[kapture.Observations] = None, kapture_keypoints: Optional[kapture.Keypoints] = None, kapture_path: Optional[str] = None, ): # early check if kapture_points_3d is None: logger.warning('no 3D points to export.') return xyz_coordinates = kapture_points_3d[:, 0:3] include_2d_observations = kapture_observations is not None openmvg_structure = [] # this loop can be very long, lets show some progress hide_progress_bars = logger.getEffectiveLevel() > logging.INFO for point_idx, coords in enumerate(tqdm(xyz_coordinates, disable=hide_progress_bars)): point_3d_structure = { 'key': point_idx, 'value': { 'X': coords.tolist(), 'observations': [] } } if include_2d_observations and point_idx in kapture_observations: for kapture_image_name, feature_point_id in kapture_observations[point_idx]: openmvg_view_id = kapture_to_openmvg_view_ids[kapture_image_name] point_2d_observation = {'key': openmvg_view_id, 'value': {'id_feat': feature_point_id, }} if kapture_path and kapture_keypoints is not None: # if given, load keypoints to populate 2D coordinates of the feature. keypoints_file_path = get_keypoints_fullpath(kapture_path, kapture_image_name) try: keypoints_data = image_keypoints_from_file(keypoints_file_path, dtype=kapture_keypoints.dtype, dsize=kapture_keypoints.dsize) point_2d_observation['value']['x'] = keypoints_data[feature_point_id, 0:2].tolist() except FileNotFoundError: logger.warning(f'unable to load keypoints file {keypoints_file_path}') point_3d_structure['value']['observations'].append(point_2d_observation) openmvg_structure.append(point_3d_structure) return openmvg_structure
def extract_kapture_keypoints(kapture_root, config, output_dir='', overwrite=False): """ Extract r2d2 keypoints and descritors to the kapture format directly """ print('extract_kapture_keypoints...') kdata = kapture_from_dir(kapture_root, matches_pairsfile_path=None, skip_list= [kapture.GlobalFeatures, kapture.Matches, kapture.Points3d, kapture.Observations]) export_dir = output_dir if output_dir else kapture_root # root of output directory for features os.makedirs(export_dir, exist_ok=True) assert kdata.records_camera is not None image_list = [filename for _, _, filename in kapture.flatten(kdata.records_camera)] # resume extraction if some features exist try: # load existing features, if any kdata.keypoints = keypoints_from_dir(export_dir, None) kdata.descriptors = descriptors_from_dir(export_dir, None) if kdata.keypoints is not None and kdata.descriptors is not None and not overwrite: image_list = [name for name in image_list if name not in kdata.keypoints or name not in kdata.descriptors] except FileNotFoundError: pass except: logging.exception("Error with importing existing local features.") # clear features first if overwriting if overwrite: delete_existing_kapture_files(export_dir, True, only=[kapture.Descriptors, kapture.Keypoints]) if len(image_list) == 0: print('All features were already extracted') return else: print(f'Extracting r2d2 features for {len(image_list)} images') iscuda = common.torch_set_gpu([torch.cuda.is_available()]) # load the network... net = load_network(config['checkpoint']) if iscuda: net = net.cuda() # create the non-maxima detector detector = NonMaxSuppression( rel_thr = config['reliability_thr'], rep_thr = config['repeatability_thr']) keypoints_dtype = None if kdata.keypoints is None else kdata.keypoints.dtype descriptors_dtype = None if kdata.descriptors is None else kdata.descriptors.dtype keypoints_dsize = None if kdata.keypoints is None else kdata.keypoints.dsize descriptors_dsize = None if kdata.descriptors is None else kdata.descriptors.dsize for image_name in image_list: img_path = get_image_fullpath(kapture_root, image_name) if img_path.endswith('.txt'): images = open(img_path).read().splitlines() + images continue print(f"\nExtracting features for {img_path}") img = Image.open(img_path).convert('RGB') W, H = img.size img = norm_RGB(img)[None] if iscuda: img = img.cuda() # extract keypoints/descriptors for a single image xys, desc, scores = extract_multiscale(net, img, detector, scale_f = config['scale_f'], min_scale = config['min_scale'], max_scale = config['max_scale'], min_size = config['min_size'], max_size = config['max_size'], verbose = True) xys = xys.cpu().numpy() desc = desc.cpu().numpy() scores = scores.cpu().numpy() idxs = scores.argsort()[-config['top_k'] or None:] xys = xys[idxs] desc = desc[idxs] if keypoints_dtype is None or descriptors_dtype is None: keypoints_dtype = xys.dtype descriptors_dtype = desc.dtype keypoints_dsize = xys.shape[1] descriptors_dsize = desc.shape[1] kdata.keypoints = kapture.Keypoints('r2d2', keypoints_dtype, keypoints_dsize) kdata.descriptors = kapture.Descriptors('r2d2', descriptors_dtype, descriptors_dsize) keypoints_config_absolute_path = get_csv_fullpath(kapture.Keypoints, export_dir) descriptors_config_absolute_path = get_csv_fullpath(kapture.Descriptors, export_dir) keypoints_to_file(keypoints_config_absolute_path, kdata.keypoints) descriptors_to_file(descriptors_config_absolute_path, kdata.descriptors) else: assert kdata.keypoints.type_name == 'r2d2' assert kdata.descriptors.type_name == 'r2d2' assert kdata.keypoints.dtype == xys.dtype assert kdata.descriptors.dtype == desc.dtype assert kdata.keypoints.dsize == xys.shape[1] assert kdata.descriptors.dsize == desc.shape[1] keypoints_fullpath = get_keypoints_fullpath(export_dir, image_name) print(f"Saving {xys.shape[0]} keypoints to {keypoints_fullpath}") image_keypoints_to_file(keypoints_fullpath, xys) kdata.keypoints.add(image_name) descriptors_fullpath = get_descriptors_fullpath(export_dir, image_name) print(f"Saving {desc.shape[0]} descriptors to {descriptors_fullpath}") image_descriptors_to_file(descriptors_fullpath, desc) kdata.descriptors.add(image_name) if not keypoints_check_dir(kdata.keypoints, export_dir) or \ not descriptors_check_dir(kdata.descriptors, export_dir): print('local feature extraction ended successfully but not all files were saved')
def export_opensfm( kapture_rootdir: str, opensfm_rootdir: str, force_overwrite_existing: bool = False, images_import_method: TransferAction = TransferAction.copy) -> None: """ :param kapture_rootdir: :param opensfm_rootdir: :param force_overwrite_existing: :param images_import_method: :return: """ disable_tqdm = logger.getEffectiveLevel( ) > logging.INFO # dont display tqdm for non-verbose levels # load reconstruction kapture_data = kapture.io.csv.kapture_from_dir( kapture_dirpath=kapture_rootdir) # export cameras opensfm_cameras = {} kapture_cameras = { cam_id: cam for cam_id, cam in kapture_data.sensors.items() if cam.sensor_type == 'camera' } for cam_id, kapture_camera in kapture_cameras.items(): opensfm_cameras[cam_id] = export_opensfm_camera(kapture_camera) # export shots opensfm_shots = {} for timestamp, camera_id, image_filename in tqdm(kapture.flatten( kapture_data.records_camera), disable=disable_tqdm): # retrieve pose (if there is one). # opensfm_shots = {image_filename: shot} # shot = {camera , rotation, translation, capture_time, gps_position, ...} opensfm_shot = { 'capture_time': 0, # in ms != timestamp 'camera': camera_id, } if (timestamp, camera_id) in kapture_data.trajectories: pose = kapture_data.trajectories[timestamp, camera_id] rotation_vector = quaternion.as_rotation_vector(pose.r) translation_vector = pose.t.flatten() opensfm_shot.update({ 'rotation': rotation_vector.tolist(), 'translation': translation_vector.tolist() }) opensfm_shots[image_filename] = opensfm_shot # pack it opensfm_reconstruction = { 'cameras': opensfm_cameras, 'shots': opensfm_shots, } # images logger.info( f'writing image files "{path.join(opensfm_rootdir, "images")}".') image_filenames = [ f for _, _, f in kapture.flatten(kapture_data.records_camera) ] kapture_image_filepaths = [ get_record_fullpath(kapture_rootdir, image_filename) for image_filename in image_filenames ] opensfm_image_filepaths = [ path.join(opensfm_rootdir, 'images', image_filename) for image_filename in image_filenames ] transfer_files_from_dir( source_filepath_list=kapture_image_filepaths, destination_filepath_list=opensfm_image_filepaths, force_overwrite=force_overwrite_existing, copy_strategy=images_import_method, ) # export features files (keypoints + descriptors) opensfm_features_suffix = '.features.npz' opensfm_features_dirpath = path.join(opensfm_rootdir, 'features') logger.info( f'exporting keypoint and descriptors to {opensfm_features_dirpath}') os.makedirs(opensfm_features_dirpath, exist_ok=True) for image_filename in tqdm(image_filenames, disable=disable_tqdm): opensfm_features = {} # look and load for keypoints in kapture if kapture_data.keypoints is not None and image_filename in kapture_data.keypoints: kapture_keypoints_filepath = get_keypoints_fullpath( kapture_dirpath=kapture_rootdir, image_filename=image_filename) logger.debug(f'loading {kapture_keypoints_filepath}') kapture_keypoint = image_keypoints_from_file( kapture_keypoints_filepath, dtype=kapture_data.keypoints.dtype, dsize=kapture_data.keypoints.dsize) opensfm_features['points'] = kapture_keypoint # look and load for descriptors in kapture if kapture_data.descriptors is not None and image_filename in kapture_data.descriptors: kapture_descriptor_filepath = get_descriptors_fullpath( kapture_dirpath=kapture_rootdir, image_filename=image_filename) logger.debug(f'loading {kapture_descriptor_filepath}') kapture_descriptor = image_descriptors_from_file( kapture_descriptor_filepath, dtype=kapture_data.descriptors.dtype, dsize=kapture_data.descriptors.dsize) opensfm_features['descriptors'] = kapture_descriptor # writing opensfm feature file if len(opensfm_features) > 0: opensfm_features_filepath = path.join( opensfm_features_dirpath, image_filename + opensfm_features_suffix) logger.debug(f'writing {opensfm_features_filepath}') os.makedirs(path.dirname(opensfm_features_filepath), exist_ok=True) np.save(opensfm_features_filepath, opensfm_features) # export matches files if kapture_data.matches is not None: opensfm_matches_suffix = '_matches.pkl.gz' opensfm_matches_dirpath = path.join(opensfm_rootdir, 'matches') os.makedirs(opensfm_matches_dirpath, exist_ok=True) logger.info(f'exporting matches to {opensfm_matches_dirpath}') opensfm_pairs = {} for image_filename1, image_filename2 in kapture_data.matches: opensfm_pairs.setdefault(image_filename1, []).append(image_filename2) for image_filename1 in tqdm(image_filenames, disable=disable_tqdm): opensfm_matches = {} opensfm_matches_filepath = path.join( opensfm_matches_dirpath, image_filename1 + opensfm_matches_suffix) logger.debug(f'loading matches for {image_filename1}') for image_filename2 in opensfm_pairs.get(image_filename1, []): # print(image_filename1, image_filename2) kapture_matches_filepath = get_matches_fullpath( (image_filename1, image_filename2), kapture_dirpath=kapture_rootdir) kapture_matches = image_matches_from_file( kapture_matches_filepath) opensfm_matches[image_filename2] = kapture_matches[:, 0:2].astype( np.int) os.makedirs(path.dirname(opensfm_matches_filepath), exist_ok=True) with gzip.open(opensfm_matches_filepath, 'wb') as f: pickle.dump(opensfm_matches, f) # export 3D-points files if kapture_data.points3d is not None: logger.info('exporting points 3-D') opensfm_reconstruction['points'] = {} for i, (x, y, z, r, g, b) in tqdm(enumerate(kapture_data.points3d), disable=disable_tqdm): opensfm_reconstruction['points'][i] = { 'coordinates': [x, y, z], 'color': [r, g, b] } # write json files ################################################################################################# os.makedirs(opensfm_rootdir, exist_ok=True) # write reconstruction.json opensfm_reconstruction_filepath = path.join(opensfm_rootdir, 'reconstruction.json') logger.info( f'writing reconstruction file "{opensfm_reconstruction_filepath}".') with open(opensfm_reconstruction_filepath, 'wt') as f: json.dump([opensfm_reconstruction], f, indent=4) # write camera_models.json opensfm_cameras_filepath = path.join(opensfm_rootdir, 'camera_models.json') logger.info(f'writing camera models file "{opensfm_cameras_filepath}".') with open(opensfm_cameras_filepath, 'wt') as f: json.dump(opensfm_cameras, f, indent=4)
kdata.keypoints = kapture.Keypoints('d2net', keypoints_dtype, keypoints_dsize) kdata.descriptors = kapture.Descriptors('d2net', descriptors_dtype, descriptors_dsize) keypoints_config_absolute_path = get_csv_fullpath(kapture.Keypoints, args.kapture_root) descriptors_config_absolute_path = get_csv_fullpath(kapture.Descriptors, args.kapture_root) keypoints_to_file(keypoints_config_absolute_path, kdata.keypoints) descriptors_to_file(descriptors_config_absolute_path, kdata.descriptors) else: assert kdata.keypoints.type_name == 'd2net' assert kdata.descriptors.type_name == 'd2net' assert kdata.keypoints.dtype == keypoints.dtype assert kdata.descriptors.dtype == descriptors.dtype assert kdata.keypoints.dsize == keypoints.shape[1] assert kdata.descriptors.dsize == descriptors.shape[1] keypoints_fullpath = get_keypoints_fullpath(args.kapture_root, image_name) print(f"Saving {keypoints.shape[0]} keypoints to {keypoints_fullpath}") image_keypoints_to_file(keypoints_fullpath, keypoints) kdata.keypoints.add(image_name) descriptors_fullpath = get_descriptors_fullpath(args.kapture_root, image_name) print(f"Saving {descriptors.shape[0]} descriptors to {descriptors_fullpath}") image_descriptors_to_file(descriptors_fullpath, descriptors) kdata.descriptors.add(image_name) if not keypoints_check_dir(kdata.keypoints, args.kapture_root) or \ not descriptors_check_dir(kdata.descriptors, args.kapture_root): print('local feature extraction ended successfully but not all files were saved')
def add_frames(self, frames: List[Frame], points3d: List[Keypoint]): k = self.kapture if k.records_camera is None: k.records_camera = kt.RecordsCamera() if k.trajectories is None: k.trajectories = kt.Trajectories() if k.keypoints is None: k.keypoints = { self.default_kp_type: kt.Keypoints(self.default_kp_type, np.float32, 2) } if k.points3d is None: k.points3d = kt.Points3d() if k.observations is None: k.observations = kt.Observations() def check_kp(kp): return not kp.bad_qlt and kp.inlier_count > self.min_pt3d_obs and kp.inlier_count / kp.total_count > self.min_pt3d_ratio kp_ids, pts3d = zip(*[(kp.id, kp.pt3d) for kp in points3d if check_kp(kp)]) I = np.argsort(kp_ids) pt3d_ids = dict(zip(np.array(kp_ids)[I], np.arange(len(I)))) pt3d_arr = np.array(pts3d)[I, :] k.points3d = kt.Points3d( np.concatenate((pt3d_arr, np.ones_like(pt3d_arr) * 128), axis=1)) for f in frames: if not f.pose.post: continue id = f.frame_num img = f.orig_image img_file = os.path.join(self.default_cam[1], 'frame%06d.%s' % (id, self.img_format)) img_fullpath = get_record_fullpath(self.path, img_file) os.makedirs(os.path.dirname(img_fullpath), exist_ok=True) if not np.isclose(self.scale, 1.0): img = cv2.resize(img, None, fx=self.scale, fy=self.scale, interpolation=cv2.INTER_AREA) if self.img_format == self.IMG_FORMAT_PNG: cv2.imwrite(img_fullpath, img, (cv2.IMWRITE_PNG_COMPRESSION, 9)) elif self.img_format == self.IMG_FORMAT_JPG: cv2.imwrite(img_fullpath, img, (cv2.IMWRITE_JPEG_QUALITY, self.jpg_qlt)) else: assert False, 'Invalid image format: %s' % (self.img_format, ) record_id = (id, self.default_cam[0]) k.records_camera[record_id] = img_file pose = f.pose.post if 1 else (-f.pose.post) k.trajectories[record_id] = kt.PoseTransform( r=pose.quat.components, t=pose.loc) k.keypoints[self.default_kp_type].add(img_file) uvs = np.zeros((len(f.kps_uv), 2), np.float32) i = 0 for kp_id, uv in f.kps_uv.items(): if kp_id in pt3d_ids: k.observations.add(int(pt3d_ids[kp_id]), self.default_kp_type, img_file, i) uvs[i, :] = uv / f.img_sc * self.scale i += 1 image_keypoints_to_file( get_keypoints_fullpath(self.default_kp_type, self.path, img_file), uvs[:i, :])
def extract_kapture_keypoints(args): """ Extract r2d2 keypoints and descritors to the kapture format directly """ print('extract_kapture_keypoints...') kdata = kapture_from_dir(args.kapture_root, matches_pairsfile_path=None, skip_list=[ kapture.GlobalFeatures, kapture.Matches, kapture.Points3d, kapture.Observations ]) assert kdata.records_camera is not None image_list = [ filename for _, _, filename in kapture.flatten(kdata.records_camera) ] if kdata.keypoints is not None and kdata.descriptors is not None: image_list = [ name for name in image_list if name not in kdata.keypoints or name not in kdata.descriptors ] if len(image_list) == 0: print('All features were already extracted') return else: print(f'Extracting r2d2 features for {len(image_list)} images') iscuda = common.torch_set_gpu(args.gpu) # load the network... net = load_network(args.model) if iscuda: net = net.cuda() # create the non-maxima detector detector = NonMaxSuppression(rel_thr=args.reliability_thr, rep_thr=args.repeatability_thr) keypoints_dtype = None if kdata.keypoints is None else kdata.keypoints.dtype descriptors_dtype = None if kdata.descriptors is None else kdata.descriptors.dtype keypoints_dsize = None if kdata.keypoints is None else kdata.keypoints.dsize descriptors_dsize = None if kdata.descriptors is None else kdata.descriptors.dsize for image_name in image_list: img_path = get_image_fullpath(args.kapture_root, image_name) print(f"\nExtracting features for {img_path}") img = Image.open(img_path).convert('RGB') W, H = img.size img = norm_RGB(img)[None] if iscuda: img = img.cuda() # extract keypoints/descriptors for a single image xys, desc, scores = extract_multiscale(net, img, detector, scale_f=args.scale_f, min_scale=args.min_scale, max_scale=args.max_scale, min_size=args.min_size, max_size=args.max_size, verbose=True) xys = xys.cpu().numpy() desc = desc.cpu().numpy() scores = scores.cpu().numpy() idxs = scores.argsort()[-args.top_k or None:] xys = xys[idxs] desc = desc[idxs] if keypoints_dtype is None or descriptors_dtype is None: keypoints_dtype = xys.dtype descriptors_dtype = desc.dtype keypoints_dsize = xys.shape[1] descriptors_dsize = desc.shape[1] kdata.keypoints = kapture.Keypoints('r2d2', keypoints_dtype, keypoints_dsize) kdata.descriptors = kapture.Descriptors('r2d2', descriptors_dtype, descriptors_dsize) keypoints_config_absolute_path = get_csv_fullpath( kapture.Keypoints, args.kapture_root) descriptors_config_absolute_path = get_csv_fullpath( kapture.Descriptors, args.kapture_root) keypoints_to_file(keypoints_config_absolute_path, kdata.keypoints) descriptors_to_file(descriptors_config_absolute_path, kdata.descriptors) else: assert kdata.keypoints.type_name == 'r2d2' assert kdata.descriptors.type_name == 'r2d2' assert kdata.keypoints.dtype == xys.dtype assert kdata.descriptors.dtype == desc.dtype assert kdata.keypoints.dsize == xys.shape[1] assert kdata.descriptors.dsize == desc.shape[1] keypoints_fullpath = get_keypoints_fullpath(args.kapture_root, image_name) print(f"Saving {xys.shape[0]} keypoints to {keypoints_fullpath}") image_keypoints_to_file(keypoints_fullpath, xys) kdata.keypoints.add(image_name) descriptors_fullpath = get_descriptors_fullpath( args.kapture_root, image_name) print(f"Saving {desc.shape[0]} descriptors to {descriptors_fullpath}") image_descriptors_to_file(descriptors_fullpath, desc) kdata.descriptors.add(image_name) if not keypoints_check_dir(kdata.keypoints, args.kapture_root) or \ not descriptors_check_dir(kdata.descriptors, args.kapture_root): print( 'local feature extraction ended successfully but not all files were saved' )
def load_keypoints(keypoints_type, input_path, image_name, dtype, dsize, tar_handlers): keypoints_path = get_keypoints_fullpath(keypoints_type, input_path, image_name, tar_handlers) return image_keypoints_from_file(keypoints_path, dtype, dsize)
kdata.descriptors[args.descriptors_type]) else: assert kdata.keypoints[ args.keypoints_type].dtype == keypoints.dtype assert kdata.descriptors[ args.descriptors_type].dtype == descriptors.dtype assert kdata.keypoints[ args.keypoints_type].dsize == keypoints.shape[1] assert kdata.descriptors[ args.descriptors_type].dsize == descriptors.shape[1] assert kdata.descriptors[ args.descriptors_type].keypoints_type == args.keypoints_type assert kdata.descriptors[args.descriptors_type].metric_type == 'L2' keypoints_fullpath = get_keypoints_fullpath(args.keypoints_type, args.kapture_root, image_name, tar_handlers) print(f"Saving {keypoints.shape[0]} keypoints to {keypoints_fullpath}") image_keypoints_to_file(keypoints_fullpath, keypoints) kdata.keypoints[args.keypoints_type].add(image_name) descriptors_fullpath = get_descriptors_fullpath( args.descriptors_type, args.kapture_root, image_name, tar_handlers) print( f"Saving {descriptors.shape[0]} descriptors to {descriptors_fullpath}" ) image_descriptors_to_file(descriptors_fullpath, descriptors) kdata.descriptors[args.descriptors_type].add(image_name) if not keypoints_check_dir(kdata.keypoints[args.keypoints_type], args.keypoints_type, args.kapture_root, tar_handlers) or \
def _export_opensfm_features_and_matches(image_filenames, kapture_data, kapture_root_dir, opensfm_root_dir, disable_tqdm): """ export features files (keypoints + descriptors) and matches """ opensfm_features_suffix = '.features.npz' opensfm_features_dir_path = path.join(opensfm_root_dir, 'features') logger.info( f'exporting keypoint and descriptors to {opensfm_features_dir_path}') os.makedirs(opensfm_features_dir_path, exist_ok=True) for image_filename in tqdm(image_filenames, disable=disable_tqdm): opensfm_features = {} # look and load for keypoints in kapture if kapture_data.keypoints is not None and image_filename in kapture_data.keypoints: kapture_keypoints_filepath = get_keypoints_fullpath( kapture_dirpath=kapture_root_dir, image_filename=image_filename) logger.debug(f'loading {kapture_keypoints_filepath}') kapture_keypoint = image_keypoints_from_file( kapture_keypoints_filepath, dtype=kapture_data.keypoints.dtype, dsize=kapture_data.keypoints.dsize) opensfm_features['points'] = kapture_keypoint # look and load for descriptors in kapture if kapture_data.descriptors is not None and image_filename in kapture_data.descriptors: kapture_descriptor_filepath = get_descriptors_fullpath( kapture_dirpath=kapture_root_dir, image_filename=image_filename) logger.debug(f'loading {kapture_descriptor_filepath}') kapture_descriptor = image_descriptors_from_file( kapture_descriptor_filepath, dtype=kapture_data.descriptors.dtype, dsize=kapture_data.descriptors.dsize) opensfm_features['descriptors'] = kapture_descriptor # writing opensfm feature file if len(opensfm_features) > 0: opensfm_features_filepath = path.join( opensfm_features_dir_path, image_filename + opensfm_features_suffix) logger.debug(f'writing {opensfm_features_filepath}') os.makedirs(path.dirname(opensfm_features_filepath), exist_ok=True) np.save(opensfm_features_filepath, opensfm_features) # export matches files if kapture_data.matches is not None: opensfm_matches_suffix = '_matches.pkl.gz' opensfm_matches_dir_path = path.join(opensfm_root_dir, 'matches') os.makedirs(opensfm_matches_dir_path, exist_ok=True) logger.info(f'exporting matches to {opensfm_matches_dir_path}') opensfm_pairs = {} for image_filename1, image_filename2 in kapture_data.matches: opensfm_pairs.setdefault(image_filename1, []).append(image_filename2) for image_filename1 in tqdm(image_filenames, disable=disable_tqdm): opensfm_matches = {} opensfm_matches_filepath = path.join( opensfm_matches_dir_path, image_filename1 + opensfm_matches_suffix) logger.debug(f'loading matches for {image_filename1}') for image_filename2 in opensfm_pairs.get(image_filename1, []): # print(image_filename1, image_filename2) kapture_matches_filepath = get_matches_fullpath( (image_filename1, image_filename2), kapture_dirpath=kapture_root_dir) kapture_matches = image_matches_from_file( kapture_matches_filepath) opensfm_matches[image_filename2] = kapture_matches[:, 0:2].astype( np.int) os.makedirs(path.dirname(opensfm_matches_filepath), exist_ok=True) with gzip.open(opensfm_matches_filepath, 'wb') as f: pickle.dump(opensfm_matches, f)
def load_from_kapture(self, kapture_data, minimal_observation_count=10): image_list = [ filename for _, _, filename in kapture.flatten(kapture_data.records_camera) ] descriptors = [] keypoints = [] points3d = [] mask = [] image_indexes = {} image_index_list = [] keypoint_index_list = [] self.keypoint_count = 0 for i, image_path in enumerate(image_list): descriptors_full_path = get_descriptors_fullpath( self._descriptor_name, kapture_data.kapture_path, image_path) kapture_descriptors = kapture_data.descriptors[ self._descriptor_name] descriptors.append( image_descriptors_from_file(descriptors_full_path, kapture_descriptors.dtype, kapture_descriptors.dsize)) keypoints_full_path = get_keypoints_fullpath( self._descriptor_name, kapture_data.kapture_path, image_path) kapture_keypoints = kapture_data.keypoints[self._descriptor_name] keypoints.append( image_keypoints_from_file(keypoints_full_path, kapture_keypoints.dtype, kapture_keypoints.dsize)) point_count = len(keypoints[i]) points3d.append(np.zeros((point_count, 3), dtype=np.float32)) mask.append(np.zeros(point_count, dtype=np.bool)) image_indexes[image_path] = i image_index_list.append(np.array([i] * point_count)) keypoint_index_list.append(np.arange(point_count)) self.keypoint_count += point_count for point_index, observation in kapture_data.observations.items(): if len(observation[ self._descriptor_name]) > minimal_observation_count: for observation_image_name, image_keypoints_index in observation[ self._descriptor_name]: image_index = image_indexes[observation_image_name] mask[image_index][image_keypoints_index] = True points3d[image_index][ image_keypoints_index] = kapture_data.points3d[ point_index][:3] for i in range(len(mask)): self.image_index_list.extend(list(image_index_list[i])) self.keypoint_index_list.extend(list(keypoint_index_list[i])) self.masked_image_index_list.extend( list(image_index_list[i][mask[i]])) self.masked_keypoint_index_list.extend( list(keypoint_index_list[i][mask[i]])) self.descriptors = descriptors self.keypoints = keypoints self.points3d = points3d self.mask = mask self.image_index_from_image_name = image_indexes self.load_trajectory(kapture_data)