def MakeExtractor(sess, config, import_scope=None): """Creates a function to extract features from an image. Args: sess: TensorFlow session to use. config: DelfConfig proto containing the model configuration. import_scope: Optional scope to use for model. Returns: Function that receives an image and returns features. """ tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], config.model_path, import_scope=import_scope) import_scope_prefix = import_scope + '/' if import_scope is not None else '' input_image = sess.graph.get_tensor_by_name('%sinput_image:0' % import_scope_prefix) input_score_threshold = sess.graph.get_tensor_by_name( '%sinput_abs_thres:0' % import_scope_prefix) input_image_scales = sess.graph.get_tensor_by_name('%sinput_scales:0' % import_scope_prefix) input_max_feature_num = sess.graph.get_tensor_by_name( '%sinput_max_feature_num:0' % import_scope_prefix) boxes = sess.graph.get_tensor_by_name('%sboxes:0' % import_scope_prefix) raw_descriptors = sess.graph.get_tensor_by_name('%sfeatures:0' % import_scope_prefix) feature_scales = sess.graph.get_tensor_by_name('%sscales:0' % import_scope_prefix) attention_with_extra_dim = sess.graph.get_tensor_by_name( '%sscores:0' % import_scope_prefix) attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, config) def ExtractorFn(image): """Receives an image and returns DELF features. Args: image: Uint8 array with shape (height, width 3) containing the RGB image. Returns: Tuple (locations, descriptors, feature_scales, attention) """ return sess.run( [locations, descriptors, feature_scales, attention], feed_dict={ input_image: image, input_score_threshold: config.delf_local_config.score_threshold, input_image_scales: list(config.image_scales), input_max_feature_num: config.delf_local_config.max_feature_num }) return ExtractorFn
def get_single_attention(self, image_file): ''' 从一张图片中提取关键点特征向量 :param image_file: 图片名 :return: 关键点的位置和对应的特征向量 ''' with self.graph.as_default(): image_raw_data = tf.gfile.FastGFile(image_file, 'rb').read() image_tf = tf.image.decode_jpeg(image_raw_data, channels=3) input_image = self.graph.get_tensor_by_name('input_image:0') input_score_threshold = self.graph.get_tensor_by_name( 'input_abs_thres:0') input_image_scales = self.graph.get_tensor_by_name( 'input_scales:0') input_max_feature_num = self.graph.get_tensor_by_name( 'input_max_feature_num:0') boxes = self.graph.get_tensor_by_name('boxes:0') raw_descriptors = self.graph.get_tensor_by_name('features:0') feature_scales = self.graph.get_tensor_by_name('scales:0') attention_with_extra_dim = self.graph.get_tensor_by_name( 'scores:0') attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, self.config) im = self.sess.run(image_tf) # Extract and save features. (locations_out, descriptors_out, feature_scales_out, attention_out) = self.sess.run( [locations, descriptors, feature_scales, attention], feed_dict={ input_image: im, input_score_threshold: self.config.delf_local_config.score_threshold, input_image_scales: list(self.config.image_scales), input_max_feature_num: self.config.delf_local_config.max_feature_num }) return locations_out, descriptors_out, feature_scales_out, attention_out
def MakeExtractor(sess, config, import_scope=None): tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], config.model_path, import_scope=import_scope) import_scope_prefix = (import_scope + '/' if import_scope is not None else '') input_image = sess.graph.get_tensor_by_name('%sinput_image:0' % import_scope_prefix) input_score_threshold = sess.graph.get_tensor_by_name( '%sinput_abs_thres:0' % import_scope_prefix) input_image_scales = sess.graph.get_tensor_by_name('%sinput_scales:0' % import_scope_prefix) input_max_feature_num = sess.graph.get_tensor_by_name( '%sinput_max_feature_num:0' % import_scope_prefix) boxes = sess.graph.get_tensor_by_name('%sboxes:0' % import_scope_prefix) raw_descriptors = sess.graph.get_tensor_by_name('%sfeatures:0' % import_scope_prefix) feature_scales = sess.graph.get_tensor_by_name('%sscales:0' % import_scope_prefix) attention_with_extra_dim = sess.graph.get_tensor_by_name( '%sscores:0' % import_scope_prefix) attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, config) def ExtractorFn(image): return sess.run( [locations, descriptors, feature_scales, attention], feed_dict={ input_image: image, input_score_threshold: config.delf_local_config.score_threshold, # noqa input_image_scales: list(config.image_scales), input_max_feature_num: config.delf_local_config.max_feature_num }) return ExtractorFn
def createFeatures(listpath, configpath, outputpath): # Read list of images. #print ('Reading list of images') image_paths = _ReadImageList(listpath) num_images = len(image_paths) #print ('done! Found %d images', num_images) # Parse DelfConfig proto. config = delf_config_pb2.DelfConfig() with tf.gfile.FastGFile(configpath, 'r') as f: text_format.Merge(f.read(), config) # Create output directory if necessary. if not os.path.exists(outputpath): os.makedirs(outputpath) # Tell TensorFlow that the model will be built into the default Graph. with tf.Graph().as_default(): # Reading list of images. filename_queue = tf.train.string_input_producer(image_paths, shuffle=False) reader = tf.WholeFileReader() _, value = reader.read(filename_queue) image_tf = tf.image.decode_jpeg(value, channels=3) with tf.Session() as sess: # Initialize variables. init_op = tf.global_variables_initializer() sess.run(init_op) # Loading model that will be used. tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], config.model_path) graph = tf.get_default_graph() input_image = graph.get_tensor_by_name('input_image:0') input_score_threshold = graph.get_tensor_by_name('input_abs_thres:0') input_image_scales = graph.get_tensor_by_name('input_scales:0') input_max_feature_num = graph.get_tensor_by_name( 'input_max_feature_num:0') boxes = graph.get_tensor_by_name('boxes:0') raw_descriptors = graph.get_tensor_by_name('features:0') feature_scales = graph.get_tensor_by_name('scales:0') attention_with_extra_dim = graph.get_tensor_by_name('scores:0') attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, config) # Start input enqueue threads. coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=sess, coord=coord) start = clock() for i in range(num_images): # Write to log-info once in a while. if i == 0: print('Starting to extract DELF features from images...') elif i % _STATUS_CHECK_ITERATIONS == 0: elapsed = (clock() - start) #print ('Processing image %d out of %d, last %d ' #'images took %f seconds', i, num_images, #_STATUS_CHECK_ITERATIONS, elapsed) start = clock() # # Get next image. im = sess.run(image_tf) # If descriptor already exists, skip its computation. out_desc_filename = os.path.splitext(os.path.basename( image_paths[i]))[0] + _DELF_EXT out_desc_fullpath = os.path.join(outputpath, out_desc_filename) if tf.gfile.Exists(out_desc_fullpath): #print('Skipping %s', image_paths[i]) continue # Extract and save features. (locations_out, descriptors_out, feature_scales_out, attention_out) = sess.run( [locations, descriptors, feature_scales, attention], feed_dict={ input_image: im, input_score_threshold: config.delf_local_config.score_threshold, input_image_scales: list(config.image_scales), input_max_feature_num: config.delf_local_config.max_feature_num }) feature_io.WriteToFile(out_desc_fullpath, locations_out, feature_scales_out, descriptors_out, attention_out) # Finalize enqueue threads. coord.request_stop() coord.join(threads)
def MakeExtractor(sess, config, import_scope=None): """Creates a function to extract features from an image. Args: sess: TensorFlow session to use. config: DelfConfig proto containing the model configuration. import_scope: Optional scope to use for model. Returns: Function that receives an image and returns features. """ ''' tf.saved_model.loader.load( sess, [tf.saved_model.tag_constants.SERVING], config.model_path, import_scope=import_scope) ''' with tf.gfile.GFile('./static_model/delf_both_white/frozen_graph.pb', 'rb') as f: frozen_graph = tf.GraphDef() frozen_graph.ParseFromString(f.read()) # Now you can create a TensorRT inference graph from your # frozen graph: converter = trt.TrtGraphConverter(input_graph_def=frozen_graph, nodes_blacklist=[ 'global_feature', 'boxes', 'features', 'scales', 'scores' ], precision_mode="FP32", maximum_cached_engines=100, is_dynamic_op=True) #output nodes trt_graph = converter.convert() # Import the TensorRT graph into a new graph and run: output_node = tf.import_graph_def(trt_graph, return_elements=[ 'global_feature', 'boxes', 'features', 'scales', 'scores' ]) import_scope_prefix = import_scope + '/' if import_scope is not None else '' input_image = sess.graph.get_tensor_by_name('%sinput_image:0' % import_scope_prefix) input_score_threshold = sess.graph.get_tensor_by_name( '%sinput_abs_thres:0' % import_scope_prefix) input_image_scales = sess.graph.get_tensor_by_name('%sinput_scales:0' % import_scope_prefix) input_max_feature_num = sess.graph.get_tensor_by_name( '%sinput_max_feature_num:0' % import_scope_prefix) global_feature = sess.graph.get_tensor_by_name('%sglobal_feature:0' % import_scope_prefix) boxes = sess.graph.get_tensor_by_name('%sboxes:0' % import_scope_prefix) raw_descriptors = sess.graph.get_tensor_by_name('%sfeatures:0' % import_scope_prefix) feature_scales = sess.graph.get_tensor_by_name('%sscales:0' % import_scope_prefix) attention_with_extra_dim = sess.graph.get_tensor_by_name( '%sscores:0' % import_scope_prefix) attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, config) def ExtractorFn(image): """Receives an image and returns DELF features. If image is too small, returns empty set of features. Args: image: Uint8 array with shape (height, width, 3) containing the RGB image. Returns: Tuple (locations, descriptors, feature_scales, attention) """ resized_image, scale_factor = ResizeImage(image, config) # If the image is too small, returns empty features. if resized_image.shape[0] < _MIN_HEIGHT or resized_image.shape[ 1] < _MIN_WIDTH: return np.array([]), np.array([]), np.array([]), np.array([]) (global_feature_out, locations_out, descriptors_out, feature_scales_out, attention_out) = sess.run( [ global_feature, locations, descriptors, feature_scales, attention ], feed_dict={ input_image: resized_image, input_score_threshold: config.delf_local_config.score_threshold, input_image_scales: list(config.image_scales), input_max_feature_num: config.delf_local_config.max_feature_num }) rescaled_locations_out = locations_out / scale_factor return (global_feature_out, rescaled_locations_out, descriptors_out, feature_scales_out, attention_out) return ExtractorFn
def __init__(self, config_path): tf.logging.set_verbosity(tf.logging.INFO) # Parse DelfConfig proto. config = delf_config_pb2.DelfConfig() self.config = config with tf.gfile.FastGFile(config_path, 'r') as f: text_format.Merge(f.read(), config) # Tell TensorFlow that the model will be built into the default Graph. with tf.Graph().as_default(): self.byte_value = tf.placeholder(tf.string) self.image_tf = tf.image.decode_jpeg(self.byte_value, channels=3) self.input_image = tf.placeholder(tf.uint8, [None, None, 3]) self.input_score_threshold = tf.placeholder(tf.float32) self.input_image_scales = tf.placeholder(tf.float32, [None]) self.input_max_feature_num = tf.placeholder(tf.int32) model_fn = feature_extractor.BuildModel( 'resnet_v1_50/block3', 'softplus', 'use_l2_normalized_feature', 1) boxes, self.feature_scales, features, scores, self.attention = feature_extractor.ExtractKeypointDescriptor( self.input_image, layer_name='resnet_v1_50/block3', image_scales=self.input_image_scales, iou=1.0, max_feature_num=self.input_max_feature_num, abs_thres=self.input_score_threshold, model_fn=model_fn) ## Optimistic restore. latest_checkpoint = config.model_path + 'variables/variables' variables_to_restore = tf.global_variables() reader = tf.train.NewCheckpointReader(latest_checkpoint) saved_shapes = reader.get_variable_to_shape_map() variable_names_to_restore = [ var.name.split(':')[0] for var in variables_to_restore ] for shape in saved_shapes: if not shape in variable_names_to_restore: print(shape) for var_name in variable_names_to_restore: if not var_name in saved_shapes: print( "WARNING. Saved weight not exists in checkpoint. Init var:", var_name) var_names = sorted([(var.name, var.name.split(':')[0]) for var in variables_to_restore if var.name.split(':')[0] in saved_shapes]) restore_vars = [] with tf.variable_scope('', reuse=True): for var_name, saved_var_name in var_names: try: curr_var = tf.get_variable(saved_var_name) var_shape = curr_var.get_shape().as_list() if var_shape == saved_shapes[saved_var_name]: # print("restore var:", saved_var_name) restore_vars.append(curr_var) except ValueError: print("Ignore due to ValueError on getting var:", saved_var_name) saver = tf.train.Saver(restore_vars) sess = tf.Session() self.sess = sess # Initialize variables. init_op = tf.global_variables_initializer() sess.run(init_op) saver.restore(sess, latest_checkpoint) # # Loading model that will be used. # tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], # config.model_path) graph = tf.get_default_graph() self.attention_score = tf.reshape( scores, [tf.shape(scores)[0]]) # remove extra dim. self.locations, self.descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, features, config)
def get_feature_from_path(image_paths, config_path): """ with filename queue, batch proces. """ tf.logging.set_verbosity(tf.logging.INFO) num_images = len(image_paths) tf.logging.info('done! Found %d images', num_images) # Parse DelfConfig proto. config = delf_config_pb2.DelfConfig() with tf.gfile.FastGFile(config_path, 'r') as f: text_format.Merge(f.read(), config) location_np_list = [] descriptor_np_list = [] feature_scale_np_list = [] attention_np_list = [] # Tell TensorFlow that the model will be built into the default Graph. with tf.Graph().as_default(): # Reading list of images. filename_queue = tf.train.string_input_producer(image_paths, shuffle=False) reader = tf.WholeFileReader() _, value = reader.read(filename_queue) image_tf = tf.image.decode_jpeg(value, channels=3) with tf.Session() as sess: # Initialize variables. init_op = tf.global_variables_initializer() sess.run(init_op) # Loading model that will be used. tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], config.model_path) graph = tf.get_default_graph() input_image = graph.get_tensor_by_name('input_image:0') input_score_threshold = graph.get_tensor_by_name( 'input_abs_thres:0') input_image_scales = graph.get_tensor_by_name('input_scales:0') input_max_feature_num = graph.get_tensor_by_name( 'input_max_feature_num:0') boxes = graph.get_tensor_by_name('boxes:0') raw_descriptors = graph.get_tensor_by_name('features:0') feature_scales = graph.get_tensor_by_name('scales:0') attention_with_extra_dim = graph.get_tensor_by_name('scores:0') attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, config) # Start input enqueue threads. coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=sess, coord=coord) start = time.clock() for i in range(num_images): # Write to log-info once in a while. if i == 0: tf.logging.info( 'Starting to extract DELF features from images...') elif i % _STATUS_CHECK_ITERATIONS == 0: elapsed = (time.clock() - start) tf.logging.info( 'Processing image %d out of %d, last %d ' 'images took %f seconds', i, num_images, _STATUS_CHECK_ITERATIONS, elapsed) start = time.clock() # # Get next image. im = sess.run(image_tf) # Extract and save features. (locations_out, descriptors_out, feature_scales_out, attention_out) = sess.run( [locations, descriptors, feature_scales, attention], feed_dict={ input_image: im, input_score_threshold: config.delf_local_config.score_threshold, input_image_scales: list(config.image_scales), input_max_feature_num: config.delf_local_config.max_feature_num }) location_np_list.append(locations_out) descriptor_np_list.append(descriptors_out) feature_scale_np_list.append(feature_scales_out) attention_np_list.append(attention_out) # Finalize enqueue threads. coord.request_stop() coord.join(threads) return location_np_list, descriptor_np_list, feature_scale_np_list, attention_np_list
def ExtractorFn(image, resize_factor=1.0): """Receives an image and returns DELF global and/or local features. If image is too small, returns empty features. Args: image: Uint8 array with shape (height, width, 3) containing the RGB image. resize_factor: Optional float resize factor for the input image. If given, the maximum and minimum allowed image sizes in the config are scaled by this factor. Returns: extracted_features: A dict containing the extracted global descriptors (key 'global_descriptor' mapping to a [D] float array), and/or local features (key 'local_features' mapping to a dict with keys 'locations', 'descriptors', 'scales', 'attention'). """ resized_image, scale_factors = utils.ResizeImage( image, config, resize_factor=resize_factor) # If the image is too small, returns empty features. if resized_image.shape[0] < _MIN_HEIGHT or resized_image.shape[ 1] < _MIN_WIDTH: extracted_features = {'global_descriptor': np.array([])} if config.use_local_features: extracted_features.update({ 'local_features': { 'locations': np.array([]), 'descriptors': np.array([]), 'scales': np.array([]), 'attention': np.array([]), } }) return extracted_features # Input tensors. image_tensor = tf.convert_to_tensor(resized_image) # Extracted features. extracted_features = {} output = None if config.use_local_features: if hasattr(config, 'is_tf2_exported') and config.is_tf2_exported: predict = model.signatures['serving_default'] output_dict = predict( input_image=image_tensor, input_scales=image_scales_tensor, input_max_feature_num=max_feature_num_tensor, input_abs_thres=score_threshold_tensor) output = [ output_dict['boxes'], output_dict['features'], output_dict['scales'], output_dict['scores'] ] else: output = model(image_tensor, image_scales_tensor, score_threshold_tensor, max_feature_num_tensor) else: output = model(image_tensor, image_scales_tensor) # Post-process extracted features: normalize, PCA (optional), pooling. if config.use_global_features: raw_global_descriptors = output[-1] if config.delf_global_config.image_scales_ind: raw_global_descriptors_selected_scales = tf.gather( raw_global_descriptors, list(config.delf_global_config.image_scales_ind)) else: raw_global_descriptors_selected_scales = raw_global_descriptors global_descriptors_per_scale = feature_extractor.PostProcessDescriptors( raw_global_descriptors_selected_scales, config.delf_global_config.use_pca, global_pca_parameters) unnormalized_global_descriptor = tf.reduce_sum( global_descriptors_per_scale, axis=0, name='sum_pooling') global_descriptor = tf.nn.l2_normalize( unnormalized_global_descriptor, axis=0, name='final_l2_normalization') extracted_features.update({ 'global_descriptor': global_descriptor.numpy(), }) if config.use_local_features: boxes = output[0] raw_local_descriptors = output[1] feature_scales = output[2] attention_with_extra_dim = output[3] attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, local_descriptors = ( feature_extractor.DelfFeaturePostProcessing( boxes, raw_local_descriptors, config.delf_local_config.use_pca, local_pca_parameters)) locations /= scale_factors extracted_features.update({ 'local_features': { 'locations': locations.numpy(), 'descriptors': local_descriptors.numpy(), 'scales': feature_scales.numpy(), 'attention': attention.numpy(), } }) return extracted_features
def main(unused_argv): tf.logging.set_verbosity(tf.logging.INFO) # Read list of images. tf.logging.info('Reading list of images...') image_paths = _ReadImageList(cmd_args.list_images_path) num_images = len(image_paths) tf.logging.info('done! Found %d images', num_images) # Parse DelfConfig proto. config = delf_config_pb2.DelfConfig() with tf.gfile.FastGFile(cmd_args.config_path, 'rb') as f: text_format.Merge(f.read(), config) # Create output directory if necessary. if not os.path.exists(cmd_args.output_dir): os.makedirs(cmd_args.output_dir) # Tell TensorFlow that the model will be built into the default Graph. with tf.Graph().as_default(): # Reading list of images. filename_queue = tf.train.string_input_producer(image_paths, shuffle=False) reader = tf.WholeFileReader() _, value = reader.read(filename_queue) image_tf = tf.image.decode_jpeg(value, channels=3) with tf.Session() as sess: # Initialize variables. init_op = tf.global_variables_initializer() sess.run(init_op) # Loading model that will be used. tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], config.model_path) graph = tf.get_default_graph() input_image = graph.get_tensor_by_name('input_image:0') input_score_threshold = graph.get_tensor_by_name( 'input_abs_thres:0') input_image_scales = graph.get_tensor_by_name('input_scales:0') input_max_feature_num = graph.get_tensor_by_name( 'input_max_feature_num:0') boxes = graph.get_tensor_by_name('boxes:0') raw_descriptors = graph.get_tensor_by_name('features:0') feature_scales = graph.get_tensor_by_name('scales:0') attention_with_extra_dim = graph.get_tensor_by_name('scores:0') attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, config) # Start input enqueue threads. coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=sess, coord=coord) start = time.clock() for i in range(num_images): # Write to log-info once in a while. if i == 0: tf.logging.info( 'Starting to extract DELF features from images...') elif i % _STATUS_CHECK_ITERATIONS == 0: elapsed = (time.clock() - start) tf.logging.info( 'Processing image %d out of %d, last %d ' 'images took %f seconds', i, num_images, _STATUS_CHECK_ITERATIONS, elapsed) start = time.clock() # # Get next image. im = sess.run(image_tf) # If descriptor already exists, skip its computation. out_desc_filename = os.path.splitext( os.path.basename(image_paths[i]))[0] + _DELF_EXT out_desc_fullpath = os.path.join(cmd_args.output_dir, out_desc_filename) if tf.gfile.Exists(out_desc_fullpath): tf.logging.info('Skipping %s', image_paths[i]) continue feed_dict = { input_image: im, input_score_threshold: config.delf_local_config.score_threshold, input_image_scales: list(config.image_scales), input_max_feature_num: config.delf_local_config.max_feature_num } options = tf.RunOptions(trace_level=tf.RunOptions.FULL_TRACE) run_metadata = tf.RunMetadata() # Extract and save features. (locations_out, descriptors_out, feature_scales_out, attention_out) = sess.run( [locations, descriptors, feature_scales, attention], feed_dict=feed_dict, options=options, run_metadata=run_metadata) cg = CompGraph('delf_extract_features', run_metadata, tf.get_default_graph()) cg_tensor_dict = cg.get_tensors() cg_sorted_keys = sorted(cg_tensor_dict.keys()) cg_sorted_items = [] for cg_key in cg_sorted_keys: cg_sorted_items.append(cg_tensor_dict[cg_key].shape) #cg_sorted_shape = sess.run(cg_sorted_items, feed_dict=feed_dict) cg.op_analysis(dict(zip(cg_sorted_keys, cg_sorted_items)), 'delf_extract_features.pickle') serialized_desc = feature_io.WriteToFile( out_desc_fullpath, locations_out, feature_scales_out, descriptors_out, attention_out) # Finalize enqueue threads. coord.request_stop() coord.join(threads)
def main(*args): args = parse_args() print('delf.main: args=', vars(args), file=sys.stderr) image_paths = [path.rstrip() for path in sys.stdin] # Config config = delf_config_pb2.DelfConfig() with tf.gfile.FastGFile(args.config_path, 'r') as f: text_format.Merge(f.read(), config) with tf.Graph().as_default(): # -- # IO filename_queue = tf.train.string_input_producer(image_paths, shuffle=False) reader = tf.WholeFileReader() _, value = reader.read(filename_queue) image_tf = tf.image.decode_jpeg(value, channels=3) with tf.Session() as sess: # -- # Define graph init_op = tf.global_variables_initializer() sess.run(init_op) tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], os.path.expanduser(config.model_path)) graph = tf.get_default_graph() input_image = graph.get_tensor_by_name('input_image:0') input_score_threshold = graph.get_tensor_by_name('input_abs_thres:0') input_image_scales = graph.get_tensor_by_name('input_scales:0') input_max_feature_num = graph.get_tensor_by_name('input_max_feature_num:0') boxes = graph.get_tensor_by_name('boxes:0') raw_descriptors = graph.get_tensor_by_name('features:0') feature_scales = graph.get_tensor_by_name('scales:0') attention_with_extra_dim = graph.get_tensor_by_name('scores:0') attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing(boxes, raw_descriptors, config) coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=sess, coord=coord) # -- # Run on images for image_path in tqdm(image_paths): if args.hash_filenames: outpath = md5(image_path).hexdigest() else: outpath = os.path.splitext(os.path.basename(image_path))[0] outpath = os.path.join(args.output_dir, outpath + '.delf') img = sess.run(image_tf) print(json.dumps({"path" : image_path, "key" : outpath})) sys.stdout.flush() # Extract and save features. (locations_out, descriptors_out, feature_scales_out, attention_out) = sess.run( [locations, descriptors, feature_scales, attention], feed_dict={ input_image : img, input_score_threshold : config.delf_local_config.score_threshold, input_image_scales : list(config.image_scales), input_max_feature_num : config.delf_local_config.max_feature_num }) if not args.to_h5: _ = feature_io.WriteToFile(outpath, locations_out, feature_scales_out, descriptors_out, attention_out) else: raise Exception('delf.__main__.py: not implemented yet') coord.request_stop() coord.join(threads)
def get_attention(self, list_images_path, output_dir): ''' 从一组图片中提取出关键点特征到文件中 :param list_images_path: 图片列表的存储路径 :param output_dir: 输出文件夹 :return: ''' # Read list of images. tf.logging.info('Reading list of images...') image_paths = _ReadImageList(list_images_path) num_images = len(image_paths) tf.logging.info('done! Found %d images', num_images) # Create output directory if necessary. if not os.path.exists(output_dir): os.makedirs(output_dir) with self.graph.as_default(): # Reading list of images. filename_queue = tf.train.string_input_producer(image_paths, shuffle=False) reader = tf.WholeFileReader() _, value = reader.read(filename_queue) image_tf = tf.image.decode_jpeg(value, channels=3) input_image = self.graph.get_tensor_by_name('input_image:0') input_score_threshold = self.graph.get_tensor_by_name( 'input_abs_thres:0') input_image_scales = self.graph.get_tensor_by_name( 'input_scales:0') input_max_feature_num = self.graph.get_tensor_by_name( 'input_max_feature_num:0') boxes = self.graph.get_tensor_by_name('boxes:0') raw_descriptors = self.graph.get_tensor_by_name('features:0') feature_scales = self.graph.get_tensor_by_name('scales:0') attention_with_extra_dim = self.graph.get_tensor_by_name( 'scores:0') attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, self.config) # Start input enqueue threads. coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=self.sess, coord=coord) start = time.clock() for i in range(num_images): # Write to log-info once in a while. if i == 0: tf.logging.info( 'Starting to extract DELF features from images...') elif i % _STATUS_CHECK_ITERATIONS == 0: elapsed = (time.clock() - start) tf.logging.info( 'Processing image %d out of %d, last %d ' 'images took %f seconds', i, num_images, _STATUS_CHECK_ITERATIONS, elapsed) start = time.clock() # # Get next image. im = self.sess.run(image_tf) # If descriptor already exists, skip its computation. out_desc_filename = os.path.splitext( os.path.basename(image_paths[i]))[0] + _DELF_EXT out_desc_fullpath = os.path.join(cmd_args.output_dir, out_desc_filename) if tf.gfile.Exists(out_desc_fullpath): tf.logging.info('Skipping %s', image_paths[i]) continue # Extract and save features. (locations_out, descriptors_out, feature_scales_out, attention_out) = self.sess.run( [locations, descriptors, feature_scales, attention], feed_dict={ input_image: im, input_score_threshold: self.config.delf_local_config.score_threshold, input_image_scales: list(self.config.image_scales), input_max_feature_num: self.config.delf_local_config.max_feature_num }) feature_io.WriteToFile(out_desc_fullpath, locations_out, feature_scales_out, descriptors_out, attention_out) # Finalize enqueue threads. coord.request_stop() coord.join(threads)
def MakeExtractor(sess, config, import_scope=None): """Creates a function to extract global and/or local features from an image. Args: sess: TensorFlow session to use. config: DelfConfig proto containing the model configuration. import_scope: Optional scope to use for model. Returns: Function that receives an image and returns features. """ # Load model. tf.compat.v1.saved_model.loader.load( sess, [tf.compat.v1.saved_model.tag_constants.SERVING], config.model_path, import_scope=import_scope) import_scope_prefix = import_scope + '/' if import_scope is not None else '' # Input tensors. input_image = sess.graph.get_tensor_by_name('%sinput_image:0' % import_scope_prefix) input_image_scales = sess.graph.get_tensor_by_name('%sinput_scales:0' % import_scope_prefix) if config.use_local_features: input_score_threshold = sess.graph.get_tensor_by_name( '%sinput_abs_thres:0' % import_scope_prefix) input_max_feature_num = sess.graph.get_tensor_by_name( '%sinput_max_feature_num:0' % import_scope_prefix) # Output tensors. if config.use_global_features: raw_global_descriptors = sess.graph.get_tensor_by_name( '%sglobal_descriptors:0' % import_scope_prefix) if config.use_local_features: boxes = sess.graph.get_tensor_by_name('%sboxes:0' % import_scope_prefix) raw_local_descriptors = sess.graph.get_tensor_by_name('%sfeatures:0' % import_scope_prefix) feature_scales = sess.graph.get_tensor_by_name('%sscales:0' % import_scope_prefix) attention_with_extra_dim = sess.graph.get_tensor_by_name( '%sscores:0' % import_scope_prefix) # Post-process extracted features: normalize, PCA (optional), pooling. if config.use_global_features: if config.delf_global_config.image_scales_ind: raw_global_descriptors_selected_scales = tf.gather( raw_global_descriptors, list(config.delf_global_config.image_scales_ind)) else: raw_global_descriptors_selected_scales = raw_global_descriptors global_descriptors_per_scale = feature_extractor.PostProcessDescriptors( raw_global_descriptors_selected_scales, config.delf_global_config.use_pca, config.delf_global_config.pca_parameters) unnormalized_global_descriptor = tf.reduce_sum( global_descriptors_per_scale, axis=0, name='sum_pooling') global_descriptor = tf.nn.l2_normalize( unnormalized_global_descriptor, axis=0, name='final_l2_normalization') if config.use_local_features: attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, local_descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_local_descriptors, config) def ExtractorFn(image, resize_factor=1.0): """Receives an image and returns DELF global and/or local features. If image is too small, returns empty features. Args: image: Uint8 array with shape (height, width, 3) containing the RGB image. resize_factor: Optional float resize factor for the input image. If given, the maximum and minimum allowed image sizes in the config are scaled by this factor. Returns: extracted_features: A dict containing the extracted global descriptors (key 'global_descriptor' mapping to a [D] float array), and/or local features (key 'local_features' mapping to a dict with keys 'locations', 'descriptors', 'scales', 'attention'). """ resized_image, scale_factors = ResizeImage( image, config, resize_factor=resize_factor) # If the image is too small, returns empty features. if resized_image.shape[0] < _MIN_HEIGHT or resized_image.shape[ 1] < _MIN_WIDTH: extracted_features = {'global_descriptor': np.array([])} if config.use_local_features: extracted_features.update({ 'local_features': { 'locations': np.array([]), 'descriptors': np.array([]), 'scales': np.array([]), 'attention': np.array([]), } }) return extracted_features feed_dict = { input_image: resized_image, input_image_scales: list(config.image_scales), } fetches = {} if config.use_global_features: fetches.update({ 'global_descriptor': global_descriptor, }) if config.use_local_features: feed_dict.update({ input_score_threshold: config.delf_local_config.score_threshold, input_max_feature_num: config.delf_local_config.max_feature_num, }) fetches.update({ 'local_features': { 'locations': locations, 'descriptors': local_descriptors, 'scales': feature_scales, 'attention': attention, } }) extracted_features = sess.run(fetches, feed_dict=feed_dict) # Adjust local feature positions due to rescaling. if config.use_local_features: extracted_features['local_features']['locations'] /= scale_factors return extracted_features return ExtractorFn
def main(unused_argv): tf.logging.set_verbosity(tf.logging.INFO) # Read list of images. tf.logging.info('Reading list of images...') image_paths = _ReadImageList(cmd_args.list_images_path) num_images = len(image_paths) tf.logging.info('done! Found %d images', num_images) # Parse DelfConfig proto. config = delf_config_pb2.DelfConfig() with tf.gfile.FastGFile(cmd_args.config_path, 'r') as f: text_format.Merge(f.read(), config) # Create output directory if necessary. if not os.path.exists(cmd_args.output_dir): os.makedirs(cmd_args.output_dir) # Tell TensorFlow that the model will be built into the default Graph. with tf.Graph().as_default(): # Reading list of images. filename_queue = tf.train.string_input_producer(image_paths, shuffle=False) print("PRINTING THE fileNAME QUEUE", filename_queue) reader = tf.WholeFileReader() print("PRINTING THE reader", reader) _, value = reader.read(filename_queue) print("PRINTING the VALUE", value) image_tf = tf.image.decode_jpeg(value, channels=3) print("THE IMAGE", image_tf) """ ADDED FOR CHECKING PURPOSE ONLY """ imagetest = image_tf imagetest = tf.expand_dims(imagetest, 0) print("size of tensor === ", imagetest) print("THE IMAGE FORMED", imagetest) print("MAKING FIRST FUNCTION") modelsssss = feature_extractor.BuildModel('resnet_v1_50/block3', 'softplus', 'use_l2_normalized_feature', 1) print("CALLING THE MODEL") buildedModel, _ = modelsssss(imagetest, False, False) print("CAME BACK TO ORIGINAL") with tf.Session() as sess: # Initialize variables. init_op = tf.global_variables_initializer() print("SHOWING OPERATION", init_op) tf.logging.info('Starting session...') sess.run(init_op) tf.logging.info('Starting to load the models to be used...') # Loading model that will be used. tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], config.model_path) graph = tf.get_default_graph() input_image = graph.get_tensor_by_name('input_image:0') input_score_threshold = graph.get_tensor_by_name( 'input_abs_thres:0') input_image_scales = graph.get_tensor_by_name('input_scales:0') input_max_feature_num = graph.get_tensor_by_name( 'input_max_feature_num:0') boxes = graph.get_tensor_by_name('boxes:0') raw_descriptors = graph.get_tensor_by_name('features:0') feature_scales = graph.get_tensor_by_name('scales:0') attention_with_extra_dim = graph.get_tensor_by_name('scores:0') attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, config) tf.logging.info('Finished loading the models ...') print('Hi') print('------------------------locations--------------- = ', locations) # Start input enqueue threads. coord = tf.train.Coordinator() threads = tf.train.start_queue_runners(sess=sess, coord=coord) start = time.clock() for i in range(num_images): # Write to log-info once in a while. if i == 0: tf.logging.info( 'Starting to extract DELF features from images...') elif i % _STATUS_CHECK_ITERATIONS == 0: elapsed = (time.clock() - start) tf.logging.info( 'Processing image %d out of %d, last %d ' 'images took %f seconds', i, num_images, _STATUS_CHECK_ITERATIONS, elapsed) start = time.clock() # # Get next image. im = sess.run(image_tf) # If descriptor already exists, skip its computation. out_desc_filename = os.path.splitext( os.path.basename(image_paths[i]))[0] + _DELF_EXT out_desc_fullpath = os.path.join(cmd_args.output_dir, out_desc_filename) if tf.gfile.Exists(out_desc_fullpath): tf.logging.info('Skipping %s', image_paths[i]) continue # Extract and save features. (locations_out, descriptors_out, feature_scales_out, attention_out) = sess.run( [locations, descriptors, feature_scales, attention], feed_dict={ input_image: im, input_score_threshold: config.delf_local_config.score_threshold, input_image_scales: list(config.image_scales), input_max_feature_num: config.delf_local_config.max_feature_num }) feature_io.WriteToFile(out_desc_fullpath, locations_out, feature_scales_out, descriptors_out, attention_out) # Finalize enqueue threads. coord.request_stop() coord.join(threads)
def MakeExtractor(sess, config, import_scope=None): """Creates a function to extract features from an image. Args: sess: TensorFlow session to use. config: DelfConfig proto containing the model configuration. import_scope: Optional scope to use for model. Returns: Function that receives an image and returns features. """ tf.saved_model.loader.load(sess, [tf.saved_model.tag_constants.SERVING], config.model_path, import_scope=import_scope) import_scope_prefix = import_scope + '/' if import_scope is not None else '' input_image = sess.graph.get_tensor_by_name('%sinput_image:0' % import_scope_prefix) input_score_threshold = sess.graph.get_tensor_by_name( '%sinput_abs_thres:0' % import_scope_prefix) input_image_scales = sess.graph.get_tensor_by_name('%sinput_scales:0' % import_scope_prefix) input_max_feature_num = sess.graph.get_tensor_by_name( '%sinput_max_feature_num:0' % import_scope_prefix) feature_map = sess.graph.get_tensor_by_name('%sattonly/l2_normalize:0' % import_scope_prefix) #feature_map = sess.graph.get_tensor_by_name('%sresnet_v1_50/block3/unit_6/bottleneck_v1/Relu:0' % import_scope_prefix) boxes = sess.graph.get_tensor_by_name('%sboxes:0' % import_scope_prefix) raw_descriptors = sess.graph.get_tensor_by_name('%sfeatures:0' % import_scope_prefix) feature_scales = sess.graph.get_tensor_by_name('%sscales:0' % import_scope_prefix) attention_with_extra_dim = sess.graph.get_tensor_by_name( '%sscores:0' % import_scope_prefix) attention = tf.reshape(attention_with_extra_dim, [tf.shape(attention_with_extra_dim)[0]]) locations, descriptors = feature_extractor.DelfFeaturePostProcessing( boxes, raw_descriptors, config) def ExtractorFn(image): """Receives an image and returns DELF features. If image is too small, returns empty set of features. Args: image: Uint8 array with shape (height, width, 3) containing the RGB image. Returns: Tuple (locations, descriptors, feature_scales, attention) """ resized_image, scale_factor = ResizeImage(image, config) # If the image is too small, returns empty features. if resized_image.shape[0] < _MIN_HEIGHT or resized_image.shape[ 1] < _MIN_WIDTH: return np.array([]), np.array([]), np.array([]), np.array([]) (locations_out, descriptors_out, feature_scales_out, attention_out, feature_map_out) = sess.run( [locations, descriptors, feature_scales, attention, feature_map], feed_dict={ input_image: resized_image, input_score_threshold: config.delf_local_config.score_threshold, input_image_scales: list(config.image_scales), input_max_feature_num: config.delf_local_config.max_feature_num }) rescaled_locations_out = locations_out / scale_factor return (rescaled_locations_out, descriptors_out, feature_scales_out, attention_out, feature_map_out) return ExtractorFn