def test_extraction_output_matches_requested_default_parameters(self): """ Tests that the extraction has been performed with the requested parameters. """ image_path = os.path.abspath("../test_images/seminar.pgm") destination_dir = "/tmp" # Tests the default settings. parameters = sift_descriptors_pb2.ExtractionParameters() caltech_util.do_extraction((image_path, destination_dir, parameters.SerializeToString())) expected_output_path = os.path.join(destination_dir, "seminar.sift") result_params = sift_util.get_extraction_parameters(expected_output_path) self.assertEqual(result_params.rotation_invariance, False) self.assertEqual(result_params.normalization_threshold, 0) self.assertEqual(result_params.discard_unnormalized, False) self.assertEqual(result_params.multiscale, True) self.assertEqual(result_params.percentage, 1) self.assertEqual(result_params.minimum_radius, 0) self.assertEqual(result_params.fractional_xy, False) self.assertEqual(result_params.top_left_x, 0) self.assertEqual(result_params.top_left_y, 0) self.assertEqual(result_params.bottom_right_x, 2147483647) self.assertEqual(result_params.bottom_right_y, 2147483647) self.assertEqual(result_params.implementation, sift_descriptors_pb2.ExtractionParameters.VLFEAT) self.assertEqual(result_params.grid_method, sift_descriptors_pb2.ExtractionParameters.FIXED_3X3) self.assertEqual(result_params.smoothed, True) self.assertAlmostEqual(result_params.first_level_smoothing, 0.6666666, places=4)
def test_extraction_output_matches_requested_default_parameters(self): """ Tests that the extraction has been performed with the requested parameters. """ image_path = os.path.abspath('../test_images/seminar.pgm') destination_dir = '/tmp' # Tests the default settings. parameters = sift_descriptors_pb2.ExtractionParameters() caltech_util.do_extraction( (image_path, destination_dir, parameters.SerializeToString())) expected_output_path = os.path.join(destination_dir, 'seminar.sift') result_params = \ sift_util.get_extraction_parameters(expected_output_path) self.assertEqual(result_params.rotation_invariance, False) self.assertEqual(result_params.normalization_threshold, 0) self.assertEqual(result_params.discard_unnormalized, False) self.assertEqual(result_params.multiscale, True) self.assertEqual(result_params.percentage, 1) self.assertEqual(result_params.minimum_radius, 0) self.assertEqual(result_params.fractional_xy, False) self.assertEqual(result_params.top_left_x, 0) self.assertEqual(result_params.top_left_y, 0) self.assertEqual(result_params.bottom_right_x, 2147483647) self.assertEqual(result_params.bottom_right_y, 2147483647) self.assertEqual(result_params.implementation, sift_descriptors_pb2.ExtractionParameters.VLFEAT) self.assertEqual(result_params.grid_method, sift_descriptors_pb2.ExtractionParameters.FIXED_3X3) self.assertEqual(result_params.smoothed, True) self.assertAlmostEqual(result_params.first_level_smoothing, 0.6666666, places=4)
def do_extraction(extraction_tuple): """ Extracts sift from an image to a directory with given parameters. Runs the extract_descriptors_cli on an image with output to the specified directory and the parameters as given. Argument: - extraction_tuple: a 3-tuple (image, output_directory, extraction_parameters) with the absolute image path and absolute path of the output directory in which to place the extracted descriptor set (requested_parameters is a string-serialized protobuf) """ (image, directory, requested_parameters_string) = extraction_tuple requested_parameters = sift_descriptors_pb2.ExtractionParameters() requested_parameters.ParseFromString(requested_parameters_string) if not os.path.exists(image): raise ImageNotFoundError('%s does not exist' % image) extract_descriptors_cli = 'extract_descriptors_cli' # First, we check if there's a file in the expected output location already # (ie. directory/image_basename.sift) with the requested parameters expected_output_path = \ os.path.join(directory, os.path.splitext(os.path.basename(image))[0] + '.sift') need_fresh_extraction = False try: existing_parameters = \ sift_util.get_extraction_parameters(expected_output_path) # This complicated logic is needed because protocol buffers # don't implement an equality operator, and there are some # floating point errors introduced through in the message # chain that should be considered irrelevant. eps = 0.00001 if ((existing_parameters.rotation_invariance != requested_parameters.rotation_invariance) or (math.fabs(existing_parameters.normalization_threshold - requested_parameters.normalization_threshold) > eps) or (existing_parameters.discard_unnormalized != requested_parameters.discard_unnormalized) or (existing_parameters.multiscale != requested_parameters.multiscale) or (math.fabs(existing_parameters.percentage - requested_parameters.percentage) > eps) or (math.fabs(existing_parameters.minimum_radius - requested_parameters.minimum_radius) > eps) or (existing_parameters.fractional_xy != requested_parameters.fractional_xy) or (existing_parameters.top_left_x != requested_parameters.top_left_x) or (existing_parameters.top_left_y != requested_parameters.top_left_y) or (existing_parameters.bottom_right_x != requested_parameters.bottom_right_x) or (existing_parameters.bottom_right_y != requested_parameters.bottom_right_y) or (existing_parameters.implementation != requested_parameters.implementation) or (existing_parameters.grid_method != requested_parameters.grid_method) or (existing_parameters.smoothed != requested_parameters.smoothed) or (math.fabs(existing_parameters.first_level_smoothing - requested_parameters.first_level_smoothing) > eps) or (existing_parameters.fast != requested_parameters.fast) ): need_fresh_extraction = True except IOError as e: need_fresh_extraction = True if (requested_parameters.grid_method == sift_descriptors_pb2.ExtractionParameters.FIXED_3X3): grid_method_string = 'FIXED_3X3' elif (requested_parameters.grid_method == sift_descriptors_pb2.ExtractionParameters.FIXED_8X8): grid_method_string = 'FIXED_8X8' elif (requested_parameters.grid_method == sift_descriptors_pb2.ExtractionParameters.SCALED_3X3): grid_method_string = 'SCALED_3X3' elif (requested_parameters.grid_method == sift_descriptors_pb2.ExtractionParameters.SCALED_BIN_WIDTH): grid_method_string = 'SCALED_BIN_WIDTH' elif (requested_parameters.grid_method == sift_descriptors_pb2.ExtractionParameters.SCALED_DOUBLE_BIN_WIDTH): grid_method_string = 'SCALED_DOUBLE_BIN_WIDTH' command = (("%s --first_level_smoothing %f " "--percentage %f --clobber %s " "--normalization_threshold %f %s " "--minimum_radius %f %s %s %s " "--grid_type %s --output_directory %s %s " "--logtostderr") % (extract_descriptors_cli, requested_parameters.first_level_smoothing, requested_parameters.percentage, ('--discard' if requested_parameters.discard_unnormalized else '--nodiscard'), requested_parameters.normalization_threshold, '--smooth' if requested_parameters.smoothed else '--nosmooth', requested_parameters.minimum_radius, ('--fractional_location' if requested_parameters.fractional_xy else '--nofractional_location'), ('--multiscale' if requested_parameters.multiscale else '--nomultiscale'), '--fast' if requested_parameters.fast else '--nofast', grid_method_string, directory, image)) if need_fresh_extraction: output = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() print output[0], print output[1], else: print ('%s already exists with requested parameters' % expected_output_path)