def main(unused_argv):
  tf.logging.set_verbosity(tf.logging.INFO)

  start = time.time()

  # Read features.
  locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(
      cmd_args.features_1_path)
  num_features_1 = locations_1.shape[0]
  tf.logging.info("Loaded image 1's %d features" % num_features_1)
  locations_2, _, descriptors_2, _, _ = feature_io.ReadFromFile(
      cmd_args.features_2_path)
  num_features_2 = locations_2.shape[0]
  tf.logging.info("Loaded image 2's %d features" % num_features_2)

  # Find nearest-neighbor matches using a KD tree.
  d1_tree = spatial.cKDTree(descriptors_1)
  _, indices = d1_tree.query(
      descriptors_2, distance_upper_bound=_DISTANCE_THRESHOLD)

  print('>> feature match elapsed time: {}'.format(htime(time.time() - start)))

  # Select feature locations for putative matches.
  locations_2_to_use = np.array([
      locations_2[i,]
      for i in range(num_features_2)
      if indices[i] != num_features_1
  ])
  locations_1_to_use = np.array([
      locations_1[indices[i],]
      for i in range(num_features_2)
      if indices[i] != num_features_1
  ])

  # Perform geometric verification using RANSAC.
  _, inliers = measure.ransac((locations_1_to_use, locations_2_to_use),
                              transform.AffineTransform,
                              min_samples=3,
                              residual_threshold=20,
                              max_trials=1000)

  tf.logging.info('Found %d inliers' % sum(inliers))

  # Visualize correspondences, and save to file.
  _, ax = plt.subplots()
  img_1 = mpimg.imread(cmd_args.image_1_path)
  img_2 = mpimg.imread(cmd_args.image_2_path)
  inlier_idxs = np.nonzero(inliers)[0]
  feature.plot_matches(
      ax,
      img_1,
      img_2,
      locations_1_to_use,
      locations_2_to_use,
      np.column_stack((inlier_idxs, inlier_idxs)),
      matches_color='b')
  ax.axis('off')
  ax.set_title('DELF correspondences')
  plt.savefig(cmd_args.output_image)
def checklandmark(landmark_features):

    feats =[]
    for root, dirs, files in os.walk(landmark_features):  # loop through startfolders
        for f in files:
            feats.append(f)

    i = iter(feats)
    labeldelf = mainpath + 'data/lk_features/' + i.next()
    print (labeldelf)
    testdelf = mainpath + 'data/lk_features/' + i.next()
    print (testdelf)

    locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(labeldelf)
    num_features_1 = locations_1.shape[0]
    #print("Loaded trainimage number of features:",num_features_1)
    locations_2, _, descriptors_2, _, _ = feature_io.ReadFromFile(testdelf)
    num_features_2 = locations_2.shape[0]
    #print("Loaded testimage number of features",num_features_2)

    # Find nearest-neighbor matches using a KD tree.
    d1_tree = cKDTree(descriptors_1)
    _, indices = d1_tree.query(
        descriptors_2, distance_upper_bound=_DISTANCE_THRESHOLD)

    # Select feature locations for putative matches.
    locations_2_to_use = np.array([
        locations_2[i,]
        for i in range(num_features_2)
        if indices[i] != num_features_1
    ])
    locations_1_to_use = np.array([
        locations_1[indices[i],]
        for i in range(num_features_2)
        if indices[i] != num_features_1
    ])

    # Perform geometric verification using RANSAC.

    try:
        _, inliers = ransac(
            (locations_1_to_use, locations_2_to_use),
            AffineTransform,
            min_samples=3,
            residual_threshold=20,
            max_trials=1000)

        inlier_idxs = np.nonzero(inliers)[0]
        #print(inlier_idxs)
        #print(len(inlier_idxs))

        return len(inlier_idxs)

    except:

        return 0
Exemplo n.º 3
0
def main(unused_argv):
  tf.logging.set_verbosity(tf.logging.INFO)

  # Read features.
  locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(
      cmd_args.features_1_path)
  locations_2, _, descriptors_2, _, _ = feature_io.ReadFromFile(
      cmd_args.features_2_path)

  img_1 = mpimg.imread(cmd_args.image_1_path)
  img_2 = mpimg.imread(cmd_args.image_2_path)
  get_ransac_image_byte(img_1, locations_1, descriptors_1, img_2, locations_2, descriptors_2, cmd_args.output_image)
Exemplo n.º 4
0
def main(*args):

    args = parse_args()

    # Read features.
    locations_1, _, descriptors_1, attention_1, _ = feature_io.ReadFromFile(
        args.features_1_path)
    locations_2, _, descriptors_2, attention_2, _ = feature_io.ReadFromFile(
        args.features_2_path)

    num_features_1 = locations_1.shape[0]
    num_features_2 = locations_2.shape[0]

    d1_tree = cKDTree(descriptors_1)
    distances, indices = d1_tree.query(
        descriptors_2, distance_upper_bound=args.distance_threshold)

    has_match = distances != np.inf
    locations_1_to_use = locations_1[indices[has_match]]
    locations_2_to_use = locations_2[has_match]

    _, inliers = ransac((locations_1_to_use, locations_2_to_use),
                        AffineTransform,
                        min_samples=3,
                        residual_threshold=20,
                        max_trials=1000)

    if inliers is None:
        raise Exception('match_images.py: inliers is None')
    else:
        print('number of inliers -> %d' % len(inliers))

    # --
    # Plot

    fig, ax = plt.subplots()

    inlier_idxs = np.nonzero(inliers)[0]
    plot_matches(ax,
                 mpimg.imread(args.image_1_path),
                 mpimg.imread(args.image_2_path),
                 locations_1_to_use,
                 locations_2_to_use,
                 np.column_stack((inlier_idxs, inlier_idxs)),
                 matches_color='b')
    ax.axis('off')
    ax.set_title('DELF correspondences')
    plt.savefig(args.output_image)
