Esempio n. 1
0
 def test_write_read(self):
     nb_keypoints = 5
     dim_keypoint = 4
     type_keypoint = float
     image_keypoints = np.random.random((nb_keypoints, dim_keypoint)).astype(type_keypoint)
     binary.image_keypoints_to_file(self._temp_filepath, image_keypoints)
     image_keypoints_read = binary.image_keypoints_from_file(self._temp_filepath,
                                                             dtype=type_keypoint,
                                                             dsize=dim_keypoint)
     self.assertEqual(image_keypoints.shape, image_keypoints_read.shape)
     self.assertEqual(image_keypoints.dtype, image_keypoints_read.dtype)
     self.assertAlmostEqual(image_keypoints.tolist(), image_keypoints_read.tolist())
Esempio n. 2
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')
Esempio n. 3
0
    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, :])
Esempio n. 4
0
        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')
Esempio n. 5
0
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'
        )