def match_features(self, kapture_data): image_list = [ filename for _, _, filename in kapture.flatten(kapture_data.records_camera) ] descriptors = [] descriptor_type = kapture_data.descriptors.dtype descriptor_size = kapture_data.descriptors.dsize for image_path in image_list: descriptors_full_path = get_descriptors_fullpath( kapture_data.kapture_path, image_path) descriptors.append( image_descriptors_from_file(descriptors_full_path, descriptor_type, descriptor_size)) kapture_data.matches = kapture.Matches() if self._sequential_length is None: self._sequential_length = len(image_list) for i in tqdm(range(len(image_list))): for j in range(i + 1, min(len(image_list), i + self._sequential_length)): matches = self._matcher.match_descriptors( descriptors[i], descriptors[j]) if self._minimal_score is not None: mask = matches[:, 2] > self._minimal_score matches = matches[mask] kapture_data.matches.add(image_list[i], image_list[j]) matches_full_path = get_matches_fullpath( (image_list[i], image_list[j]), kapture_data.kapture_path) image_matches_to_file(matches_full_path, matches)
def load_descriptors(input_path: str, image_name: str, dtype, dsize): """ load a descriptor. this functions caches up to 50 descriptors :param input_path: input path to kapture input root directory :param image_name: name of the image :param dtype: dtype of the numpy array :param dsize: size of the numpy array """ descriptors_path = get_descriptors_fullpath(input_path, image_name) return image_descriptors_from_file(descriptors_path, dtype, dsize)
def load_descriptors(descriptors_type: str, input_path: str, tar_handler: Optional[TarCollection], image_name: str, dtype, dsize): """ load a descriptor. this functions caches up to 50 descriptors :param descriptors_type: type of descriptors, name of the descriptors subfolder :param input_path: input path to kapture input root directory :param tar_handler: collection of preloaded tar archives :param image_name: name of the image :param dtype: dtype of the numpy array :param dsize: size of the numpy array """ descriptors_path = get_descriptors_fullpath(descriptors_type, input_path, image_name, tar_handler) return image_descriptors_from_file(descriptors_path, dtype, dsize)
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 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' )
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 \ not descriptors_check_dir(kdata.descriptors[args.descriptors_type], args.descriptors_type, args.kapture_root, tar_handlers): print( 'local feature extraction ended successfully but not all files were saved' )
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)