Exemplo n.º 5
0
    def build_cls_KDtree(self, pred_cls):
        db_delfs = self.get_db_paths(pred_cls, self.train_delf_root)
        db_delfs = [
            i[:-4] + ".delf"
            for i in db_delfs[:min(_MAXIMUM_MATCH, len(db_delfs))]
        ]

        results_dict = {
            'loc': [],
            'descriptor': [],
            'boundaries': []
        }  # Stores the locations and their descriptors for each image
        for delf_path in db_delfs:
            if not os.path.exists(delf_path):
                continue
            locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(
                delf_path)

            results_dict['loc'].append(locations_1)
            results_dict['descriptor'].append(descriptors_1)
            results_dict['boundaries'].append(locations_1.shape[0])

        try:
            locations_agg = np.concatenate(results_dict['loc'])
            descriptors_agg = np.concatenate(results_dict['descriptor'])
            accumulated_indexes_boundaries = np.cumsum(
                results_dict['boundaries'])
        except ValueError as e:
            print(e)
            return None
        # build the KD tree
        d_tree = cKDTree(descriptors_agg)
        return d_tree, (locations_agg, descriptors_agg,
                        accumulated_indexes_boundaries)
Exemplo n.º 6
0
    def get_item_pos(self, idx, pos):

        self.num_loaded += 1

        if isinstance(idx, int):
            file_name = self.list_file_names[idx]
        elif isinstance(idx, str):
            file_name = idx
        else:
            raise TypeError('idx must be int or str')

        target_path = os.path.join(self.dir_images,
                                   '{}.delf'.format(file_name))

        try:
            locations_1, scales_1, descriptors, _, _ = feature_io.ReadFromFile(
                target_path)
            num_features_1 = locations_1.shape[0]
        except ValueError:
            # not enough values to unpack (expected 5, got 4)
            return torch.randn(41, 1000).float()

        descriptors = np.swapaxes(descriptors, 0, 1)
        zeros = np.zeros((41, 1000))
        zeros[:40, :num_features_1] = descriptors
        zeros[40, :num_features_1] = (scales_1 - 0.5) / 10.0

        return torch.FloatTensor(zeros)
Exemplo n.º 7
0
    def match_landmark(self, query_feat_path, pred_cls):
        result = self.build_cls_KDtree(pred_cls=pred_cls)
        if result is None:
            return
        d_tree, (locations_agg, descriptors_agg,
                 accumulated_indexes_boundaries) = result
        # query
        if not os.path.exists(query_feat_path):
            return
        query_image_locations, _, query_image_descriptors, _, _ = feature_io.ReadFromFile(
            query_feat_path)

        # k-nearest neighbors
        try:
            distances, indices = d_tree.query(
                query_image_descriptors,
                distance_upper_bound=_DISTANCE_THRESHOLD,
                k=K_NEAREST,
                n_jobs=-1)
        except ValueError as e:
            print(e)
            return
        # Find the list of unique accumulated/aggregated indexes
        unique_indices = np.sort(np.unique(indices))
        if unique_indices[-1] == descriptors_agg.shape[0]:
            unique_indices = unique_indices[:-1]

        unique_image_indexes = np.unique([
            np.argmax(np.array(accumulated_indexes_boundaries) > index)
            for index in unique_indices
        ])

        # Array to keep track of all candidates in database.
        inliers_counts = []
        for index in unique_image_indexes:
            locations_2_use_query, locations_2_use_db = \
                get_locations_2_use(query_image_locations, locations_agg,
                                    index, indices, accumulated_indexes_boundaries)
            # Perform geometric verification using RANSAC.
            _, inliers = ransac(
                (locations_2_use_db,
                 locations_2_use_query),  # source and destination coordinates
                AffineTransform,
                min_samples=3,
                residual_threshold=20,
                max_trials=1000)
            # If no inlier is found for a database candidate image, we continue on to the next one.
            if inliers is None or len(inliers) == 0:
                continue
            # the number of inliers as the score for retrieved images.
            inliers_counts.append({"index": index, "inliers": sum(inliers)})

        inliers_list = []
        for inl in inliers_counts:
            inliers_list.append(inl['inliers'])
        return inliers_list
Exemplo n.º 8
0
    def testWriteAndReadToFileEmptyFile(self):
        filename = os.path.join(FLAGS.test_tmpdir, 'test.delf')
        feature_io.WriteToFile(filename, np.array([]), np.array([]),
                               np.array([]), np.array([]), np.array([]))
        data_read = feature_io.ReadFromFile(filename)

        self.assertAllEqual(np.array([]), data_read[0])
        self.assertAllEqual(np.array([]), data_read[1])
        self.assertAllEqual(np.array([]), data_read[2])
        self.assertAllEqual(np.array([]), data_read[3])
        self.assertAllEqual(np.array([]), data_read[4])
Exemplo n.º 9
0
  def testWriteAndReadToFileEmptyFile(self):
    tmpdir = tf.compat.v1.test.get_temp_dir()
    filename = os.path.join(tmpdir, 'test.delf')
    feature_io.WriteToFile(filename, np.array([]), np.array([]), np.array([]),
                           np.array([]), np.array([]))
    data_read = feature_io.ReadFromFile(filename)

    self.assertAllEqual(np.array([]), data_read[0])
    self.assertAllEqual(np.array([]), data_read[1])
    self.assertAllEqual(np.array([]), data_read[2])
    self.assertAllEqual(np.array([]), data_read[3])
    self.assertAllEqual(np.array([]), data_read[4])
Exemplo n.º 10
0
def match_image(features_1_path, features_2_path):
    # Read features.
    locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(
        features_1_path)
    num_features_1 = locations_1.shape[0]
    print(f"Loaded image 1's {num_features_1} features")
    locations_2, _, descriptors_2, _, _ = feature_io.ReadFromFile(
        features_2_path)
    num_features_2 = locations_2.shape[0]
    print(f"Loaded image 2's {num_features_2} features")

    # Find nearest-neighbor matches using a KD tree.
    d1_tree = spatial.cKDTree(descriptors_1)
    _, indices = d1_tree.query(descriptors_2,
                               distance_upper_bound=_DISTANCE_THRESHOLD)

    # Select feature locations for putative matches.
    locations_2_to_use = np.array([
        locations_2[i, ] for i in range(num_features_2)
        if indices[i] != num_features_1
    ])
    locations_1_to_use = np.array([
        locations_1[indices[i], ] for i in range(num_features_2)
        if indices[i] != num_features_1
    ])

    # Perform geometric verification using RANSAC.
    if max(len(locations_1_to_use), len(locations_2_to_use)) > 0:
        _, inliers = measure.ransac((locations_1_to_use, locations_2_to_use),
                                    transform.AffineTransform,
                                    min_samples=3,
                                    residual_threshold=20,
                                    max_trials=1000)

        print(f'Found {sum(inliers)} inliers')
        return sum(inliers)
    else:
        print('Found 0 inliers')
        return 0
