Example #1
0
    def test_keypoints_read_from_images(self):
        # Create
        images_ids = set(f'cam{cam}/{timestamp:05d}.jpg' for cam in range(2)
                         for timestamp in range(2))
        keypoints_config_filepath = path.join(self._keypoints_dirpath,
                                              'keypoints.txt')
        os.makedirs(path.dirname(keypoints_config_filepath), exist_ok=True)
        with open(keypoints_config_filepath, 'wt') as f:
            f.write('SIFT, float, 4')

        # lock and load
        keypoints = csv.keypoints_from_dir(self._kapture_dirpath, images_ids)

        # check its empty
        self.assertEqual('SIFT', keypoints.type_name)
        self.assertEqual(0, len(keypoints))

        valid = kapture.io.features.keypoints_check_dir(
            keypoints, self._kapture_dirpath)
        self.assertTrue(valid)

        # create actual files
        for images_id in images_ids:
            keypoint_filepath = path.join(self._keypoints_dirpath,
                                          images_id + '.kpt')
            os.makedirs(path.dirname(keypoint_filepath), exist_ok=True)
            with open(keypoint_filepath, 'wt') as f:
                f.write('')

        # lock and load again
        keypoints = csv.keypoints_from_dir(self._kapture_dirpath, images_ids)
        self.assertEqual('SIFT', keypoints.type_name)
        self.assertEqual(4, len(keypoints))

        keypoints_filepaths = kapture.io.features.keypoints_to_filepaths(
            keypoints, self._kapture_dirpath)
        image_filenames_expected = {
            f'cam{ci}/{ts:05d}.jpg'
            for ci in [0, 1] for ts in [0, 1]
        }
        feature_filepaths_expected = {
            path_secure(
                f'{self._kapture_dirpath}/reconstruction/keypoints/cam{ci}/{ts:05d}.jpg.kpt'
            )
            for ci in [0, 1] for ts in [0, 1]
        }

        self.assertEqual(image_filenames_expected, set(keypoints_filepaths))
        self.assertEqual(feature_filepaths_expected,
                         set(keypoints_filepaths.values()))

        valid = kapture.io.features.keypoints_check_dir(
            keypoints, self._kapture_dirpath)
        self.assertTrue(valid)

        # destroy files and check
        os.remove(path.join(self._keypoints_dirpath, 'cam0/00000.jpg.kpt'))
        valid = kapture.io.features.keypoints_check_dir(
            keypoints, self._kapture_dirpath)
        self.assertFalse(valid)
Example #2
0
    def test_keypoints_read_from_files(self):
        images_ids = set(f'cam{cam}/{timestamp:05d}.jpg'
                         for cam in range(2)
                         for timestamp in range(2))
        # make up keypoints files
        keypoints_config_filepath = path.join(self._keypoints_dirpath, 'keypoints.txt')
        os.makedirs(path.dirname(keypoints_config_filepath), exist_ok=True)
        with open(keypoints_config_filepath, 'wt') as f:
            f.write('SIFT, float, 4')
        keypoints_fullpaths = [
            path_secure(path.join(self._keypoints_dirpath, image_id + '.kpt'))
            for image_id in images_ids
        ]
        for keypoints_fullpath in keypoints_fullpaths:
            os.makedirs(path.dirname(keypoints_fullpath), exist_ok=True)
            with open(keypoints_fullpath, 'wt') as f:
                f.write(' ')

        # lock and load
        keypoints = csv.keypoints_from_dir(self._kapture_dirpath, None)

        # check
        self.assertEqual('SIFT', keypoints.type_name)
        self.assertEqual(4, len(keypoints))
        keypoints_filepaths = kapture.io.features.keypoints_to_filepaths(keypoints, self._kapture_dirpath)
        image_filenames_expected = {path_secure(os.path.join(f'cam{ci}', f'{ts:05d}.jpg'))
                                    for ci in [0, 1] for ts in [0, 1]}
        feature_filepaths_expected = {
            path_secure(os.path.join(f'{self._kapture_dirpath}', 'reconstruction',
                                     'keypoints', f'cam{ci}', f'{ts:05d}.jpg.kpt'))
            for ci in [0, 1] for ts in [0, 1]}

        self.assertEqual(image_filenames_expected, set(keypoints_filepaths))
        self.assertEqual(feature_filepaths_expected, set(keypoints_filepaths.values()))
Example #3
0
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')