| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| """Tests for object_detection.utils.ops.""" |
| import numpy as np |
| import tensorflow as tf |
|
|
| from object_detection.core import standard_fields as fields |
| from object_detection.utils import ops |
| from object_detection.utils import test_case |
|
|
| slim = tf.contrib.slim |
|
|
|
|
| class NormalizedToImageCoordinatesTest(tf.test.TestCase): |
|
|
| def test_normalized_to_image_coordinates(self): |
| normalized_boxes = tf.placeholder(tf.float32, shape=(None, 1, 4)) |
| normalized_boxes_np = np.array([[[0.0, 0.0, 1.0, 1.0]], |
| [[0.5, 0.5, 1.0, 1.0]]]) |
| image_shape = tf.convert_to_tensor([1, 4, 4, 3], dtype=tf.int32) |
| absolute_boxes = ops.normalized_to_image_coordinates(normalized_boxes, |
| image_shape, |
| parallel_iterations=2) |
|
|
| expected_boxes = np.array([[[0, 0, 4, 4]], |
| [[2, 2, 4, 4]]]) |
| with self.test_session() as sess: |
| absolute_boxes = sess.run(absolute_boxes, |
| feed_dict={normalized_boxes: |
| normalized_boxes_np}) |
|
|
| self.assertAllEqual(absolute_boxes, expected_boxes) |
|
|
|
|
| class ReduceSumTrailingDimensions(tf.test.TestCase): |
|
|
| def test_reduce_sum_trailing_dimensions(self): |
| input_tensor = tf.placeholder(tf.float32, shape=[None, None, None]) |
| reduced_tensor = ops.reduce_sum_trailing_dimensions(input_tensor, ndims=2) |
| with self.test_session() as sess: |
| reduced_np = sess.run(reduced_tensor, |
| feed_dict={input_tensor: np.ones((2, 2, 2), |
| np.float32)}) |
| self.assertAllClose(reduced_np, 2 * np.ones((2, 2), np.float32)) |
|
|
|
|
| class MeshgridTest(tf.test.TestCase): |
|
|
| def test_meshgrid_numpy_comparison(self): |
| """Tests meshgrid op with vectors, for which it should match numpy.""" |
| x = np.arange(4) |
| y = np.arange(6) |
| exp_xgrid, exp_ygrid = np.meshgrid(x, y) |
| xgrid, ygrid = ops.meshgrid(x, y) |
| with self.test_session() as sess: |
| xgrid_output, ygrid_output = sess.run([xgrid, ygrid]) |
| self.assertAllEqual(xgrid_output, exp_xgrid) |
| self.assertAllEqual(ygrid_output, exp_ygrid) |
|
|
| def test_meshgrid_multidimensional(self): |
| np.random.seed(18) |
| x = np.random.rand(4, 1, 2).astype(np.float32) |
| y = np.random.rand(2, 3).astype(np.float32) |
|
|
| xgrid, ygrid = ops.meshgrid(x, y) |
|
|
| grid_shape = list(y.shape) + list(x.shape) |
| self.assertEqual(xgrid.get_shape().as_list(), grid_shape) |
| self.assertEqual(ygrid.get_shape().as_list(), grid_shape) |
| with self.test_session() as sess: |
| xgrid_output, ygrid_output = sess.run([xgrid, ygrid]) |
|
|
| |
| self.assertEqual(xgrid_output.shape, tuple(grid_shape)) |
| self.assertEqual(ygrid_output.shape, tuple(grid_shape)) |
|
|
| |
| test_elements = [((3, 0, 0), (1, 2)), |
| ((2, 0, 1), (0, 0)), |
| ((0, 0, 0), (1, 1))] |
| for xind, yind in test_elements: |
| |
| |
| self.assertEqual(xgrid_output[yind + xind], x[xind]) |
| self.assertEqual(ygrid_output[yind + xind], y[yind]) |
|
|
|
|
| class OpsTestFixedPadding(tf.test.TestCase): |
|
|
| def test_3x3_kernel(self): |
| tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]]) |
| padded_tensor = ops.fixed_padding(tensor, 3) |
| with self.test_session() as sess: |
| padded_tensor_out = sess.run(padded_tensor) |
| self.assertEqual((1, 4, 4, 1), padded_tensor_out.shape) |
|
|
| def test_5x5_kernel(self): |
| tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]]) |
| padded_tensor = ops.fixed_padding(tensor, 5) |
| with self.test_session() as sess: |
| padded_tensor_out = sess.run(padded_tensor) |
| self.assertEqual((1, 6, 6, 1), padded_tensor_out.shape) |
|
|
| def test_3x3_atrous_kernel(self): |
| tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]]) |
| padded_tensor = ops.fixed_padding(tensor, 3, 2) |
| with self.test_session() as sess: |
| padded_tensor_out = sess.run(padded_tensor) |
| self.assertEqual((1, 6, 6, 1), padded_tensor_out.shape) |
|
|
|
|
| class OpsTestPadToMultiple(tf.test.TestCase): |
|
|
| def test_zero_padding(self): |
| tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]]) |
| padded_tensor = ops.pad_to_multiple(tensor, 1) |
| with self.test_session() as sess: |
| padded_tensor_out = sess.run(padded_tensor) |
| self.assertEqual((1, 2, 2, 1), padded_tensor_out.shape) |
|
|
| def test_no_padding(self): |
| tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]]) |
| padded_tensor = ops.pad_to_multiple(tensor, 2) |
| with self.test_session() as sess: |
| padded_tensor_out = sess.run(padded_tensor) |
| self.assertEqual((1, 2, 2, 1), padded_tensor_out.shape) |
|
|
| def test_non_square_padding(self): |
| tensor = tf.constant([[[[0.], [0.]]]]) |
| padded_tensor = ops.pad_to_multiple(tensor, 2) |
| with self.test_session() as sess: |
| padded_tensor_out = sess.run(padded_tensor) |
| self.assertEqual((1, 2, 2, 1), padded_tensor_out.shape) |
|
|
| def test_padding(self): |
| tensor = tf.constant([[[[0.], [0.]], [[0.], [0.]]]]) |
| padded_tensor = ops.pad_to_multiple(tensor, 4) |
| with self.test_session() as sess: |
| padded_tensor_out = sess.run(padded_tensor) |
| self.assertEqual((1, 4, 4, 1), padded_tensor_out.shape) |
|
|
|
|
| class OpsTestPaddedOneHotEncoding(tf.test.TestCase): |
|
|
| def test_correct_one_hot_tensor_with_no_pad(self): |
| indices = tf.constant([1, 2, 3, 5]) |
| one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=6, left_pad=0) |
| expected_tensor = np.array([[0, 1, 0, 0, 0, 0], |
| [0, 0, 1, 0, 0, 0], |
| [0, 0, 0, 1, 0, 0], |
| [0, 0, 0, 0, 0, 1]], np.float32) |
| with self.test_session() as sess: |
| out_one_hot_tensor = sess.run(one_hot_tensor) |
| self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10, |
| atol=1e-10) |
|
|
| def test_correct_one_hot_tensor_with_pad_one(self): |
| indices = tf.constant([1, 2, 3, 5]) |
| one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=6, left_pad=1) |
| expected_tensor = np.array([[0, 0, 1, 0, 0, 0, 0], |
| [0, 0, 0, 1, 0, 0, 0], |
| [0, 0, 0, 0, 1, 0, 0], |
| [0, 0, 0, 0, 0, 0, 1]], np.float32) |
| with self.test_session() as sess: |
| out_one_hot_tensor = sess.run(one_hot_tensor) |
| self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10, |
| atol=1e-10) |
|
|
| def test_correct_one_hot_tensor_with_pad_three(self): |
| indices = tf.constant([1, 2, 3, 5]) |
| one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=6, left_pad=3) |
| expected_tensor = np.array([[0, 0, 0, 0, 1, 0, 0, 0, 0], |
| [0, 0, 0, 0, 0, 1, 0, 0, 0], |
| [0, 0, 0, 0, 0, 0, 1, 0, 0], |
| [0, 0, 0, 0, 0, 0, 0, 0, 1]], np.float32) |
| with self.test_session() as sess: |
| out_one_hot_tensor = sess.run(one_hot_tensor) |
| self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10, |
| atol=1e-10) |
|
|
| def test_correct_padded_one_hot_tensor_with_empty_indices(self): |
| depth = 6 |
| pad = 2 |
| indices = tf.constant([]) |
| one_hot_tensor = ops.padded_one_hot_encoding( |
| indices, depth=depth, left_pad=pad) |
| expected_tensor = np.zeros((0, depth + pad)) |
| with self.test_session() as sess: |
| out_one_hot_tensor = sess.run(one_hot_tensor) |
| self.assertAllClose(out_one_hot_tensor, expected_tensor, rtol=1e-10, |
| atol=1e-10) |
|
|
| def test_return_none_on_zero_depth(self): |
| indices = tf.constant([1, 2, 3, 4, 5]) |
| one_hot_tensor = ops.padded_one_hot_encoding(indices, depth=0, left_pad=2) |
| self.assertEqual(one_hot_tensor, None) |
|
|
| def test_raise_value_error_on_rank_two_input(self): |
| indices = tf.constant(1.0, shape=(2, 3)) |
| with self.assertRaises(ValueError): |
| ops.padded_one_hot_encoding(indices, depth=6, left_pad=2) |
|
|
| def test_raise_value_error_on_negative_pad(self): |
| indices = tf.constant(1.0, shape=(2, 3)) |
| with self.assertRaises(ValueError): |
| ops.padded_one_hot_encoding(indices, depth=6, left_pad=-1) |
|
|
| def test_raise_value_error_on_float_pad(self): |
| indices = tf.constant(1.0, shape=(2, 3)) |
| with self.assertRaises(ValueError): |
| ops.padded_one_hot_encoding(indices, depth=6, left_pad=0.1) |
|
|
| def test_raise_value_error_on_float_depth(self): |
| indices = tf.constant(1.0, shape=(2, 3)) |
| with self.assertRaises(ValueError): |
| ops.padded_one_hot_encoding(indices, depth=0.1, left_pad=2) |
|
|
|
|
| class OpsDenseToSparseBoxesTest(tf.test.TestCase): |
|
|
| def test_return_all_boxes_when_all_input_boxes_are_valid(self): |
| num_classes = 4 |
| num_valid_boxes = 3 |
| code_size = 4 |
| dense_location_placeholder = tf.placeholder(tf.float32, |
| shape=(num_valid_boxes, |
| code_size)) |
| dense_num_boxes_placeholder = tf.placeholder(tf.int32, shape=(num_classes)) |
| box_locations, box_classes = ops.dense_to_sparse_boxes( |
| dense_location_placeholder, dense_num_boxes_placeholder, num_classes) |
| feed_dict = {dense_location_placeholder: np.random.uniform( |
| size=[num_valid_boxes, code_size]), |
| dense_num_boxes_placeholder: np.array([1, 0, 0, 2], |
| dtype=np.int32)} |
|
|
| expected_box_locations = feed_dict[dense_location_placeholder] |
| expected_box_classses = np.array([0, 3, 3]) |
| with self.test_session() as sess: |
| box_locations, box_classes = sess.run([box_locations, box_classes], |
| feed_dict=feed_dict) |
|
|
| self.assertAllClose(box_locations, expected_box_locations, rtol=1e-6, |
| atol=1e-6) |
| self.assertAllEqual(box_classes, expected_box_classses) |
|
|
| def test_return_only_valid_boxes_when_input_contains_invalid_boxes(self): |
| num_classes = 4 |
| num_valid_boxes = 3 |
| num_boxes = 10 |
| code_size = 4 |
|
|
| dense_location_placeholder = tf.placeholder(tf.float32, shape=(num_boxes, |
| code_size)) |
| dense_num_boxes_placeholder = tf.placeholder(tf.int32, shape=(num_classes)) |
| box_locations, box_classes = ops.dense_to_sparse_boxes( |
| dense_location_placeholder, dense_num_boxes_placeholder, num_classes) |
| feed_dict = {dense_location_placeholder: np.random.uniform( |
| size=[num_boxes, code_size]), |
| dense_num_boxes_placeholder: np.array([1, 0, 0, 2], |
| dtype=np.int32)} |
|
|
| expected_box_locations = (feed_dict[dense_location_placeholder] |
| [:num_valid_boxes]) |
| expected_box_classses = np.array([0, 3, 3]) |
| with self.test_session() as sess: |
| box_locations, box_classes = sess.run([box_locations, box_classes], |
| feed_dict=feed_dict) |
|
|
| self.assertAllClose(box_locations, expected_box_locations, rtol=1e-6, |
| atol=1e-6) |
| self.assertAllEqual(box_classes, expected_box_classses) |
|
|
|
|
| class OpsTestIndicesToDenseVector(tf.test.TestCase): |
|
|
| def test_indices_to_dense_vector(self): |
| size = 10000 |
| num_indices = np.random.randint(size) |
| rand_indices = np.random.permutation(np.arange(size))[0:num_indices] |
|
|
| expected_output = np.zeros(size, dtype=np.float32) |
| expected_output[rand_indices] = 1. |
|
|
| tf_rand_indices = tf.constant(rand_indices) |
| indicator = ops.indices_to_dense_vector(tf_rand_indices, size) |
|
|
| with self.test_session() as sess: |
| output = sess.run(indicator) |
| self.assertAllEqual(output, expected_output) |
| self.assertEqual(output.dtype, expected_output.dtype) |
|
|
| def test_indices_to_dense_vector_size_at_inference(self): |
| size = 5000 |
| num_indices = 250 |
| all_indices = np.arange(size) |
| rand_indices = np.random.permutation(all_indices)[0:num_indices] |
|
|
| expected_output = np.zeros(size, dtype=np.float32) |
| expected_output[rand_indices] = 1. |
|
|
| tf_all_indices = tf.placeholder(tf.int32) |
| tf_rand_indices = tf.constant(rand_indices) |
| indicator = ops.indices_to_dense_vector(tf_rand_indices, |
| tf.shape(tf_all_indices)[0]) |
| feed_dict = {tf_all_indices: all_indices} |
|
|
| with self.test_session() as sess: |
| output = sess.run(indicator, feed_dict=feed_dict) |
| self.assertAllEqual(output, expected_output) |
| self.assertEqual(output.dtype, expected_output.dtype) |
|
|
| def test_indices_to_dense_vector_int(self): |
| size = 500 |
| num_indices = 25 |
| rand_indices = np.random.permutation(np.arange(size))[0:num_indices] |
|
|
| expected_output = np.zeros(size, dtype=np.int64) |
| expected_output[rand_indices] = 1 |
|
|
| tf_rand_indices = tf.constant(rand_indices) |
| indicator = ops.indices_to_dense_vector( |
| tf_rand_indices, size, 1, dtype=tf.int64) |
|
|
| with self.test_session() as sess: |
| output = sess.run(indicator) |
| self.assertAllEqual(output, expected_output) |
| self.assertEqual(output.dtype, expected_output.dtype) |
|
|
| def test_indices_to_dense_vector_custom_values(self): |
| size = 100 |
| num_indices = 10 |
| rand_indices = np.random.permutation(np.arange(size))[0:num_indices] |
| indices_value = np.random.rand(1) |
| default_value = np.random.rand(1) |
|
|
| expected_output = np.float32(np.ones(size) * default_value) |
| expected_output[rand_indices] = indices_value |
|
|
| tf_rand_indices = tf.constant(rand_indices) |
| indicator = ops.indices_to_dense_vector( |
| tf_rand_indices, |
| size, |
| indices_value=indices_value, |
| default_value=default_value) |
|
|
| with self.test_session() as sess: |
| output = sess.run(indicator) |
| self.assertAllClose(output, expected_output) |
| self.assertEqual(output.dtype, expected_output.dtype) |
|
|
| def test_indices_to_dense_vector_all_indices_as_input(self): |
| size = 500 |
| num_indices = 500 |
| rand_indices = np.random.permutation(np.arange(size))[0:num_indices] |
|
|
| expected_output = np.ones(size, dtype=np.float32) |
|
|
| tf_rand_indices = tf.constant(rand_indices) |
| indicator = ops.indices_to_dense_vector(tf_rand_indices, size) |
|
|
| with self.test_session() as sess: |
| output = sess.run(indicator) |
| self.assertAllEqual(output, expected_output) |
| self.assertEqual(output.dtype, expected_output.dtype) |
|
|
| def test_indices_to_dense_vector_empty_indices_as_input(self): |
| size = 500 |
| rand_indices = [] |
|
|
| expected_output = np.zeros(size, dtype=np.float32) |
|
|
| tf_rand_indices = tf.constant(rand_indices) |
| indicator = ops.indices_to_dense_vector(tf_rand_indices, size) |
|
|
| with self.test_session() as sess: |
| output = sess.run(indicator) |
| self.assertAllEqual(output, expected_output) |
| self.assertEqual(output.dtype, expected_output.dtype) |
|
|
|
|
| class GroundtruthFilterTest(tf.test.TestCase): |
|
|
| def test_filter_groundtruth(self): |
| input_image = tf.placeholder(tf.float32, shape=(None, None, 3)) |
| input_boxes = tf.placeholder(tf.float32, shape=(None, 4)) |
| input_classes = tf.placeholder(tf.int32, shape=(None,)) |
| input_is_crowd = tf.placeholder(tf.bool, shape=(None,)) |
| input_area = tf.placeholder(tf.float32, shape=(None,)) |
| input_difficult = tf.placeholder(tf.float32, shape=(None,)) |
| input_label_types = tf.placeholder(tf.string, shape=(None,)) |
| input_confidences = tf.placeholder(tf.float32, shape=(None,)) |
| valid_indices = tf.placeholder(tf.int32, shape=(None,)) |
| input_tensors = { |
| fields.InputDataFields.image: input_image, |
| fields.InputDataFields.groundtruth_boxes: input_boxes, |
| fields.InputDataFields.groundtruth_classes: input_classes, |
| fields.InputDataFields.groundtruth_is_crowd: input_is_crowd, |
| fields.InputDataFields.groundtruth_area: input_area, |
| fields.InputDataFields.groundtruth_difficult: input_difficult, |
| fields.InputDataFields.groundtruth_label_types: input_label_types, |
| fields.InputDataFields.groundtruth_confidences: input_confidences, |
| } |
| output_tensors = ops.retain_groundtruth(input_tensors, valid_indices) |
|
|
| image_tensor = np.random.rand(224, 224, 3) |
| feed_dict = { |
| input_image: image_tensor, |
| input_boxes: |
| np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]], dtype=np.float), |
| input_classes: np.array([1, 2], dtype=np.int32), |
| input_is_crowd: np.array([False, True], dtype=np.bool), |
| input_area: np.array([32, 48], dtype=np.float32), |
| input_difficult: np.array([True, False], dtype=np.bool), |
| input_label_types: |
| np.array(['APPROPRIATE', 'INCORRECT'], dtype=np.string_), |
| input_confidences: np.array([0.99, 0.5], dtype=np.float32), |
| valid_indices: np.array([0], dtype=np.int32), |
| } |
| expected_tensors = { |
| fields.InputDataFields.image: image_tensor, |
| fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: [1], |
| fields.InputDataFields.groundtruth_is_crowd: [False], |
| fields.InputDataFields.groundtruth_area: [32], |
| fields.InputDataFields.groundtruth_difficult: [True], |
| fields.InputDataFields.groundtruth_label_types: ['APPROPRIATE'], |
| fields.InputDataFields.groundtruth_confidences: [0.99], |
| } |
| with self.test_session() as sess: |
| output_tensors = sess.run(output_tensors, feed_dict=feed_dict) |
| for key in [fields.InputDataFields.image, |
| fields.InputDataFields.groundtruth_boxes, |
| fields.InputDataFields.groundtruth_area, |
| fields.InputDataFields.groundtruth_confidences]: |
| self.assertAllClose(expected_tensors[key], output_tensors[key]) |
| for key in [fields.InputDataFields.groundtruth_classes, |
| fields.InputDataFields.groundtruth_is_crowd, |
| fields.InputDataFields.groundtruth_label_types]: |
| self.assertAllEqual(expected_tensors[key], output_tensors[key]) |
|
|
| def test_filter_with_missing_fields(self): |
| input_boxes = tf.placeholder(tf.float32, shape=(None, 4)) |
| input_classes = tf.placeholder(tf.int32, shape=(None,)) |
| input_tensors = { |
| fields.InputDataFields.groundtruth_boxes: input_boxes, |
| fields.InputDataFields.groundtruth_classes: input_classes |
| } |
| valid_indices = tf.placeholder(tf.int32, shape=(None,)) |
|
|
| feed_dict = { |
| input_boxes: |
| np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]], dtype=np.float), |
| input_classes: |
| np.array([1, 2], dtype=np.int32), |
| valid_indices: |
| np.array([0], dtype=np.int32) |
| } |
| expected_tensors = { |
| fields.InputDataFields.groundtruth_boxes: |
| [[0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: |
| [1] |
| } |
|
|
| output_tensors = ops.retain_groundtruth(input_tensors, valid_indices) |
| with self.test_session() as sess: |
| output_tensors = sess.run(output_tensors, feed_dict=feed_dict) |
| for key in [fields.InputDataFields.groundtruth_boxes]: |
| self.assertAllClose(expected_tensors[key], output_tensors[key]) |
| for key in [fields.InputDataFields.groundtruth_classes]: |
| self.assertAllEqual(expected_tensors[key], output_tensors[key]) |
|
|
| def test_filter_with_empty_fields(self): |
| input_boxes = tf.placeholder(tf.float32, shape=(None, 4)) |
| input_classes = tf.placeholder(tf.int32, shape=(None,)) |
| input_is_crowd = tf.placeholder(tf.bool, shape=(None,)) |
| input_area = tf.placeholder(tf.float32, shape=(None,)) |
| input_difficult = tf.placeholder(tf.float32, shape=(None,)) |
| input_confidences = tf.placeholder(tf.float32, shape=(None,)) |
| valid_indices = tf.placeholder(tf.int32, shape=(None,)) |
| input_tensors = { |
| fields.InputDataFields.groundtruth_boxes: input_boxes, |
| fields.InputDataFields.groundtruth_classes: input_classes, |
| fields.InputDataFields.groundtruth_is_crowd: input_is_crowd, |
| fields.InputDataFields.groundtruth_area: input_area, |
| fields.InputDataFields.groundtruth_difficult: input_difficult, |
| fields.InputDataFields.groundtruth_confidences: input_confidences, |
| } |
| output_tensors = ops.retain_groundtruth(input_tensors, valid_indices) |
|
|
| feed_dict = { |
| input_boxes: |
| np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]], dtype=np.float), |
| input_classes: np.array([1, 2], dtype=np.int32), |
| input_is_crowd: np.array([False, True], dtype=np.bool), |
| input_area: np.array([], dtype=np.float32), |
| input_difficult: np.array([], dtype=np.float32), |
| input_confidences: np.array([0.99, 0.5], dtype=np.float32), |
| valid_indices: np.array([0], dtype=np.int32) |
| } |
| expected_tensors = { |
| fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: [1], |
| fields.InputDataFields.groundtruth_is_crowd: [False], |
| fields.InputDataFields.groundtruth_area: [], |
| fields.InputDataFields.groundtruth_difficult: [], |
| fields.InputDataFields.groundtruth_confidences: [0.99], |
| } |
| with self.test_session() as sess: |
| output_tensors = sess.run(output_tensors, feed_dict=feed_dict) |
| for key in [fields.InputDataFields.groundtruth_boxes, |
| fields.InputDataFields.groundtruth_area, |
| fields.InputDataFields.groundtruth_confidences]: |
| self.assertAllClose(expected_tensors[key], output_tensors[key]) |
| for key in [fields.InputDataFields.groundtruth_classes, |
| fields.InputDataFields.groundtruth_is_crowd]: |
| self.assertAllEqual(expected_tensors[key], output_tensors[key]) |
|
|
| def test_filter_with_empty_groundtruth_boxes(self): |
| input_boxes = tf.placeholder(tf.float32, shape=(None, 4)) |
| input_classes = tf.placeholder(tf.int32, shape=(None,)) |
| input_is_crowd = tf.placeholder(tf.bool, shape=(None,)) |
| input_area = tf.placeholder(tf.float32, shape=(None,)) |
| input_difficult = tf.placeholder(tf.float32, shape=(None,)) |
| input_confidences = tf.placeholder(tf.float32, shape=(None,)) |
| valid_indices = tf.placeholder(tf.int32, shape=(None,)) |
| input_tensors = { |
| fields.InputDataFields.groundtruth_boxes: input_boxes, |
| fields.InputDataFields.groundtruth_classes: input_classes, |
| fields.InputDataFields.groundtruth_is_crowd: input_is_crowd, |
| fields.InputDataFields.groundtruth_area: input_area, |
| fields.InputDataFields.groundtruth_difficult: input_difficult, |
| fields.InputDataFields.groundtruth_confidences: input_confidences, |
| } |
| output_tensors = ops.retain_groundtruth(input_tensors, valid_indices) |
|
|
| feed_dict = { |
| input_boxes: np.array([], dtype=np.float).reshape(0, 4), |
| input_classes: np.array([], dtype=np.int32), |
| input_is_crowd: np.array([], dtype=np.bool), |
| input_area: np.array([], dtype=np.float32), |
| input_difficult: np.array([], dtype=np.float32), |
| input_confidences: np.array([], dtype=np.float32), |
| valid_indices: np.array([], dtype=np.int32), |
| } |
| with self.test_session() as sess: |
| output_tensors = sess.run(output_tensors, feed_dict=feed_dict) |
| for key in input_tensors: |
| if key == fields.InputDataFields.groundtruth_boxes: |
| self.assertAllEqual([0, 4], output_tensors[key].shape) |
| else: |
| self.assertAllEqual([0], output_tensors[key].shape) |
|
|
|
|
| class RetainGroundTruthWithPositiveClasses(tf.test.TestCase): |
|
|
| def test_filter_groundtruth_with_positive_classes(self): |
| input_image = tf.placeholder(tf.float32, shape=(None, None, 3)) |
| input_boxes = tf.placeholder(tf.float32, shape=(None, 4)) |
| input_classes = tf.placeholder(tf.int32, shape=(None,)) |
| input_is_crowd = tf.placeholder(tf.bool, shape=(None,)) |
| input_area = tf.placeholder(tf.float32, shape=(None,)) |
| input_difficult = tf.placeholder(tf.float32, shape=(None,)) |
| input_label_types = tf.placeholder(tf.string, shape=(None,)) |
| input_confidences = tf.placeholder(tf.float32, shape=(None,)) |
| valid_indices = tf.placeholder(tf.int32, shape=(None,)) |
| input_tensors = { |
| fields.InputDataFields.image: input_image, |
| fields.InputDataFields.groundtruth_boxes: input_boxes, |
| fields.InputDataFields.groundtruth_classes: input_classes, |
| fields.InputDataFields.groundtruth_is_crowd: input_is_crowd, |
| fields.InputDataFields.groundtruth_area: input_area, |
| fields.InputDataFields.groundtruth_difficult: input_difficult, |
| fields.InputDataFields.groundtruth_label_types: input_label_types, |
| fields.InputDataFields.groundtruth_confidences: input_confidences, |
| } |
| output_tensors = ops.retain_groundtruth_with_positive_classes(input_tensors) |
|
|
| image_tensor = np.random.rand(224, 224, 3) |
| feed_dict = { |
| input_image: image_tensor, |
| input_boxes: |
| np.array([[0.2, 0.4, 0.1, 0.8], [0.2, 0.4, 1.0, 0.8]], dtype=np.float), |
| input_classes: np.array([1, 0], dtype=np.int32), |
| input_is_crowd: np.array([False, True], dtype=np.bool), |
| input_area: np.array([32, 48], dtype=np.float32), |
| input_difficult: np.array([True, False], dtype=np.bool), |
| input_label_types: |
| np.array(['APPROPRIATE', 'INCORRECT'], dtype=np.string_), |
| input_confidences: np.array([0.99, 0.5], dtype=np.float32), |
| valid_indices: np.array([0], dtype=np.int32), |
| } |
| expected_tensors = { |
| fields.InputDataFields.image: image_tensor, |
| fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: [1], |
| fields.InputDataFields.groundtruth_is_crowd: [False], |
| fields.InputDataFields.groundtruth_area: [32], |
| fields.InputDataFields.groundtruth_difficult: [True], |
| fields.InputDataFields.groundtruth_label_types: ['APPROPRIATE'], |
| fields.InputDataFields.groundtruth_confidences: [0.99], |
| } |
| with self.test_session() as sess: |
| output_tensors = sess.run(output_tensors, feed_dict=feed_dict) |
| for key in [fields.InputDataFields.image, |
| fields.InputDataFields.groundtruth_boxes, |
| fields.InputDataFields.groundtruth_area, |
| fields.InputDataFields.groundtruth_confidences]: |
| self.assertAllClose(expected_tensors[key], output_tensors[key]) |
| for key in [fields.InputDataFields.groundtruth_classes, |
| fields.InputDataFields.groundtruth_is_crowd, |
| fields.InputDataFields.groundtruth_label_types]: |
| self.assertAllEqual(expected_tensors[key], output_tensors[key]) |
|
|
|
|
| class ReplaceNaNGroundtruthLabelScoresWithOnes(tf.test.TestCase): |
|
|
| def test_replace_nan_groundtruth_label_scores_with_ones(self): |
| label_scores = tf.constant([np.nan, 1.0, np.nan]) |
| output_tensor = ops.replace_nan_groundtruth_label_scores_with_ones( |
| label_scores) |
| expected_tensor = [1.0, 1.0, 1.0] |
| with self.test_session(): |
| output_tensor = output_tensor.eval() |
| self.assertAllClose(expected_tensor, output_tensor) |
|
|
| def test_input_equals_output_when_no_nans(self): |
| input_label_scores = [0.5, 1.0, 1.0] |
| label_scores_tensor = tf.constant(input_label_scores) |
| output_label_scores = ops.replace_nan_groundtruth_label_scores_with_ones( |
| label_scores_tensor) |
| with self.test_session(): |
| output_label_scores = output_label_scores.eval() |
| self.assertAllClose(input_label_scores, output_label_scores) |
|
|
|
|
| class GroundtruthFilterWithCrowdBoxesTest(tf.test.TestCase): |
|
|
| def test_filter_groundtruth_with_crowd_boxes(self): |
| input_tensors = { |
| fields.InputDataFields.groundtruth_boxes: |
| [[0.1, 0.2, 0.6, 0.8], [0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: [1, 2], |
| fields.InputDataFields.groundtruth_is_crowd: [True, False], |
| fields.InputDataFields.groundtruth_area: [100.0, 238.7], |
| fields.InputDataFields.groundtruth_confidences: [0.5, 0.99], |
| } |
|
|
| expected_tensors = { |
| fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: [2], |
| fields.InputDataFields.groundtruth_is_crowd: [False], |
| fields.InputDataFields.groundtruth_area: [238.7], |
| fields.InputDataFields.groundtruth_confidences: [0.99], |
| } |
|
|
| output_tensors = ops.filter_groundtruth_with_crowd_boxes( |
| input_tensors) |
| with self.test_session() as sess: |
| output_tensors = sess.run(output_tensors) |
| for key in [fields.InputDataFields.groundtruth_boxes, |
| fields.InputDataFields.groundtruth_area, |
| fields.InputDataFields.groundtruth_confidences]: |
| self.assertAllClose(expected_tensors[key], output_tensors[key]) |
| for key in [fields.InputDataFields.groundtruth_classes, |
| fields.InputDataFields.groundtruth_is_crowd]: |
| self.assertAllEqual(expected_tensors[key], output_tensors[key]) |
|
|
|
|
| class GroundtruthFilterWithNanBoxTest(tf.test.TestCase): |
|
|
| def test_filter_groundtruth_with_nan_box_coordinates(self): |
| input_tensors = { |
| fields.InputDataFields.groundtruth_boxes: |
| [[np.nan, np.nan, np.nan, np.nan], [0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: [1, 2], |
| fields.InputDataFields.groundtruth_is_crowd: [False, True], |
| fields.InputDataFields.groundtruth_area: [100.0, 238.7], |
| fields.InputDataFields.groundtruth_confidences: [0.5, 0.99], |
| } |
|
|
| expected_tensors = { |
| fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: [2], |
| fields.InputDataFields.groundtruth_is_crowd: [True], |
| fields.InputDataFields.groundtruth_area: [238.7], |
| fields.InputDataFields.groundtruth_confidences: [0.99], |
| } |
|
|
| output_tensors = ops.filter_groundtruth_with_nan_box_coordinates( |
| input_tensors) |
| with self.test_session() as sess: |
| output_tensors = sess.run(output_tensors) |
| for key in [fields.InputDataFields.groundtruth_boxes, |
| fields.InputDataFields.groundtruth_area, |
| fields.InputDataFields.groundtruth_confidences]: |
| self.assertAllClose(expected_tensors[key], output_tensors[key]) |
| for key in [fields.InputDataFields.groundtruth_classes, |
| fields.InputDataFields.groundtruth_is_crowd]: |
| self.assertAllEqual(expected_tensors[key], output_tensors[key]) |
|
|
|
|
| class GroundtruthFilterWithUnrecognizedClassesTest(tf.test.TestCase): |
|
|
| def test_filter_unrecognized_classes(self): |
| input_tensors = { |
| fields.InputDataFields.groundtruth_boxes: |
| [[.3, .3, .5, .7], [0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: [-1, 2], |
| fields.InputDataFields.groundtruth_is_crowd: [False, True], |
| fields.InputDataFields.groundtruth_area: [100.0, 238.7], |
| fields.InputDataFields.groundtruth_confidences: [0.5, 0.99], |
| } |
|
|
| expected_tensors = { |
| fields.InputDataFields.groundtruth_boxes: [[0.2, 0.4, 0.1, 0.8]], |
| fields.InputDataFields.groundtruth_classes: [2], |
| fields.InputDataFields.groundtruth_is_crowd: [True], |
| fields.InputDataFields.groundtruth_area: [238.7], |
| fields.InputDataFields.groundtruth_confidences: [0.99], |
| } |
|
|
| output_tensors = ops.filter_unrecognized_classes(input_tensors) |
| with self.test_session() as sess: |
| output_tensors = sess.run(output_tensors) |
| for key in [fields.InputDataFields.groundtruth_boxes, |
| fields.InputDataFields.groundtruth_area, |
| fields.InputDataFields.groundtruth_confidences]: |
| self.assertAllClose(expected_tensors[key], output_tensors[key]) |
| for key in [fields.InputDataFields.groundtruth_classes, |
| fields.InputDataFields.groundtruth_is_crowd]: |
| self.assertAllEqual(expected_tensors[key], output_tensors[key]) |
|
|
|
|
| class OpsTestNormalizeToTarget(tf.test.TestCase): |
|
|
| def test_create_normalize_to_target(self): |
| inputs = tf.random_uniform([5, 10, 12, 3]) |
| target_norm_value = 4.0 |
| dim = 3 |
| with self.test_session(): |
| output = ops.normalize_to_target(inputs, target_norm_value, dim) |
| self.assertEqual(output.op.name, 'NormalizeToTarget/mul') |
| var_name = tf.contrib.framework.get_variables()[0].name |
| self.assertEqual(var_name, 'NormalizeToTarget/weights:0') |
|
|
| def test_invalid_dim(self): |
| inputs = tf.random_uniform([5, 10, 12, 3]) |
| target_norm_value = 4.0 |
| dim = 10 |
| with self.assertRaisesRegexp( |
| ValueError, |
| 'dim must be non-negative but smaller than the input rank.'): |
| ops.normalize_to_target(inputs, target_norm_value, dim) |
|
|
| def test_invalid_target_norm_values(self): |
| inputs = tf.random_uniform([5, 10, 12, 3]) |
| target_norm_value = [4.0, 4.0] |
| dim = 3 |
| with self.assertRaisesRegexp( |
| ValueError, 'target_norm_value must be a float or a list of floats'): |
| ops.normalize_to_target(inputs, target_norm_value, dim) |
|
|
| def test_correct_output_shape(self): |
| inputs = tf.random_uniform([5, 10, 12, 3]) |
| target_norm_value = 4.0 |
| dim = 3 |
| with self.test_session(): |
| output = ops.normalize_to_target(inputs, target_norm_value, dim) |
| self.assertEqual(output.get_shape().as_list(), |
| inputs.get_shape().as_list()) |
|
|
| def test_correct_initial_output_values(self): |
| inputs = tf.constant([[[[3, 4], [7, 24]], |
| [[5, -12], [-1, 0]]]], tf.float32) |
| target_norm_value = 10.0 |
| dim = 3 |
| expected_output = [[[[30/5.0, 40/5.0], [70/25.0, 240/25.0]], |
| [[50/13.0, -120/13.0], [-10, 0]]]] |
| with self.test_session() as sess: |
| normalized_inputs = ops.normalize_to_target(inputs, target_norm_value, |
| dim) |
| sess.run(tf.global_variables_initializer()) |
| output = normalized_inputs.eval() |
| self.assertAllClose(output, expected_output) |
|
|
| def test_multiple_target_norm_values(self): |
| inputs = tf.constant([[[[3, 4], [7, 24]], |
| [[5, -12], [-1, 0]]]], tf.float32) |
| target_norm_value = [10.0, 20.0] |
| dim = 3 |
| expected_output = [[[[30/5.0, 80/5.0], [70/25.0, 480/25.0]], |
| [[50/13.0, -240/13.0], [-10, 0]]]] |
| with self.test_session() as sess: |
| normalized_inputs = ops.normalize_to_target(inputs, target_norm_value, |
| dim) |
| sess.run(tf.global_variables_initializer()) |
| output = normalized_inputs.eval() |
| self.assertAllClose(output, expected_output) |
|
|
|
|
| class OpsTestPositionSensitiveCropRegions(tf.test.TestCase): |
|
|
| def test_position_sensitive(self): |
| num_spatial_bins = [3, 2] |
| image_shape = [3, 2, 6] |
|
|
| |
| image = tf.constant(range(1, 3 * 2 + 1) * 6, dtype=tf.float32, |
| shape=image_shape) |
| boxes = tf.random_uniform((2, 4)) |
|
|
| |
| |
| expected_output = np.array([3.5, 3.5]).reshape([2, 1, 1, 1]) |
|
|
| for crop_size_mult in range(1, 3): |
| crop_size = [3 * crop_size_mult, 2 * crop_size_mult] |
| ps_crop_and_pool = ops.position_sensitive_crop_regions( |
| image, boxes, crop_size, num_spatial_bins, global_pool=True) |
|
|
| with self.test_session() as sess: |
| output = sess.run(ps_crop_and_pool) |
| self.assertAllClose(output, expected_output) |
|
|
| def test_position_sensitive_with_equal_channels(self): |
| num_spatial_bins = [2, 2] |
| image_shape = [3, 3, 4] |
| crop_size = [2, 2] |
|
|
| image = tf.constant(range(1, 3 * 3 + 1), dtype=tf.float32, |
| shape=[3, 3, 1]) |
| tiled_image = tf.tile(image, [1, 1, image_shape[2]]) |
| boxes = tf.random_uniform((3, 4)) |
| box_ind = tf.constant([0, 0, 0], dtype=tf.int32) |
|
|
| |
| |
| crop = tf.image.crop_and_resize(tf.expand_dims(image, axis=0), boxes, |
| box_ind, crop_size) |
| crop_and_pool = tf.reduce_mean(crop, [1, 2], keep_dims=True) |
|
|
| ps_crop_and_pool = ops.position_sensitive_crop_regions( |
| tiled_image, |
| boxes, |
| crop_size, |
| num_spatial_bins, |
| global_pool=True) |
|
|
| with self.test_session() as sess: |
| expected_output, output = sess.run((crop_and_pool, ps_crop_and_pool)) |
| self.assertAllClose(output, expected_output) |
|
|
| def test_raise_value_error_on_num_bins_less_than_one(self): |
| num_spatial_bins = [1, -1] |
| image_shape = [1, 1, 2] |
| crop_size = [2, 2] |
|
|
| image = tf.constant(1, dtype=tf.float32, shape=image_shape) |
| boxes = tf.constant([[0, 0, 1, 1]], dtype=tf.float32) |
|
|
| with self.assertRaisesRegexp(ValueError, 'num_spatial_bins should be >= 1'): |
| ops.position_sensitive_crop_regions( |
| image, boxes, crop_size, num_spatial_bins, global_pool=True) |
|
|
| def test_raise_value_error_on_non_divisible_crop_size(self): |
| num_spatial_bins = [2, 3] |
| image_shape = [1, 1, 6] |
| crop_size = [3, 2] |
|
|
| image = tf.constant(1, dtype=tf.float32, shape=image_shape) |
| boxes = tf.constant([[0, 0, 1, 1]], dtype=tf.float32) |
|
|
| with self.assertRaisesRegexp( |
| ValueError, 'crop_size should be divisible by num_spatial_bins'): |
| ops.position_sensitive_crop_regions( |
| image, boxes, crop_size, num_spatial_bins, global_pool=True) |
|
|
| def test_raise_value_error_on_non_divisible_num_channels(self): |
| num_spatial_bins = [2, 2] |
| image_shape = [1, 1, 5] |
| crop_size = [2, 2] |
|
|
| image = tf.constant(1, dtype=tf.float32, shape=image_shape) |
| boxes = tf.constant([[0, 0, 1, 1]], dtype=tf.float32) |
|
|
| with self.assertRaisesRegexp( |
| ValueError, 'Dimension size must be evenly divisible by 4 but is 5'): |
| ops.position_sensitive_crop_regions( |
| image, boxes, crop_size, num_spatial_bins, global_pool=True) |
|
|
| def test_position_sensitive_with_global_pool_false(self): |
| num_spatial_bins = [3, 2] |
| image_shape = [3, 2, 6] |
| num_boxes = 2 |
|
|
| |
| image = tf.constant(range(1, 3 * 2 + 1) * 6, dtype=tf.float32, |
| shape=image_shape) |
| boxes = tf.random_uniform((num_boxes, 4)) |
|
|
| expected_output = [] |
|
|
| |
| expected_output.append(np.expand_dims( |
| np.tile(np.array([[1, 2], |
| [3, 4], |
| [5, 6]]), (num_boxes, 1, 1)), |
| axis=-1)) |
|
|
| |
| expected_output.append(np.expand_dims( |
| np.tile(np.array([[1, 1, 2, 2], |
| [1, 1, 2, 2], |
| [3, 3, 4, 4], |
| [3, 3, 4, 4], |
| [5, 5, 6, 6], |
| [5, 5, 6, 6]]), (num_boxes, 1, 1)), |
| axis=-1)) |
|
|
| for crop_size_mult in range(1, 3): |
| crop_size = [3 * crop_size_mult, 2 * crop_size_mult] |
| ps_crop = ops.position_sensitive_crop_regions( |
| image, boxes, crop_size, num_spatial_bins, global_pool=False) |
| with self.test_session() as sess: |
| output = sess.run(ps_crop) |
|
|
| self.assertAllEqual(output, expected_output[crop_size_mult - 1]) |
|
|
| def test_position_sensitive_with_global_pool_false_and_do_global_pool(self): |
| num_spatial_bins = [3, 2] |
| image_shape = [3, 2, 6] |
| num_boxes = 2 |
|
|
| |
| image = tf.constant(range(1, 3 * 2 + 1) * 6, dtype=tf.float32, |
| shape=image_shape) |
| boxes = tf.random_uniform((num_boxes, 4)) |
|
|
| expected_output = [] |
|
|
| |
| expected_output.append(np.mean( |
| np.expand_dims( |
| np.tile(np.array([[1, 2], |
| [3, 4], |
| [5, 6]]), (num_boxes, 1, 1)), |
| axis=-1), |
| axis=(1, 2), keepdims=True)) |
|
|
| |
| expected_output.append(np.mean( |
| np.expand_dims( |
| np.tile(np.array([[1, 1, 2, 2], |
| [1, 1, 2, 2], |
| [3, 3, 4, 4], |
| [3, 3, 4, 4], |
| [5, 5, 6, 6], |
| [5, 5, 6, 6]]), (num_boxes, 1, 1)), |
| axis=-1), |
| axis=(1, 2), keepdims=True)) |
|
|
| for crop_size_mult in range(1, 3): |
| crop_size = [3 * crop_size_mult, 2 * crop_size_mult] |
|
|
| |
| |
| ps_crop = ops.position_sensitive_crop_regions( |
| image, boxes, crop_size, num_spatial_bins, global_pool=False) |
| ps_crop_and_pool = tf.reduce_mean( |
| ps_crop, reduction_indices=(1, 2), keep_dims=True) |
|
|
| with self.test_session() as sess: |
| output = sess.run(ps_crop_and_pool) |
|
|
| self.assertAllEqual(output, expected_output[crop_size_mult - 1]) |
|
|
| def test_raise_value_error_on_non_square_block_size(self): |
| num_spatial_bins = [3, 2] |
| image_shape = [3, 2, 6] |
| crop_size = [6, 2] |
|
|
| image = tf.constant(1, dtype=tf.float32, shape=image_shape) |
| boxes = tf.constant([[0, 0, 1, 1]], dtype=tf.float32) |
|
|
| with self.assertRaisesRegexp( |
| ValueError, 'Only support square bin crop size for now.'): |
| ops.position_sensitive_crop_regions( |
| image, boxes, crop_size, num_spatial_bins, global_pool=False) |
|
|
|
|
| class OpsTestBatchPositionSensitiveCropRegions(tf.test.TestCase): |
|
|
| def test_position_sensitive_with_single_bin(self): |
| num_spatial_bins = [1, 1] |
| image_shape = [2, 3, 3, 4] |
| crop_size = [2, 2] |
|
|
| image = tf.random_uniform(image_shape) |
| boxes = tf.random_uniform((2, 3, 4)) |
| box_ind = tf.constant([0, 0, 0, 1, 1, 1], dtype=tf.int32) |
|
|
| |
| |
| crop = tf.image.crop_and_resize(image, tf.reshape(boxes, [-1, 4]), box_ind, |
| crop_size) |
| crop_and_pool = tf.reduce_mean(crop, [1, 2], keepdims=True) |
| crop_and_pool = tf.reshape(crop_and_pool, [2, 3, 1, 1, 4]) |
|
|
| ps_crop_and_pool = ops.batch_position_sensitive_crop_regions( |
| image, boxes, crop_size, num_spatial_bins, global_pool=True) |
|
|
| with self.test_session() as sess: |
| expected_output, output = sess.run((crop_and_pool, ps_crop_and_pool)) |
| self.assertAllClose(output, expected_output) |
|
|
| def test_position_sensitive_with_global_pool_false_and_known_boxes(self): |
| num_spatial_bins = [2, 2] |
| image_shape = [2, 2, 2, 4] |
| crop_size = [2, 2] |
|
|
| images = tf.constant(range(1, 2 * 2 * 4 + 1) * 2, dtype=tf.float32, |
| shape=image_shape) |
|
|
| |
| boxes = tf.constant(np.array([[[0., 0., 1., 1.]], |
| [[0., 0., 0.5, 1.]]]), dtype=tf.float32) |
| |
|
|
| expected_output = [] |
|
|
| |
| expected_output.append( |
| np.reshape(np.array([[4, 7], |
| [10, 13]]), |
| (1, 2, 2, 1)) |
| ) |
|
|
| |
| expected_output.append( |
| np.reshape(np.array([[3, 6], |
| [7, 10]]), |
| (1, 2, 2, 1)) |
| ) |
| expected_output = np.stack(expected_output, axis=0) |
|
|
| ps_crop = ops.batch_position_sensitive_crop_regions( |
| images, boxes, crop_size, num_spatial_bins, global_pool=False) |
|
|
| with self.test_session() as sess: |
| output = sess.run(ps_crop) |
| self.assertAllEqual(output, expected_output) |
|
|
| def test_position_sensitive_with_global_pool_false_and_single_bin(self): |
| num_spatial_bins = [1, 1] |
| image_shape = [2, 3, 3, 4] |
| crop_size = [1, 1] |
|
|
| images = tf.random_uniform(image_shape) |
| boxes = tf.random_uniform((2, 3, 4)) |
| |
|
|
| |
| |
| ps_crop_and_pool = ops.batch_position_sensitive_crop_regions( |
| images, boxes, crop_size, num_spatial_bins, global_pool=True) |
| ps_crop = ops.batch_position_sensitive_crop_regions( |
| images, boxes, crop_size, num_spatial_bins, global_pool=False) |
|
|
| with self.test_session() as sess: |
| pooled_output, unpooled_output = sess.run((ps_crop_and_pool, ps_crop)) |
| self.assertAllClose(pooled_output, unpooled_output) |
|
|
|
|
| class ReframeBoxMasksToImageMasksTest(tf.test.TestCase): |
|
|
| def testZeroImageOnEmptyMask(self): |
| box_masks = tf.constant([[[0, 0], |
| [0, 0]]], dtype=tf.float32) |
| boxes = tf.constant([[0.0, 0.0, 1.0, 1.0]], dtype=tf.float32) |
| image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes, |
| image_height=4, |
| image_width=4) |
| np_expected_image_masks = np.array([[[0, 0, 0, 0], |
| [0, 0, 0, 0], |
| [0, 0, 0, 0], |
| [0, 0, 0, 0]]], dtype=np.float32) |
| with self.test_session() as sess: |
| np_image_masks = sess.run(image_masks) |
| self.assertAllClose(np_image_masks, np_expected_image_masks) |
|
|
| def testZeroBoxMasks(self): |
| box_masks = tf.zeros([0, 3, 3], dtype=tf.float32) |
| boxes = tf.zeros([0, 4], dtype=tf.float32) |
| image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes, |
| image_height=4, |
| image_width=4) |
| with self.test_session() as sess: |
| np_image_masks = sess.run(image_masks) |
| self.assertAllEqual(np_image_masks.shape, np.array([0, 4, 4])) |
|
|
| def testMaskIsCenteredInImageWhenBoxIsCentered(self): |
| box_masks = tf.constant([[[1, 1], |
| [1, 1]]], dtype=tf.float32) |
| boxes = tf.constant([[0.25, 0.25, 0.75, 0.75]], dtype=tf.float32) |
| image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes, |
| image_height=4, |
| image_width=4) |
| np_expected_image_masks = np.array([[[0, 0, 0, 0], |
| [0, 1, 1, 0], |
| [0, 1, 1, 0], |
| [0, 0, 0, 0]]], dtype=np.float32) |
| with self.test_session() as sess: |
| np_image_masks = sess.run(image_masks) |
| self.assertAllClose(np_image_masks, np_expected_image_masks) |
|
|
| def testMaskOffCenterRemainsOffCenterInImage(self): |
| box_masks = tf.constant([[[1, 0], |
| [0, 1]]], dtype=tf.float32) |
| boxes = tf.constant([[0.25, 0.5, 0.75, 1.0]], dtype=tf.float32) |
| image_masks = ops.reframe_box_masks_to_image_masks(box_masks, boxes, |
| image_height=4, |
| image_width=4) |
| np_expected_image_masks = np.array([[[0, 0, 0, 0], |
| [0, 0, 0.6111111, 0.16666669], |
| [0, 0, 0.3888889, 0.83333337], |
| [0, 0, 0, 0]]], dtype=np.float32) |
| with self.test_session() as sess: |
| np_image_masks = sess.run(image_masks) |
| self.assertAllClose(np_image_masks, np_expected_image_masks) |
|
|
|
|
| class MergeBoxesWithMultipleLabelsTest(tf.test.TestCase): |
|
|
| def testMergeBoxesWithMultipleLabels(self): |
| boxes = tf.constant( |
| [[0.25, 0.25, 0.75, 0.75], [0.0, 0.0, 0.5, 0.75], |
| [0.25, 0.25, 0.75, 0.75]], |
| dtype=tf.float32) |
| class_indices = tf.constant([0, 4, 2], dtype=tf.int32) |
| class_confidences = tf.constant([0.8, 0.2, 0.1], dtype=tf.float32) |
| num_classes = 5 |
| merged_boxes, merged_classes, merged_confidences, merged_box_indices = ( |
| ops.merge_boxes_with_multiple_labels( |
| boxes, class_indices, class_confidences, num_classes)) |
| expected_merged_boxes = np.array( |
| [[0.25, 0.25, 0.75, 0.75], [0.0, 0.0, 0.5, 0.75]], dtype=np.float32) |
| expected_merged_classes = np.array( |
| [[1, 0, 1, 0, 0], [0, 0, 0, 0, 1]], dtype=np.int32) |
| expected_merged_confidences = np.array( |
| [[0.8, 0, 0.1, 0, 0], [0, 0, 0, 0, 0.2]], dtype=np.float32) |
| expected_merged_box_indices = np.array([0, 1], dtype=np.int32) |
| with self.test_session() as sess: |
| (np_merged_boxes, np_merged_classes, np_merged_confidences, |
| np_merged_box_indices) = sess.run( |
| [merged_boxes, merged_classes, merged_confidences, |
| merged_box_indices]) |
| self.assertAllClose(np_merged_boxes, expected_merged_boxes) |
| self.assertAllClose(np_merged_classes, expected_merged_classes) |
| self.assertAllClose(np_merged_confidences, expected_merged_confidences) |
| self.assertAllClose(np_merged_box_indices, expected_merged_box_indices) |
|
|
| def testMergeBoxesWithMultipleLabelsCornerCase(self): |
| boxes = tf.constant( |
| [[0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1], |
| [1, 1, 1, 1], [1, 0, 1, 1], [0, 1, 1, 1], [0, 0, 1, 1]], |
| dtype=tf.float32) |
| class_indices = tf.constant([0, 1, 2, 3, 2, 1, 0, 3], dtype=tf.int32) |
| class_confidences = tf.constant([0.1, 0.9, 0.2, 0.8, 0.3, 0.7, 0.4, 0.6], |
| dtype=tf.float32) |
| num_classes = 4 |
| merged_boxes, merged_classes, merged_confidences, merged_box_indices = ( |
| ops.merge_boxes_with_multiple_labels( |
| boxes, class_indices, class_confidences, num_classes)) |
| expected_merged_boxes = np.array( |
| [[0, 0, 1, 1], [0, 1, 1, 1], [1, 0, 1, 1], [1, 1, 1, 1]], |
| dtype=np.float32) |
| expected_merged_classes = np.array( |
| [[1, 0, 0, 1], [1, 1, 0, 0], [0, 1, 1, 0], [0, 0, 1, 1]], |
| dtype=np.int32) |
| expected_merged_confidences = np.array( |
| [[0.1, 0, 0, 0.6], [0.4, 0.9, 0, 0], |
| [0, 0.7, 0.2, 0], [0, 0, 0.3, 0.8]], dtype=np.float32) |
| expected_merged_box_indices = np.array([0, 1, 2, 3], dtype=np.int32) |
| with self.test_session() as sess: |
| (np_merged_boxes, np_merged_classes, np_merged_confidences, |
| np_merged_box_indices) = sess.run( |
| [merged_boxes, merged_classes, merged_confidences, |
| merged_box_indices]) |
| self.assertAllClose(np_merged_boxes, expected_merged_boxes) |
| self.assertAllClose(np_merged_classes, expected_merged_classes) |
| self.assertAllClose(np_merged_confidences, expected_merged_confidences) |
| self.assertAllClose(np_merged_box_indices, expected_merged_box_indices) |
|
|
| def testMergeBoxesWithEmptyInputs(self): |
| boxes = tf.zeros([0, 4], dtype=tf.float32) |
| class_indices = tf.constant([], dtype=tf.int32) |
| class_confidences = tf.constant([], dtype=tf.float32) |
| num_classes = 5 |
| merged_boxes, merged_classes, merged_confidences, merged_box_indices = ( |
| ops.merge_boxes_with_multiple_labels( |
| boxes, class_indices, class_confidences, num_classes)) |
| with self.test_session() as sess: |
| (np_merged_boxes, np_merged_classes, np_merged_confidences, |
| np_merged_box_indices) = sess.run( |
| [merged_boxes, merged_classes, merged_confidences, |
| merged_box_indices]) |
| self.assertAllEqual(np_merged_boxes.shape, [0, 4]) |
| self.assertAllEqual(np_merged_classes.shape, [0, 5]) |
| self.assertAllEqual(np_merged_confidences.shape, [0, 5]) |
| self.assertAllEqual(np_merged_box_indices.shape, [0]) |
|
|
|
|
| class NearestNeighborUpsamplingTest(test_case.TestCase): |
|
|
| def test_upsampling_with_single_scale(self): |
|
|
| def graph_fn(inputs): |
| custom_op_output = ops.nearest_neighbor_upsampling(inputs, scale=2) |
| return custom_op_output |
| inputs = np.reshape(np.arange(4).astype(np.float32), [1, 2, 2, 1]) |
| custom_op_output = self.execute(graph_fn, [inputs]) |
|
|
| expected_output = [[[[0], [0], [1], [1]], |
| [[0], [0], [1], [1]], |
| [[2], [2], [3], [3]], |
| [[2], [2], [3], [3]]]] |
| self.assertAllClose(custom_op_output, expected_output) |
|
|
| def test_upsampling_with_separate_height_width_scales(self): |
|
|
| def graph_fn(inputs): |
| custom_op_output = ops.nearest_neighbor_upsampling(inputs, |
| height_scale=2, |
| width_scale=3) |
| return custom_op_output |
| inputs = np.reshape(np.arange(4).astype(np.float32), [1, 2, 2, 1]) |
| custom_op_output = self.execute(graph_fn, [inputs]) |
|
|
| expected_output = [[[[0], [0], [0], [1], [1], [1]], |
| [[0], [0], [0], [1], [1], [1]], |
| [[2], [2], [2], [3], [3], [3]], |
| [[2], [2], [2], [3], [3], [3]]]] |
| self.assertAllClose(custom_op_output, expected_output) |
|
|
|
|
| class MatmulGatherOnZerothAxis(test_case.TestCase): |
|
|
| def test_gather_2d(self): |
|
|
| def graph_fn(params, indices): |
| return ops.matmul_gather_on_zeroth_axis(params, indices) |
|
|
| params = np.array([[1, 2, 3, 4], |
| [5, 6, 7, 8], |
| [9, 10, 11, 12], |
| [0, 1, 0, 0]], dtype=np.float32) |
| indices = np.array([2, 2, 1], dtype=np.int32) |
| expected_output = np.array([[9, 10, 11, 12], [9, 10, 11, 12], [5, 6, 7, 8]]) |
| gather_output = self.execute(graph_fn, [params, indices]) |
| self.assertAllClose(gather_output, expected_output) |
|
|
| def test_gather_3d(self): |
|
|
| def graph_fn(params, indices): |
| return ops.matmul_gather_on_zeroth_axis(params, indices) |
|
|
| params = np.array([[[1, 2], [3, 4]], |
| [[5, 6], [7, 8]], |
| [[9, 10], [11, 12]], |
| [[0, 1], [0, 0]]], dtype=np.float32) |
| indices = np.array([0, 3, 1], dtype=np.int32) |
| expected_output = np.array([[[1, 2], [3, 4]], |
| [[0, 1], [0, 0]], |
| [[5, 6], [7, 8]]]) |
| gather_output = self.execute(graph_fn, [params, indices]) |
| self.assertAllClose(gather_output, expected_output) |
|
|
| def test_gather_with_many_indices(self): |
|
|
| def graph_fn(params, indices): |
| return ops.matmul_gather_on_zeroth_axis(params, indices) |
|
|
| params = np.array([[1, 2, 3, 4], |
| [5, 6, 7, 8], |
| [9, 10, 11, 12], |
| [0, 1, 0, 0]], dtype=np.float32) |
| indices = np.array([0, 0, 0, 0, 0, 0], dtype=np.int32) |
| expected_output = np.array(6*[[1, 2, 3, 4]]) |
| gather_output = self.execute(graph_fn, [params, indices]) |
| self.assertAllClose(gather_output, expected_output) |
|
|
| def test_gather_with_dynamic_shape_input(self): |
| params_placeholder = tf.placeholder(tf.float32, shape=[None, 4]) |
| indices_placeholder = tf.placeholder(tf.int32, shape=[None]) |
| gather_result = ops.matmul_gather_on_zeroth_axis( |
| params_placeholder, indices_placeholder) |
| params = np.array([[1, 2, 3, 4], |
| [5, 6, 7, 8], |
| [9, 10, 11, 12], |
| [0, 1, 0, 0]], dtype=np.float32) |
| indices = np.array([0, 0, 0, 0, 0, 0]) |
| expected_output = np.array(6*[[1, 2, 3, 4]]) |
| with self.test_session() as sess: |
| gather_output = sess.run(gather_result, feed_dict={ |
| params_placeholder: params, indices_placeholder: indices}) |
| self.assertAllClose(gather_output, expected_output) |
|
|
|
|
| class OpsTestMatMulCropAndResize(test_case.TestCase): |
|
|
| def testMatMulCropAndResize2x2To1x1(self): |
|
|
| def graph_fn(image, boxes): |
| return ops.matmul_crop_and_resize(image, boxes, crop_size=[1, 1]) |
|
|
| image = np.array([[[[1], [2]], [[3], [4]]]], dtype=np.float32) |
| boxes = np.array([[[0, 0, 1, 1]]], dtype=np.float32) |
| expected_output = [[[[[2.5]]]]] |
| crop_output = self.execute(graph_fn, [image, boxes]) |
| self.assertAllClose(crop_output, expected_output) |
|
|
| def testMatMulCropAndResize2x2To1x1Flipped(self): |
|
|
| def graph_fn(image, boxes): |
| return ops.matmul_crop_and_resize(image, boxes, crop_size=[1, 1]) |
|
|
| image = np.array([[[[1], [2]], [[3], [4]]]], dtype=np.float32) |
| boxes = np.array([[[1, 1, 0, 0]]], dtype=np.float32) |
| expected_output = [[[[[2.5]]]]] |
| crop_output = self.execute(graph_fn, [image, boxes]) |
| self.assertAllClose(crop_output, expected_output) |
|
|
| def testMatMulCropAndResize2x2To3x3(self): |
|
|
| def graph_fn(image, boxes): |
| return ops.matmul_crop_and_resize(image, boxes, crop_size=[3, 3]) |
|
|
| image = np.array([[[[1], [2]], [[3], [4]]]], dtype=np.float32) |
| boxes = np.array([[[0, 0, 1, 1]]], dtype=np.float32) |
| expected_output = [[[[[1.0], [1.5], [2.0]], |
| [[2.0], [2.5], [3.0]], |
| [[3.0], [3.5], [4.0]]]]] |
| crop_output = self.execute(graph_fn, [image, boxes]) |
| self.assertAllClose(crop_output, expected_output) |
|
|
| def testMatMulCropAndResize2x2To3x3Flipped(self): |
|
|
| def graph_fn(image, boxes): |
| return ops.matmul_crop_and_resize(image, boxes, crop_size=[3, 3]) |
|
|
| image = np.array([[[[1], [2]], [[3], [4]]]], dtype=np.float32) |
| boxes = np.array([[[1, 1, 0, 0]]], dtype=np.float32) |
| expected_output = [[[[[4.0], [3.5], [3.0]], |
| [[3.0], [2.5], [2.0]], |
| [[2.0], [1.5], [1.0]]]]] |
| crop_output = self.execute(graph_fn, [image, boxes]) |
| self.assertAllClose(crop_output, expected_output) |
|
|
| def testMatMulCropAndResize3x3To2x2(self): |
|
|
| def graph_fn(image, boxes): |
| return ops.matmul_crop_and_resize(image, boxes, crop_size=[2, 2]) |
|
|
| image = np.array([[[[1], [2], [3]], |
| [[4], [5], [6]], |
| [[7], [8], [9]]]], dtype=np.float32) |
| boxes = np.array([[[0, 0, 1, 1], |
| [0, 0, .5, .5]]], dtype=np.float32) |
| expected_output = [[[[[1], [3]], [[7], [9]]], |
| [[[1], [2]], [[4], [5]]]]] |
| crop_output = self.execute(graph_fn, [image, boxes]) |
| self.assertAllClose(crop_output, expected_output) |
|
|
| def testMatMulCropAndResize3x3To2x2_2Channels(self): |
|
|
| def graph_fn(image, boxes): |
| return ops.matmul_crop_and_resize(image, boxes, crop_size=[2, 2]) |
|
|
| image = np.array([[[[1, 0], [2, 1], [3, 2]], |
| [[4, 3], [5, 4], [6, 5]], |
| [[7, 6], [8, 7], [9, 8]]]], dtype=np.float32) |
| boxes = np.array([[[0, 0, 1, 1], |
| [0, 0, .5, .5]]], dtype=np.float32) |
| expected_output = [[[[[1, 0], [3, 2]], [[7, 6], [9, 8]]], |
| [[[1, 0], [2, 1]], [[4, 3], [5, 4]]]]] |
| crop_output = self.execute(graph_fn, [image, boxes]) |
| self.assertAllClose(crop_output, expected_output) |
|
|
| def testBatchMatMulCropAndResize3x3To2x2_2Channels(self): |
|
|
| def graph_fn(image, boxes): |
| return ops.matmul_crop_and_resize(image, boxes, crop_size=[2, 2]) |
|
|
| image = np.array([[[[1, 0], [2, 1], [3, 2]], |
| [[4, 3], [5, 4], [6, 5]], |
| [[7, 6], [8, 7], [9, 8]]], |
| [[[1, 0], [2, 1], [3, 2]], |
| [[4, 3], [5, 4], [6, 5]], |
| [[7, 6], [8, 7], [9, 8]]]], dtype=np.float32) |
| boxes = np.array([[[0, 0, 1, 1], |
| [0, 0, .5, .5]], |
| [[1, 1, 0, 0], |
| [.5, .5, 0, 0]]], dtype=np.float32) |
| expected_output = [[[[[1, 0], [3, 2]], [[7, 6], [9, 8]]], |
| [[[1, 0], [2, 1]], [[4, 3], [5, 4]]]], |
| [[[[9, 8], [7, 6]], [[3, 2], [1, 0]]], |
| [[[5, 4], [4, 3]], [[2, 1], [1, 0]]]]] |
| crop_output = self.execute(graph_fn, [image, boxes]) |
| self.assertAllClose(crop_output, expected_output) |
|
|
| def testMatMulCropAndResize3x3To2x2Flipped(self): |
|
|
| def graph_fn(image, boxes): |
| return ops.matmul_crop_and_resize(image, boxes, crop_size=[2, 2]) |
|
|
| image = np.array([[[[1], [2], [3]], |
| [[4], [5], [6]], |
| [[7], [8], [9]]]], dtype=np.float32) |
| boxes = np.array([[[1, 1, 0, 0], |
| [.5, .5, 0, 0]]], dtype=np.float32) |
| expected_output = [[[[[9], [7]], [[3], [1]]], |
| [[[5], [4]], [[2], [1]]]]] |
| crop_output = self.execute(graph_fn, [image, boxes]) |
| self.assertAllClose(crop_output, expected_output) |
|
|
| def testInvalidInputShape(self): |
| image = tf.constant([[[1], [2]], [[3], [4]]], dtype=tf.float32) |
| boxes = tf.constant([[-1, -1, 1, 1]], dtype=tf.float32) |
| crop_size = [4, 4] |
| with self.assertRaises(ValueError): |
| _ = ops.matmul_crop_and_resize(image, boxes, crop_size) |
|
|
|
|
| class OpsTestCropAndResize(test_case.TestCase): |
|
|
| def testBatchCropAndResize3x3To2x2_2Channels(self): |
|
|
| def graph_fn(image, boxes): |
| return ops.native_crop_and_resize(image, boxes, crop_size=[2, 2]) |
|
|
| image = np.array([[[[1, 0], [2, 1], [3, 2]], |
| [[4, 3], [5, 4], [6, 5]], |
| [[7, 6], [8, 7], [9, 8]]], |
| [[[1, 0], [2, 1], [3, 2]], |
| [[4, 3], [5, 4], [6, 5]], |
| [[7, 6], [8, 7], [9, 8]]]], dtype=np.float32) |
| boxes = np.array([[[0, 0, 1, 1], |
| [0, 0, .5, .5]], |
| [[1, 1, 0, 0], |
| [.5, .5, 0, 0]]], dtype=np.float32) |
| expected_output = [[[[[1, 0], [3, 2]], [[7, 6], [9, 8]]], |
| [[[1, 0], [2, 1]], [[4, 3], [5, 4]]]], |
| [[[[9, 8], [7, 6]], [[3, 2], [1, 0]]], |
| [[[5, 4], [4, 3]], [[2, 1], [1, 0]]]]] |
| crop_output = self.execute_cpu(graph_fn, [image, boxes]) |
| self.assertAllClose(crop_output, expected_output) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| if __name__ == '__main__': |
| tf.test.main() |
|
|