Exemplo n.º 11
0
    def testWriteAndReadToFile(self):
        locations, scales, descriptors, attention, orientations = create_data()

        filename = os.path.join(FLAGS.test_tmpdir, 'test.delf')
        feature_io.WriteToFile(filename, locations, scales, descriptors,
                               attention, orientations)
        data_read = feature_io.ReadFromFile(filename)

        self.assertAllEqual(locations, data_read[0])
        self.assertAllEqual(scales, data_read[1])
        self.assertAllEqual(descriptors, data_read[2])
        self.assertAllEqual(attention, data_read[3])
        self.assertAllEqual(orientations, data_read[4])
Exemplo n.º 12
0
def get_num_inlier(locations_2, descriptors_2, path1):

    num_features_2 = locations_2.shape[0]

    try:
        locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(path1)
        num_features_1 = locations_1.shape[0]
    except:
        # print('Warning: Failed to load index feature')
        return -1

    # Find nearest-neighbor matches using a KD tree.
    d1_tree = cKDTree(descriptors_1)

    _, indices = d1_tree.query(descriptors_2,
                               distance_upper_bound=_DISTANCE_THRESHOLD)

    # Select feature locations for putative matches.

    locations_2_to_use = np.array([
        locations_2[i, ] for i in range(num_features_2)
        if indices[i] != num_features_1
    ])

    locations_1_to_use = np.array([
        locations_1[indices[i], ] for i in range(num_features_2)
        if indices[i] != num_features_1
    ])

    if len(locations_1_to_use) == 0 or len(locations_2_to_use) == 0:
        return 0

    try:
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")

            # Perform geometric verification using RANSAC.
            _, inliers = ransac((locations_1_to_use, locations_2_to_use),
                                AffineTransform,
                                min_samples=3,
                                residual_threshold=80,
                                max_trials=40)
    except:
        return 0

    if inliers is None:
        return 0

    return sum(inliers)
    def load_image(self, file_name):

        target_path = os.path.join(self.dir_images, file_name)

        try:
            locations_1, scales_1, descriptors, _, _ = feature_io.ReadFromFile(target_path)
            num_features_1 = locations_1.shape[0]
        except:
            return torch.randn(1, 40, 1000)

        descriptors = np.swapaxes(descriptors, 0, 1)
        zeros = np.zeros((1, 40, 1000))
        zeros[:, :, :num_features_1] = descriptors

        return torch.FloatTensor(zeros)
Exemplo n.º 14
0
def get_list_inliers(path1, list_images):

    try:
        locations_t, _, descriptors_t, _, _ = feature_io.ReadFromFile(path1)
    except:
        # print('Warning: Failed to load test feature')
        return range(len(list_images), 0, -1)

    list_inliers = list()

    for img in list_images:
        path2 = os.path.join('../../input_large_delf/index', img + '.delf')
        list_inliers.append(get_num_inlier(locations_t, descriptors_t, path2))

    return list_inliers
    def careful_search(self,image_path, k=10, multiple=4,DELFFile=None):
        '''
        精挑图片
        :param image_path: 图片路径名
        :param k: 返回多少张
        :param multiple:候选者的倍数
        :return: 最像的10张图片,不含后缀;以及相似度的平均分数
        '''
        similar_list = self.filter_search(image_path,int(k*multiple))
        if DELFFile:
            candidate_feature_path = DELFFile
            # Read features.
            try:
                locations_out, _, descriptors_out, _, _ = feature_io.ReadFromFile(candidate_feature_path)
            except:
                return similar_list[0:10],0
        else:
            locations_out, descriptors_out, feature_scales_out, attention_out = self.attention_model.get_single_attention(image_path)
        similar_list_new = careful_select(locations_out, descriptors_out, similar_list, k)
        average_similarity = self.count_average_similarity(similar_list_new)
        # if similar_list_new[9]['similarity'] > 20: #注意力网络需要比较图像有较多的相似度
        #     similar_list = similar_list_new
        #     similar_list = [s["image"] for s in similar_list]
        # else:
        #     similar_list = similar_list[0:k]

        similar_list_final = []
        for s in similar_list_new:
            if s['similarity'] > 20:
                similar_list_final.append(s['image'])
            if len(similar_list_final) == 10:
                break

        for s in similar_list:
            if len(similar_list_final) >= 10:
                break
            if s not in similar_list_final:
                similar_list_final.append(s)

        print(similar_list_final)

        return similar_list_final,average_similarity
