def main(argv): if len(argv) > 1: raise RuntimeError('Too many command-line arguments.') # 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) # Compose list of image paths. image_paths = [ os.path.join(cmd_args.images_dir, index_image_name + _IMAGE_EXTENSION) for index_image_name in index_list ] # Extract boxes/features and save them to files. boxes_and_features_extraction.ExtractBoxesAndFeaturesToFiles( image_names=index_list, image_paths=image_paths, delf_config_path=cmd_args.delf_config_path, detector_model_dir=cmd_args.detector_model_dir, detector_thresh=cmd_args.detector_thresh, output_features_dir=cmd_args.output_features_dir, output_boxes_dir=cmd_args.output_boxes_dir, output_mapping=cmd_args.output_index_mapping)
def main(argv): if len(argv) > 1: raise RuntimeError('Too many command-line arguments.') tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.INFO) # Read list of query images from dataset file. tf.compat.v1.logging.info( 'Reading list of query images and boxes from dataset file...') query_list, _, ground_truth = dataset.ReadDatasetFile( cmd_args.dataset_file_path) num_images = len(query_list) tf.compat.v1.logging.info('done! Found %d images', num_images) # Parse DelfConfig proto. config = delf_config_pb2.DelfConfig() with tf.io.gfile.GFile(cmd_args.delf_config_path, 'r') as f: text_format.Merge(f.read(), config) # Create output directory if necessary. if not tf.io.gfile.exists(cmd_args.output_features_dir): tf.io.gfile.makedirs(cmd_args.output_features_dir) with tf.Graph().as_default(): with tf.compat.v1.Session() as sess: # Initialize variables, construct DELF extractor. init_op = tf.compat.v1.global_variables_initializer() sess.run(init_op) extractor_fn = extractor.MakeExtractor(sess, config) start = time.clock() for i in range(num_images): query_image_name = query_list[i] input_image_filename = os.path.join( cmd_args.images_dir, query_image_name + _IMAGE_EXTENSION) output_feature_filename = os.path.join( cmd_args.output_features_dir, query_image_name + _DELF_EXTENSION) if tf.io.gfile.exists(output_feature_filename): tf.compat.v1.logging.info('Skipping %s', query_image_name) continue # Crop query image according to bounding box. bbox = [int(round(b)) for b in ground_truth[i]['bbx']] im = np.array(_PilLoader(input_image_filename).crop(bbox)) # Extract and save features. (locations_out, descriptors_out, feature_scales_out, attention_out) = extractor_fn(im) feature_io.WriteToFile(output_feature_filename, locations_out, feature_scales_out, descriptors_out, attention_out) elapsed = (time.clock() - start) print('Processed %d query images in %f seconds' % (num_images, elapsed))
def main(argv): if len(argv) > 1: raise RuntimeError('Too many command-line arguments.') # Read list of query images from dataset file. print('Reading list of query images and boxes from dataset file...') query_list, _, ground_truth = dataset.ReadDatasetFile( cmd_args.dataset_file_path) num_images = len(query_list) print(f'done! Found {num_images} images') # Parse DelfConfig proto. config = delf_config_pb2.DelfConfig() with tf.io.gfile.GFile(cmd_args.delf_config_path, 'r') as f: text_format.Merge(f.read(), config) # Create output directory if necessary. if not tf.io.gfile.exists(cmd_args.output_features_dir): tf.io.gfile.makedirs(cmd_args.output_features_dir) extractor_fn = extractor.MakeExtractor(config) start = time.time() for i in range(num_images): query_image_name = query_list[i] input_image_filename = os.path.join( cmd_args.images_dir, query_image_name + _IMAGE_EXTENSION) output_feature_filename = os.path.join( cmd_args.output_features_dir, query_image_name + _DELF_EXTENSION) if tf.io.gfile.exists(output_feature_filename): print(f'Skipping {query_image_name}') continue # Crop query image according to bounding box. bbox = [int(round(b)) for b in ground_truth[i]['bbx']] im = np.array(utils.RgbLoader(input_image_filename).crop(bbox)) # Extract and save features. extracted_features = extractor_fn(im) locations_out = extracted_features['local_features']['locations'] descriptors_out = extracted_features['local_features']['descriptors'] feature_scales_out = extracted_features['local_features']['scales'] attention_out = extracted_features['local_features']['attention'] feature_io.WriteToFile(output_feature_filename, locations_out, feature_scales_out, descriptors_out, attention_out) elapsed = (time.time() - start) print('Processed %d query images in %f seconds' % (num_images, elapsed))
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) aggregation_extraction.ExtractAggregatedRepresentationsToFiles( image_names=image_list, features_dir=cmd_args.features_dir, aggregation_config_path=cmd_args.aggregation_config_path, mapping_path=cmd_args.index_mapping_path, output_aggregation_dir=cmd_args.output_aggregation_dir)
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!')
def main(argv): if len(argv) > 1: raise RuntimeError('Too many command-line arguments.') # Parse dataset to obtain query/index images, and ground-truth. print('Parsing dataset...') query_list, index_list, ground_truth = dataset.ReadDatasetFile( FLAGS.dataset_file_path) num_query_images = len(query_list) num_index_images = len(index_list) (_, medium_ground_truth, hard_ground_truth) = dataset.ParseEasyMediumHardGroundTruth(ground_truth) print('done! Found %d queries and %d index images' % (num_query_images, num_index_images)) # Read global features. query_global_features = _ReadDelgGlobalDescriptors( FLAGS.query_features_dir, query_list) index_global_features = _ReadDelgGlobalDescriptors( FLAGS.index_features_dir, index_list) # Compute similarity between query and index images, potentially re-ranking # with geometric verification. ranks_before_gv = np.zeros([num_query_images, num_index_images], dtype='int32') if FLAGS.use_geometric_verification: medium_ranks_after_gv = np.zeros([num_query_images, num_index_images], dtype='int32') hard_ranks_after_gv = np.zeros([num_query_images, num_index_images], dtype='int32') for i in range(num_query_images): print('Performing retrieval with query %d (%s)...' % (i, query_list[i])) start = time.time() # Compute similarity between global descriptors. similarities = np.dot(index_global_features, query_global_features[i]) ranks_before_gv[i] = np.argsort(-similarities) # Re-rank using geometric verification. if FLAGS.use_geometric_verification: medium_ranks_after_gv[ i] = image_reranking.RerankByGeometricVerification( input_ranks=ranks_before_gv[i], initial_scores=similarities, query_name=query_list[i], index_names=index_list, query_features_dir=FLAGS.query_features_dir, index_features_dir=FLAGS.index_features_dir, junk_ids=set(medium_ground_truth[i]['junk']), local_feature_extension=_DELG_LOCAL_EXTENSION, ransac_seed=0, feature_distance_threshold=FLAGS. local_feature_distance_threshold, ransac_residual_threshold=FLAGS.ransac_residual_threshold) hard_ranks_after_gv[ i] = image_reranking.RerankByGeometricVerification( input_ranks=ranks_before_gv[i], initial_scores=similarities, query_name=query_list[i], index_names=index_list, query_features_dir=FLAGS.query_features_dir, index_features_dir=FLAGS.index_features_dir, junk_ids=set(hard_ground_truth[i]['junk']), local_feature_extension=_DELG_LOCAL_EXTENSION, ransac_seed=0, feature_distance_threshold=FLAGS. local_feature_distance_threshold, ransac_residual_threshold=FLAGS.ransac_residual_threshold) elapsed = (time.time() - start) print('done! Retrieval for query %d took %f seconds' % (i, elapsed)) # Create output directory if necessary. if not tf.io.gfile.exists(FLAGS.output_dir): tf.io.gfile.makedirs(FLAGS.output_dir) # Compute metrics. medium_metrics = dataset.ComputeMetrics(ranks_before_gv, medium_ground_truth, _PR_RANKS) hard_metrics = dataset.ComputeMetrics(ranks_before_gv, hard_ground_truth, _PR_RANKS) if FLAGS.use_geometric_verification: medium_metrics_after_gv = dataset.ComputeMetrics( medium_ranks_after_gv, medium_ground_truth, _PR_RANKS) hard_metrics_after_gv = dataset.ComputeMetrics(hard_ranks_after_gv, hard_ground_truth, _PR_RANKS) # Write metrics to file. mean_average_precision_dict = { 'medium': medium_metrics[0], 'hard': hard_metrics[0] } mean_precisions_dict = { 'medium': medium_metrics[1], 'hard': hard_metrics[1] } mean_recalls_dict = {'medium': medium_metrics[2], 'hard': hard_metrics[2]} if FLAGS.use_geometric_verification: mean_average_precision_dict.update({ 'medium_after_gv': medium_metrics_after_gv[0], 'hard_after_gv': hard_metrics_after_gv[0] }) mean_precisions_dict.update({ 'medium_after_gv': medium_metrics_after_gv[1], 'hard_after_gv': hard_metrics_after_gv[1] }) mean_recalls_dict.update({ 'medium_after_gv': medium_metrics_after_gv[2], 'hard_after_gv': hard_metrics_after_gv[2] }) dataset.SaveMetricsFile(mean_average_precision_dict, mean_precisions_dict, mean_recalls_dict, _PR_RANKS, os.path.join(FLAGS.output_dir, _METRICS_FILENAME))
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, ground_truth = dataset.ReadDatasetFile( FLAGS.dataset_file_path) if FLAGS.image_set == 'query': image_list = query_list else: image_list = index_list num_images = len(image_list) print('done! Found %d images' % num_images) # Parse DelfConfig proto. config = delf_config_pb2.DelfConfig() with tf.io.gfile.GFile(FLAGS.delf_config_path, 'r') as f: text_format.Parse(f.read(), config) # Create output directory if necessary. if not tf.io.gfile.exists(FLAGS.output_features_dir): tf.io.gfile.makedirs(FLAGS.output_features_dir) with tf.Graph().as_default(): with tf.compat.v1.Session() as sess: # Initialize variables, construct DELG extractor. init_op = tf.compat.v1.global_variables_initializer() sess.run(init_op) extractor_fn = extractor.MakeExtractor(sess, config) start = time.time() for i in range(num_images): if i == 0: print('Starting to extract features...') elif i % _STATUS_CHECK_ITERATIONS == 0: elapsed = (time.time() - start) print('Processing image %d out of %d, last %d ' 'images took %f seconds' % (i, num_images, _STATUS_CHECK_ITERATIONS, elapsed)) start = time.time() image_name = image_list[i] input_image_filename = os.path.join( FLAGS.images_dir, image_name + _IMAGE_EXTENSION) # Compose output file name and decide if image should be skipped. should_skip_global = True should_skip_local = True if config.use_global_features: output_global_feature_filename = os.path.join( FLAGS.output_features_dir, image_name + _DELG_GLOBAL_EXTENSION) if not tf.io.gfile.exists(output_global_feature_filename): should_skip_global = False if config.use_local_features: output_local_feature_filename = os.path.join( FLAGS.output_features_dir, image_name + _DELG_LOCAL_EXTENSION) if not tf.io.gfile.exists(output_local_feature_filename): should_skip_local = False if should_skip_global and should_skip_local: print('Skipping %s' % image_name) continue pil_im = utils.RgbLoader(input_image_filename) resize_factor = 1.0 if FLAGS.image_set == 'query': # Crop query image according to bounding box. original_image_size = max(pil_im.size) bbox = [int(round(b)) for b in ground_truth[i]['bbx']] pil_im = pil_im.crop(bbox) cropped_image_size = max(pil_im.size) resize_factor = cropped_image_size / original_image_size im = np.array(pil_im) # Extract and save features. extracted_features = extractor_fn(im, resize_factor) if config.use_global_features: global_descriptor = extracted_features['global_descriptor'] datum_io.WriteToFile(global_descriptor, output_global_feature_filename) if config.use_local_features: locations = extracted_features['local_features'][ 'locations'] descriptors = extracted_features['local_features'][ 'descriptors'] feature_scales = extracted_features['local_features'][ 'scales'] attention = extracted_features['local_features'][ 'attention'] feature_io.WriteToFile(output_local_feature_filename, locations, feature_scales, descriptors, attention)
def main(argv): if len(argv) > 1: raise RuntimeError('Too many command-line arguments.') # Parse dataset to obtain query/index images, and ground-truth. print('Parsing dataset...') query_list, index_list, ground_truth = dataset.ReadDatasetFile( cmd_args.dataset_file_path) num_query_images = len(query_list) num_index_images = len(index_list) (_, medium_ground_truth, hard_ground_truth) = dataset.ParseEasyMediumHardGroundTruth(ground_truth) print('done! Found %d queries and %d index images' % (num_query_images, num_index_images)) # Parse AggregationConfig protos. query_config = aggregation_config_pb2.AggregationConfig() with tf.gfile.GFile(cmd_args.query_aggregation_config_path, 'r') as f: text_format.Merge(f.read(), query_config) index_config = aggregation_config_pb2.AggregationConfig() with tf.gfile.GFile(cmd_args.index_aggregation_config_path, 'r') as f: text_format.Merge(f.read(), index_config) # Read aggregated descriptors. query_aggregated_descriptors, query_visual_words = _ReadAggregatedDescriptors( cmd_args.query_aggregation_dir, query_list, query_config) index_aggregated_descriptors, index_visual_words = _ReadAggregatedDescriptors( cmd_args.index_aggregation_dir, index_list, index_config) # Create similarity computer. similarity_computer = (feature_aggregation_similarity. SimilarityAggregatedRepresentation(index_config)) # Compute similarity between query and index images, potentially re-ranking # with geometric verification. ranks_before_gv = np.zeros([num_query_images, num_index_images], dtype='int32') if cmd_args.use_geometric_verification: medium_ranks_after_gv = np.zeros([num_query_images, num_index_images], dtype='int32') hard_ranks_after_gv = np.zeros([num_query_images, num_index_images], dtype='int32') for i in range(num_query_images): print('Performing retrieval with query %d (%s)...' % (i, query_list[i])) start = time.clock() # Compute similarity between aggregated descriptors. similarities = np.zeros([num_index_images]) for j in range(num_index_images): similarities[j] = similarity_computer.ComputeSimilarity( query_aggregated_descriptors[i], index_aggregated_descriptors[j], query_visual_words[i], index_visual_words[j]) ranks_before_gv[i] = np.argsort(-similarities) # Re-rank using geometric verification. if cmd_args.use_geometric_verification: medium_ranks_after_gv[i] = _RerankByGeometricVerification( ranks_before_gv[i], similarities, query_list[i], index_list, cmd_args.query_features_dir, cmd_args.index_features_dir, set(medium_ground_truth[i]['junk'])) hard_ranks_after_gv[i] = _RerankByGeometricVerification( ranks_before_gv[i], similarities, query_list[i], index_list, cmd_args.query_features_dir, cmd_args.index_features_dir, set(hard_ground_truth[i]['junk'])) elapsed = (time.clock() - start) print('done! Retrieval for query %d took %f seconds' % (i, elapsed)) # Create output directory if necessary. if not tf.gfile.Exists(cmd_args.output_dir): tf.gfile.MakeDirs(cmd_args.output_dir) # Compute metrics. medium_metrics = dataset.ComputeMetrics(ranks_before_gv, medium_ground_truth, _PR_RANKS) hard_metrics = dataset.ComputeMetrics(ranks_before_gv, hard_ground_truth, _PR_RANKS) if cmd_args.use_geometric_verification: medium_metrics_after_gv = dataset.ComputeMetrics( medium_ranks_after_gv, medium_ground_truth, _PR_RANKS) hard_metrics_after_gv = dataset.ComputeMetrics(hard_ranks_after_gv, hard_ground_truth, _PR_RANKS) # Write metrics to file. mean_average_precision_dict = { 'medium': medium_metrics[0], 'hard': hard_metrics[0] } mean_precisions_dict = { 'medium': medium_metrics[1], 'hard': hard_metrics[1] } mean_recalls_dict = {'medium': medium_metrics[2], 'hard': hard_metrics[2]} if cmd_args.use_geometric_verification: mean_average_precision_dict.update({ 'medium_after_gv': medium_metrics_after_gv[0], 'hard_after_gv': hard_metrics_after_gv[0] }) mean_precisions_dict.update({ 'medium_after_gv': medium_metrics_after_gv[1], 'hard_after_gv': hard_metrics_after_gv[1] }) mean_recalls_dict.update({ 'medium_after_gv': medium_metrics_after_gv[2], 'hard_after_gv': hard_metrics_after_gv[2] }) _SaveMetricsFile(mean_average_precision_dict, mean_precisions_dict, mean_recalls_dict, _PR_RANKS, os.path.join(cmd_args.output_dir, _METRICS_FILENAME))
def main(argv): if len(argv) > 1: raise RuntimeError('Too many command-line arguments.') tf.logging.set_verbosity(tf.logging.INFO) # Read list of index images from dataset file. tf.logging.info('Reading list of index images from dataset file...') _, index_list, _ = dataset.ReadDatasetFile(cmd_args.dataset_file_path) num_images = len(index_list) tf.logging.info('done! Found %d images', num_images) # Parse DelfConfig proto. config = delf_config_pb2.DelfConfig() with tf.gfile.GFile(cmd_args.delf_config_path, 'r') as f: text_format.Merge(f.read(), config) # Create output directories if necessary. if not os.path.exists(cmd_args.output_features_dir): os.makedirs(cmd_args.output_features_dir) if not os.path.exists(cmd_args.output_boxes_dir): os.makedirs(cmd_args.output_boxes_dir) index_names_ids_and_boxes = [] with tf.Graph().as_default(): with tf.Session() as sess: # Initialize variables, construct detector and DELF extractor. init_op = tf.global_variables_initializer() sess.run(init_op) detector_fn = extract_boxes.MakeDetector( sess, cmd_args.detector_model_dir, import_scope='detector') delf_extractor_fn = extract_features.MakeExtractor( sess, config, import_scope='extractor_delf') start = time.clock() for i in range(num_images): if i == 0: print( 'Starting to extract features/boxes from index images...' ) elif 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() index_image_name = index_list[i] input_image_filename = os.path.join( cmd_args.images_dir, index_image_name + _IMAGE_EXTENSION) output_feature_filename_whole_image = os.path.join( cmd_args.output_features_dir, index_image_name + _DELF_EXTENSION) output_box_filename = os.path.join( cmd_args.output_boxes_dir, index_image_name + _BOX_EXTENSION) pil_im = _PilLoader(input_image_filename) width, height = pil_im.size # Extract and save boxes. if tf.gfile.Exists(output_box_filename): tf.logging.info('Skipping box computation for %s', index_image_name) (boxes_out, scores_out, class_indices_out ) = box_io.ReadFromFile(output_box_filename) else: (boxes_out, scores_out, class_indices_out) = detector_fn( np.expand_dims(pil_im, 0)) # Using only one image per batch. boxes_out = boxes_out[0] scores_out = scores_out[0] class_indices_out = class_indices_out[0] box_io.WriteToFile(output_box_filename, boxes_out, scores_out, class_indices_out) # Select boxes with scores greater than threshold. Those will be the # ones with extracted DELF features (besides the whole image, whose DELF # features are extracted in all cases). num_delf_files = 1 selected_boxes = [] for box_ind, box in enumerate(boxes_out): if scores_out[box_ind] >= cmd_args.detector_thresh: selected_boxes.append(box) num_delf_files += len(selected_boxes) # Extract and save DELF features. for delf_file_ind in range(num_delf_files): if delf_file_ind == 0: index_box_name = index_image_name output_feature_filename = output_feature_filename_whole_image else: index_box_name = index_image_name + '_' + str( delf_file_ind - 1) output_feature_filename = os.path.join( cmd_args.output_features_dir, index_box_name + _DELF_EXTENSION) index_names_ids_and_boxes.append( [index_box_name, i, delf_file_ind - 1]) if tf.gfile.Exists(output_feature_filename): tf.logging.info('Skipping DELF computation for %s', index_box_name) continue if delf_file_ind >= 1: bbox_for_cropping = selected_boxes[delf_file_ind - 1] bbox_for_cropping_pil_convention = [ int(math.floor(bbox_for_cropping[1] * width)), int(math.floor(bbox_for_cropping[0] * height)), int(math.ceil(bbox_for_cropping[3] * width)), int(math.ceil(bbox_for_cropping[2] * height)) ] pil_cropped_im = pil_im.crop( bbox_for_cropping_pil_convention) im = np.array(pil_cropped_im) else: im = np.array(pil_im) (locations_out, descriptors_out, feature_scales_out, attention_out) = delf_extractor_fn(im) feature_io.WriteToFile(output_feature_filename, locations_out, feature_scales_out, descriptors_out, attention_out) # Save mapping from output DELF name to index image id and box id. _WriteMappingBasenameToIds(index_names_ids_and_boxes, cmd_args.output_index_mapping)
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)