def main(argv):
    if len(argv) > 1:
        raise RuntimeError('Too many command-line arguments.')

    # Process output directory.
    if tf.io.gfile.exists(cmd_args.output_cluster_dir):
        raise RuntimeError(
            'output_cluster_dir = %s already exists. This may indicate that a '
            'previous run already wrote checkpoints in this directory, which would '
            'lead to incorrect training. Please re-run this script by specifying an'
            ' inexisting directory.' % cmd_args.output_cluster_dir)
    else:
        tf.io.gfile.makedirs(cmd_args.output_cluster_dir)

    # Read list of index images from dataset file.
    print('Reading list of index images from dataset file...')
    _, index_list, _ = dataset.ReadDatasetFile(cmd_args.dataset_file_path)
    num_images = len(index_list)
    print('done! Found %d images' % num_images)

    # Loop over list of index images and collect DELF features.
    features_for_clustering = []
    start = time.clock()
    print('Starting to collect features from index images...')
    for i in range(num_images):
        if i > 0 and i % _STATUS_CHECK_ITERATIONS == 0:
            elapsed = (time.clock() - start)
            print('Processing index image %d out of %d, last %d '
                  'images took %f seconds' %
                  (i, num_images, _STATUS_CHECK_ITERATIONS, elapsed))
            start = time.clock()

        features_filename = index_list[i] + _DELF_EXTENSION
        features_fullpath = os.path.join(cmd_args.features_dir,
                                         features_filename)
        _, _, features, _, _ = feature_io.ReadFromFile(features_fullpath)
        if features.size != 0:
            assert features.shape[1] == _DELF_DIM
        for feature in features:
            features_for_clustering.append(feature)

    features_for_clustering = np.array(features_for_clustering,
                                       dtype=np.float32)
    print('All features were loaded! There are %d features, each with %d '
          'dimensions' %
          (features_for_clustering.shape[0], features_for_clustering.shape[1]))

    # Run K-means clustering.
    def _get_input_fn():
        """Helper function to create input function and hook for training.

    Returns:
      input_fn: Input function for k-means Estimator training.
      init_hook: Hook used to load data during training.
    """
        init_hook = _IteratorInitHook()

        def _input_fn():
            """Produces tf.data.Dataset object for k-means training.

      Returns:
        Tensor with the data for training.
      """
            features_placeholder = tf.compat.v1.placeholder(
                tf.float32, features_for_clustering.shape)
            delf_dataset = tf.data.Dataset.from_tensor_slices(
                (features_placeholder))
            delf_dataset = delf_dataset.shuffle(1000).batch(
                features_for_clustering.shape[0])
            iterator = tf.compat.v1.data.make_initializable_iterator(
                delf_dataset)

            def _initializer_fn(sess):
                """Initialize dataset iterator, feed in the data."""
                sess.run(
                    iterator.initializer,
                    feed_dict={features_placeholder: features_for_clustering})

            init_hook.iterator_initializer_fn = _initializer_fn
            return iterator.get_next()

        return _input_fn, init_hook

    input_fn, init_hook = _get_input_fn()

    kmeans = tf.compat.v1.estimator.experimental.KMeans(
        num_clusters=cmd_args.num_clusters,
        model_dir=cmd_args.output_cluster_dir,
        use_mini_batch=False,
    )

    print('Starting K-means clustering...')
    start = time.clock()
    for i in range(cmd_args.num_iterations):
        kmeans.train(input_fn, hooks=[init_hook])
        average_sum_squared_error = kmeans.evaluate(
            input_fn, hooks=[init_hook
                             ])['score'] / features_for_clustering.shape[0]
        elapsed = (time.clock() - start)
        print('K-means iteration %d (out of %d) took %f seconds, '
              'average-sum-of-squares: %f' %
              (i, cmd_args.num_iterations, elapsed, average_sum_squared_error))
        start = time.clock()

    print('K-means clustering finished!')
Exemplo n.º 17
0
datasets = ['Oxford5k', 'Paris6k', 'Holidays', 'Landmarks']

for dataset in datasets:

    query_dir = './result/' + dataset + '/query'
    query_list = natsort.natsorted(os.listdir(query_dir))
    result_dir = './delf/' + dataset + '/query'

    for q in query_list:
        # a = feature_io.ReadFromFile(query_dir + '/' + q)
        # print(len(a))
        # print(a[0].shape)
        # print(a[1].shape)
        # print(a[2].shape)
        # print(a[3].shape)
        query_l, _, query_d, _, _ = feature_io.ReadFromFile(query_dir + '/' +
                                                            q)
        mat_name = result_dir + '/' + q
        sio.savemat(mat_name, {'delf': query_d})
        print(mat_name)
        # break

    base_dir = './result/' + dataset + '/base'
    base_list = natsort.natsorted(os.listdir(base_dir))
    result_dir = './delf/' + dataset + '/base'

    for b in base_list:
        # a = feature_io.ReadFromFile(base_dir + '/' + b)
        # print(len(a))
        # print(a[0].shape)
        # print(a[1].shape)
        # print(a[2].shape)
Exemplo n.º 18
0
def ExtractAggregatedRepresentationsToFiles(image_names, features_dir,
                                            aggregation_config_path,
                                            mapping_path,
                                            output_aggregation_dir):
    """Extracts aggregated feature representations, saving them to files.

  It checks if the aggregated representation for an image already exists,
  and skips computation for those.

  Args:
    image_names: List of image names. These are used to compose input file names
      for the feature files, and the output file names for aggregated
      representations.
    features_dir: Directory where DELF features are located.
    aggregation_config_path: Path to AggregationConfig proto text file with
      configuration to be used for extraction.
    mapping_path: Optional CSV file which maps each .delf file name to the index
      image ID and detected box ID. If regional aggregation is performed, this
      should be set. Otherwise, this is ignored.
    output_aggregation_dir: Directory where aggregation output will be written
      to.

  Raises:
    ValueError: If AggregationConfig is malformed, or `mapping_path` is
      missing.
  """
    num_images = len(image_names)

    # Parse AggregationConfig proto, and select output extension.
    config = aggregation_config_pb2.AggregationConfig()
    with tf.io.gfile.GFile(aggregation_config_path, 'r') as f:
        text_format.Merge(f.read(), config)
    output_extension = '.'
    if config.use_regional_aggregation:
        output_extension += 'r'
    if config.aggregation_type == _VLAD:
        output_extension += _VLAD_EXTENSION_SUFFIX
    elif config.aggregation_type == _ASMK:
        output_extension += _ASMK_EXTENSION_SUFFIX
    elif config.aggregation_type == _ASMK_STAR:
        output_extension += _ASMK_STAR_EXTENSION_SUFFIX
    else:
        raise ValueError('Invalid aggregation type: %d' %
                         config.aggregation_type)

    # Read index mapping path, if provided.
    if mapping_path:
        images_to_box_feature_files = _ReadMappingBasenameToBoxNames(
            mapping_path, image_names)

    # Create output directory if necessary.
    if not tf.io.gfile.exists(output_aggregation_dir):
        tf.io.gfile.makedirs(output_aggregation_dir)

    with tf.compat.v1.Session() as sess:
        extractor = feature_aggregation_extractor.ExtractAggregatedRepresentation(
            sess, config)

        start = time.clock()
        for i in range(num_images):
            if i == 0:
                print('Starting to extract aggregation from images...')
            elif i % _STATUS_CHECK_ITERATIONS == 0:
                elapsed = (time.clock() - start)
                print('Processing image %d out of %d, last %d '
                      'images took %f seconds' %
                      (i, num_images, _STATUS_CHECK_ITERATIONS, elapsed))
                start = time.clock()

            image_name = image_names[i]

            # Compose output file name, skip extraction for this image if it already
            # exists.
            output_aggregation_filename = os.path.join(
                output_aggregation_dir, image_name + output_extension)
            if tf.io.gfile.exists(output_aggregation_filename):
                print('Skipping %s' % image_name)
                continue

            # Load DELF features.
            if config.use_regional_aggregation:
                if not mapping_path:
                    raise ValueError(
                        'Requested regional aggregation, but mapping_path was not '
                        'provided')
                descriptors_list = []
                num_features_per_box = []
                for box_feature_file in images_to_box_feature_files[
                        image_name]:
                    delf_filename = os.path.join(
                        features_dir, box_feature_file + _DELF_EXTENSION)
                    _, _, box_descriptors, _, _ = feature_io.ReadFromFile(
                        delf_filename)
                    # If `box_descriptors` is empty, reshape it such that it can be
                    # concatenated with other descriptors.
                    if not box_descriptors.shape[0]:
                        box_descriptors = np.reshape(
                            box_descriptors,
                            [0, config.feature_dimensionality])
                    descriptors_list.append(box_descriptors)
                    num_features_per_box.append(box_descriptors.shape[0])

                descriptors = np.concatenate(descriptors_list)
            else:
                input_delf_filename = os.path.join(
                    features_dir, image_name + _DELF_EXTENSION)
                _, _, descriptors, _, _ = feature_io.ReadFromFile(
                    input_delf_filename)
                # If `descriptors` is empty, reshape it to avoid extraction failure.
                if not descriptors.shape[0]:
                    descriptors = np.reshape(
                        descriptors, [0, config.feature_dimensionality])
                num_features_per_box = None

            # Extract and save aggregation. If using VLAD, only
            # `aggregated_descriptors` needs to be saved.
            (aggregated_descriptors,
             feature_visual_words) = extractor.Extract(descriptors,
                                                       num_features_per_box)
            if config.aggregation_type == _VLAD:
                datum_io.WriteToFile(aggregated_descriptors,
                                     output_aggregation_filename)
            else:
                datum_io.WritePairToFile(aggregated_descriptors,
                                         feature_visual_words.astype('uint32'),
                                         output_aggregation_filename)
Exemplo n.º 19
0
def count_i(land_name):
	data = land_name.split('/')[-1].split('.')[0]
	#file1 = open('txt_file_m18_m/'+data+'.txt','w')
	maxNum = 0
	maxName = ''
	for name in glob(feature_dir+'/*'):
		#print (name)
		name2 = name.split('/')
		number = name2[-1].split('.')[0]			
		# Read features.
		locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(land_name)
				#cmd_args.features_1_path)
		num_features_1 = locations_1.shape[0]
		#tf.logging.info("Loaded image 1's %d features" % num_features_1)
		locations_2, _, descriptors_2, _, _ = feature_io.ReadFromFile(name)
				#cmd_args.features_2_path)
		num_features_2 = locations_2.shape[0]
		#tf.logging.info("Loaded image 2's %d features" % num_features_2)

		# Find nearest-neighbor matches using a KD tree.
		d1_tree = cKDTree(descriptors_1)
		_, indices = d1_tree.query(
				descriptors_2, distance_upper_bound=_DISTANCE_THRESHOLD)

		# Select feature locations for putative matches.
		locations_2_to_use = np.array([
				locations_2[i,]
				for i in range(num_features_2)
				if indices[i] != num_features_1
		])
		locations_1_to_use = np.array([
				locations_1[indices[i],]
				for i in range(num_features_2)
				if indices[i] != num_features_1
		])

		# Perform geometric verification using RANSAC.
		try: 
			_, inliers = ransac(
					(locations_1_to_use, locations_2_to_use),
					AffineTransform,
					min_samples=3,
					residual_threshold=20,
					max_trials=1000)

			tf.logging.info('Found %d inliers' % sum(inliers))
			#print(sum(inliers))
			#print(maxNum)
			score = int(sum(inliers))
			#file1.write(name+'\t'+str(sum(inliers))+'\n')		
			num = name.split('/')[-1].split('.')[0]  
			if score>35 and score>maxNum:
				maxNum = score
				maxName = num2name[number]
				#print (maxName)
				#print (maxNum)
				#break

		except:
				#print('fail')
				a=0

	#print (maxName)
	#result_dic[data] = maxName
	return maxName
Exemplo n.º 20
0
def main(unused_argv):

    tf.logging.set_verbosity(tf.logging.INFO)

    query_image_paths = _ReadImageList(cmd_args.query_list_images_path)
    train_image_paths = _ReadImageList(cmd_args.train_list_images_path)

    output_fh = open(cmd_args.output_file, 'w')

    for query in query_image_paths:
        # Read features.
        locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(query)
        num_features_1 = locations_1.shape[0]
        #tf.logging.info("Loaded image 1's %d features" % num_features_1)

        best_f = ""
        best_inliers = 0
        for train in train_image_paths:

            locations_2, _, descriptors_2, _, _ = feature_io.ReadFromFile(
                train)
            num_features_2 = locations_2.shape[0]
            #tf.logging.info("Loaded image 2's %d features" % num_features_2)

            # Find nearest-neighbor matches using a KD tree.
            d1_tree = cKDTree(descriptors_1)
            _, indices = d1_tree.query(
                descriptors_2, distance_upper_bound=_DISTANCE_THRESHOLD)

            # Select feature locations for putative matches.
            locations_2_to_use = np.array([
                locations_2[i, ] for i in range(num_features_2)
                if indices[i] != num_features_1
            ])
            locations_1_to_use = np.array([
                locations_1[indices[i], ] for i in range(num_features_2)
                if indices[i] != num_features_1
            ])

            # Perform geometric verification using RANSAC.
            try:
                _, inliers = ransac((locations_1_to_use, locations_2_to_use),
                                    AffineTransform,
                                    min_samples=3,
                                    residual_threshold=20,
                                    max_trials=100)

                sum_inliers = sum(inliers)
                if (sum_inliers > best_inliers):
                    best_inliers = sum_inliers
                    best_label = train

                #print(best_label, train, query)
            except:
                continue

            #print(best_label, train, query)

            #tf.logging.info('Found %d inliers' % sum(inliers))
        if (best_inliers > 20):
            output_fh.write(query.split('data/query_features/')[1]\
              + ","+best_label.split('data/train_features/')[1]+"\n")
        else:
            output_fh.write(query + "\n")

    output_fh.close()
def _RerankByGeometricVerification(input_ranks, initial_scores, query_name,
                                   index_names, query_features_dir,
                                   index_features_dir, junk_ids):
    """Re-ranks retrieval results using geometric verification.

  Args:
    input_ranks: 1D NumPy array with indices of top-ranked index images, sorted
      from the most to the least similar.
    initial_scores: 1D NumPy array with initial similarity scores between query
      and index images. Entry i corresponds to score for image i.
    query_name: Name for query image (string).
    index_names: List of names for index images (strings).
    query_features_dir: Directory where query local feature file is located
      (string).
    index_features_dir: Directory where index local feature files are located
      (string).
    junk_ids: Set with indices of junk images which should not be considered
      during re-ranking.

  Returns:
    output_ranks: 1D NumPy array with index image indices, sorted from the most
      to the least similar according to the geometric verification and initial
      scores.

  Raises:
    ValueError: If `input_ranks`, `initial_scores` and `index_names` do not have
      the same number of entries.
  """
    num_index_images = len(index_names)
    if len(input_ranks) != num_index_images:
        raise ValueError(
            'input_ranks and index_names have different number of '
            'elements: %d vs %d' % (len(input_ranks), len(index_names)))
    if len(initial_scores) != num_index_images:
        raise ValueError(
            'initial_scores and index_names have different number of '
            'elements: %d vs %d' % (len(initial_scores), len(index_names)))

    # Filter out junk images from list that will be re-ranked.
    input_ranks_for_gv = []
    for ind in input_ranks:
        if ind not in junk_ids:
            input_ranks_for_gv.append(ind)
    num_to_rerank = min(_NUM_TO_RERANK, len(input_ranks_for_gv))

    # Load query image features.
    query_features_path = os.path.join(query_features_dir,
                                       query_name + _DELF_EXTENSION)
    query_locations, _, query_descriptors, _, _ = feature_io.ReadFromFile(
        query_features_path)

    # Initialize list containing number of inliers and initial similarity scores.
    inliers_and_initial_scores = []
    for i in range(num_index_images):
        inliers_and_initial_scores.append([0, initial_scores[i]])

    # Loop over top-ranked images and get results.
    print('Starting to re-rank')
    for i in range(num_to_rerank):
        if i > 0 and i % _STATUS_CHECK_GV_ITERATIONS == 0:
            print('Re-ranking: i = %d out of %d' % (i, num_to_rerank))

        index_image_id = input_ranks_for_gv[i]

        # Load index image features.
        index_image_features_path = os.path.join(
            index_features_dir, index_names[index_image_id] + _DELF_EXTENSION)
        (index_image_locations, _, index_image_descriptors, _,
         _) = feature_io.ReadFromFile(index_image_features_path)

        inliers_and_initial_scores[index_image_id][0] = _MatchFeatures(
            query_locations, query_descriptors, index_image_locations,
            index_image_descriptors)

    # Sort based on (inliers_score, initial_score).
    def _InliersInitialScoresSorting(k):
        """Helper function to sort list based on two entries.

    Args:
      k: Index into `inliers_and_initial_scores`.

    Returns:
      Tuple containing inlier score and initial score.
    """
        return (inliers_and_initial_scores[k][0],
                inliers_and_initial_scores[k][1])

    output_ranks = sorted(range(num_index_images),
                          key=_InliersInitialScoresSorting,
                          reverse=True)

    return output_ranks
Exemplo n.º 22
0
_DISTANCE_THRESHOLD = 0.8
_INLIER_THRESHOLD = 30

tf.logging.set_verbosity(tf.logging.INFO)

features_output_dir = '/media/iap205/Data4T/Export_temp/GLD-v2_DELF_features'

for i in range(ranks.shape[1]):
    # Read features.
    features_1_path = os.path.join(features_output_dir,
                                   df_train['id'][query_idx[i]] + '.delf')
    image_1_path = os.path.join(
        train_img_path, '/'.join(list(df_train['id'][query_idx[i]])[:3]),
        df_train['id'][query_idx[i]] + '.jpg')
    locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(
        features_1_path)
    num_features_1 = locations_1.shape[0]
    # tf.logging.info("Loaded qurey image {}'s %d features".format(i) % num_features_1)
    d1_tree = spatial.cKDTree(descriptors_1)
    img_1 = mpimg.imread(image_1_path)
    for j in range(ranks.shape[0]):
        features_2_path = os.path.join(features_output_dir,
                                       knn_imgs[j] + '.delf')
        image_2_path = os.path.join(train_img_path,
                                    '/'.join(list(knn_imgs[j])[:3]),
                                    knn_imgs[j] + '.jpg')
        locations_2, _, descriptors_2, _, _ = feature_io.ReadFromFile(
            features_2_path)
        num_features_2 = locations_2.shape[0]
        # tf.logging.info("Loaded image 2's %d features" % num_features_2)
Exemplo n.º 23
0
def main(unused_argv):
    # Read features.
    locations_1, _, descriptors_1, _, _ = feature_io.ReadFromFile(
        cmd_args.features_1_path)
    num_features_1 = locations_1.shape[0]
    print(f"Loaded image 1's {num_features_1} features")
    locations_2, _, descriptors_2, _, _ = feature_io.ReadFromFile(
        cmd_args.features_2_path)
    num_features_2 = locations_2.shape[0]
    print(f"Loaded image 2's {num_features_2} features")

    # Find nearest-neighbor matches using a KD tree.
    d1_tree = spatial.cKDTree(descriptors_1)
    _, indices = d1_tree.query(descriptors_2,
                               distance_upper_bound=_DISTANCE_THRESHOLD)

    # Select feature locations for putative matches.
    locations_2_to_use = np.array([
        locations_2[i, ] for i in range(num_features_2)
        if indices[i] != num_features_1
    ])
    locations_1_to_use = np.array([
        locations_1[indices[i], ] for i in range(num_features_2)
        if indices[i] != num_features_1
    ])

    # Perform geometric verification using RANSAC.
    _, inliers = measure.ransac((locations_1_to_use, locations_2_to_use),
                                transform.AffineTransform,
                                min_samples=3,
                                residual_threshold=20,
                                max_trials=1000)

    print(f'Found {sum(inliers)} inliers')

    # Visualize correspondences, and save to file.
    _, ax = plt.subplots()

    img1_ext = os.path.splitext(cmd_args.image_1_path)[1]
    if img1_ext == '.exr':
        img_1 = (utils.loadEXRImage(cmd_args.image_1_path))
        img_1_min = np.min(img_1)
        img_1 = ((img_1 - img_1_min) / (np.max(img_1) - img_1_min))
    else:
        img_1 = mpimg.imread(cmd_args.image_1_path)
    img2_ext = os.path.splitext(cmd_args.image_2_path)[1]
    if img2_ext == '.exr':
        img_2 = (utils.loadEXRImage(cmd_args.image_2_path))
        print("max", np.max(img_2))
        img_2_min = np.min(img_2)
        img_2 = ((img_2 - img_2_min) / (np.max(img_2) - img_2_min))
    else:
        img_2 = mpimg.imread(cmd_args.image_2_path)

    inlier_idxs = np.nonzero(inliers)[0]
    feature.plot_matches(ax,
                         img_1[:, :, :3],
                         img_2[:, :, :3],
                         locations_1_to_use,
                         locations_2_to_use,
                         np.column_stack((inlier_idxs, inlier_idxs)),
                         matches_color='b',
                         only_matches=False)
    ax.axis('off')
    ax.set_title('DELF correspondences')
    plt.savefig(cmd_args.output_image, dpi=600)
    # Perform geometric verification using RANSAC.
    _, inliers = ransac((locations_2_to_use, locations_1_to_use),
                        AffineTransform,
                        min_samples=3,
                        residual_threshold=20,
                        max_trials=1000)
    if type(inliers) == type(None):
        return 3
    #tf.logging.info('Found %d inliers' % sum(inliers))
    return sum(inliers)


if __name__ == '__main__':

    features_1_path = "test_features/1.delf"
    features_2_path = "test_features/2.delf"
    # Read features.
    locations_1, features_out_1, descriptors_1, attention_out_1, _ = feature_io.ReadFromFile(
        features_1_path)
    num_features_1 = locations_1.shape[0]
    tf.logging.info("Loaded image 1's %d features" % num_features_1)
    locations_2, features_out_2, descriptors_2, attention_out_2, _ = feature_io.ReadFromFile(
        features_2_path)
    num_features_2 = locations_2.shape[0]
    tf.logging.info("Loaded image 2's %d features" % num_features_2)
    # evaluate_similarity(locations_1, descriptors_1, locations_2, descriptors_2)
    print(locations_1.shape)
    print(features_out_1)
    print(descriptors_1.shape)
    print(attention_out_1)
Exemplo n.º 25
0
    if n%1000 == 0:
        print(n/len(l)*100)
    n += 1
	
# Here I extract DELF features from the images

l = os.listdir(TRAIN_IMAGE_DIR)

for i in range(0, len(l),RESET):
    with open('list_images.txt', 'w') as f:
        [f.write(os.path.join(os.getcwd(), TRAIN_IMAGE_DIR, file)+'\n') for file in l[i:i+RESET]]
    p = mp.Process(target=fetex, args=(TRAIN_FET_DIR,))
    p.start()
    p.join()
    for file in l[i:i+RESET]:
        _, _, desc, _, _ = feature_io.ReadFromFile(TRAIN_FET_DIR+'/'+file.split('.')[0]+'.delf')
        np.save(TRAIN_FET_DIR+'/'+file.split('.')[0]+'.npy', desc)
		
# Next, loaded the features of all images into a spark rdd. This takes a long time

findspark.init()

conf = SparkConf().setAppName("App")
conf = (conf.setMaster('local[*]')
        .set('spark.executor.memory', '1G')
        .set('spark.driver.memory', '12G'))
sc = SparkContext(conf=conf)

spark = SparkSession \
    .builder \
    .appName("Python Spark SQL basic example") \
Exemplo n.º 26
0
 def DelfReadSingleImage(self, features_path=None):
     locations, _, descriptors, _, _ = feature_io.ReadFromFile(
         features_path)
     name = features_path.split('/')[-1]
     name = name.split('.')[0]
     return (name, locations, descriptors)
def RerankByGeometricVerification(input_ranks,
                                  initial_scores,
                                  query_name,
                                  index_names,
                                  query_features_dir,
                                  index_features_dir,
                                  junk_ids,
                                  local_feature_type='delf',
                                  local_feature_extension=_DELF_EXTENSION,
                                  ransac_seed=None,
                                  descriptor_matching_threshold=0.9,
                                  ransac_residual_threshold=10.0,
                                  use_ratio_test=False):
    """Re-ranks retrieval results using geometric verification.

  Args:
    input_ranks: 1D NumPy array with indices of top-ranked index images, sorted
      from the most to the least similar.
    initial_scores: 1D NumPy array with initial similarity scores between query
      and index images. Entry i corresponds to score for image i.
    query_name: Name for query image (string).
    index_names: List of names for index images (strings).
    query_features_dir: Directory where query local feature file is located
      (string).
    index_features_dir: Directory where index local feature files are located
      (string).
    junk_ids: Set with indices of junk images which should not be considered
      during re-ranking.
    local_feature_extension: String, extension to use for loading local feature
      files.
    ransac_seed: Seed used by RANSAC. If None (default), no seed is provided.
    descriptor_matching_threshold: Threshold used for local descriptor matching.
    ransac_residual_threshold: Residual error threshold for considering matches
      as inliers, used in RANSAC algorithm.
    use_ratio_test: If True, descriptor matching is performed via ratio test,
      instead of distance-based threshold.

  Returns:
    output_ranks: 1D NumPy array with index image indices, sorted from the most
      to the least similar according to the geometric verification and initial
      scores.

  Raises:
    ValueError: If `input_ranks`, `initial_scores` and `index_names` do not have
      the same number of entries.
  """
    num_index_images = len(index_names)
    if len(input_ranks) != num_index_images:
        raise ValueError(
            'input_ranks and index_names have different number of '
            'elements: %d vs %d' % (len(input_ranks), len(index_names)))
    if len(initial_scores) != num_index_images:
        raise ValueError(
            'initial_scores and index_names have different number of '
            'elements: %d vs %d' % (len(initial_scores), len(index_names)))

    # Filter out junk images from list that will be re-ranked.
    input_ranks_for_gv = []
    for ind in input_ranks:
        if ind not in junk_ids:
            input_ranks_for_gv.append(ind)
    num_to_rerank = min(_NUM_TO_RERANK, len(input_ranks_for_gv))
    print("Rerank ", num_to_rerank, " instances")

    # Load query image features.
    query_features_path = os.path.join(query_features_dir,
                                       query_name + local_feature_extension)
    if local_feature_type == 'delf':
        query_locations, _, query_descriptors, _, _ = feature_io.ReadFromFile(
            query_features_path)
        print("Shape of query_locations and query_descriptors",
              query_locations.shape, query_descriptors.shape)
    else:
        data = np.load(query_features_path)
        query_locations = data['keypoint'].reshape(data['keypoint'].shape[0],
                                                   2)
        query_descriptors = data['feature']
        print("Shape of query_locations and query_descriptors",
              query_locations.shape, query_descriptors.shape)

    # Initialize list containing number of inliers and initial similarity scores.
    inliers_and_initial_scores = []
    for i in range(num_index_images):
        inliers_and_initial_scores.append([0, initial_scores[i]])

    # Loop over top-ranked images and get results.
    print('Starting to re-rank')
    for i in range(num_to_rerank):
        if i > 0 and i % _STATUS_CHECK_GV_ITERATIONS == 0:
            print('Re-ranking: i = %d out of %d' % (i, num_to_rerank))

        index_image_id = input_ranks_for_gv[i]

        # Load index image features.
        index_image_features_path = os.path.join(
            index_features_dir,
            index_names[index_image_id] + local_feature_extension)
        # (index_image_locations, _, index_image_descriptors, _,
        #  _) = feature_io.ReadFromFile(index_image_features_path)
        data = np.load(query_features_path)
        index_image_locations = data['keypoint'].reshape(
            data['keypoint'].shape[0], 2)
        index_image_descriptors = data['feature']

        inliers_and_initial_scores[index_image_id][0], _ = MatchFeatures(
            query_locations,
            query_descriptors,
            index_image_locations,
            index_image_descriptors,
            ransac_seed=ransac_seed,
            descriptor_matching_threshold=descriptor_matching_threshold,
            ransac_residual_threshold=ransac_residual_threshold,
            use_ratio_test=use_ratio_test)

    # Sort based on (inliers_score, initial_score).
    def _InliersInitialScoresSorting(k):
        """Helper function to sort list based on two entries.

    Args:
      k: Index into `inliers_and_initial_scores`.

    Returns:
      Tuple containing inlier score and initial score.
    """
        return (inliers_and_initial_scores[k][0],
                inliers_and_initial_scores[k][1])

    output_ranks = sorted(range(num_index_images),
                          key=_InliersInitialScoresSorting,
                          reverse=True)

    return output_ranks
Exemplo n.º 28
0
def main(argv):
    if len(argv) > 1:
        raise RuntimeError('Too many command-line arguments.')

    # Read list of images from dataset file.
    print('Reading list of images from dataset file...')
    query_list, index_list, _ = dataset.ReadDatasetFile(
        cmd_args.dataset_file_path)
    if cmd_args.use_query_images:
        image_list = query_list
    else:
        image_list = index_list
    num_images = len(image_list)
    print('done! Found %d images' % num_images)

    # Parse AggregationConfig proto, and select output extension.
    config = aggregation_config_pb2.AggregationConfig()
    with tf.gfile.GFile(cmd_args.aggregation_config_path, 'r') as f:
        text_format.Merge(f.read(), config)
    output_extension = '.'
    if config.use_regional_aggregation:
        output_extension += 'r'
    if config.aggregation_type == _VLAD:
        output_extension += _VLAD_EXTENSION_SUFFIX
    elif config.aggregation_type == _ASMK:
        output_extension += _ASMK_EXTENSION_SUFFIX
    elif config.aggregation_type == _ASMK_STAR:
        output_extension += _ASMK_STAR_EXTENSION_SUFFIX
    else:
        raise ValueError('Invalid aggregation type: %d' %
                         config.aggregation_type)

    # Read index mapping path, if provided.
    if cmd_args.index_mapping_path:
        images_to_box_feature_files = _ReadMappingBasenameToBoxNames(
            cmd_args.index_mapping_path, image_list)

    # Create output directory if necessary.
    if not os.path.exists(cmd_args.output_aggregation_dir):
        os.makedirs(cmd_args.output_aggregation_dir)

    with tf.Session() as sess:
        extractor = feature_aggregation_extractor.ExtractAggregatedRepresentation(
            sess, config)

        start = time.clock()
        for i in range(num_images):
            if i == 0:
                print('Starting to extract aggregation from images...')
            elif i % _STATUS_CHECK_ITERATIONS == 0:
                elapsed = (time.clock() - start)
                print('Processing image %d out of %d, last %d '
                      'images took %f seconds' %
                      (i, num_images, _STATUS_CHECK_ITERATIONS, elapsed))
                start = time.clock()

            image_name = image_list[i]

            # Compose output file name, skip extraction for this image if it already
            # exists.
            output_aggregation_filename = os.path.join(
                cmd_args.output_aggregation_dir, image_name + output_extension)
            if tf.io.gfile.exists(output_aggregation_filename):
                print('Skipping %s' % image_name)
                continue

            # Load DELF features.
            if config.use_regional_aggregation:
                if not cmd_args.index_mapping_path:
                    raise ValueError(
                        'Requested regional aggregation, but index_mapping_path was not '
                        'provided')
                descriptors_list = []
                num_features_per_box = []
                for box_feature_file in images_to_box_feature_files[
                        image_name]:
                    delf_filename = os.path.join(
                        cmd_args.features_dir,
                        box_feature_file + _DELF_EXTENSION)
                    _, _, box_descriptors, _, _ = feature_io.ReadFromFile(
                        delf_filename)
                    # If `box_descriptors` is empty, reshape it such that it can be
                    # concatenated with other descriptors.
                    if not box_descriptors.shape[0]:
                        box_descriptors = np.reshape(
                            box_descriptors,
                            [0, config.feature_dimensionality])
                    descriptors_list.append(box_descriptors)
                    num_features_per_box.append(box_descriptors.shape[0])

                descriptors = np.concatenate(descriptors_list)
            else:
                input_delf_filename = os.path.join(
                    cmd_args.features_dir, image_name + _DELF_EXTENSION)
                _, _, descriptors, _, _ = feature_io.ReadFromFile(
                    input_delf_filename)
                num_features_per_box = None

            # Extract and save aggregation. If using VLAD, only
            # `aggregated_descriptors` needs to be saved.
            (aggregated_descriptors,
             feature_visual_words) = extractor.Extract(descriptors,
                                                       num_features_per_box)
            if config.aggregation_type == _VLAD:
                datum_io.WriteToFile(aggregated_descriptors,
                                     output_aggregation_filename)
            else:
                datum_io.WritePairToFile(aggregated_descriptors,
                                         feature_visual_words.astype('uint32'),
                                         output_aggregation_filename)