Download object_detection/utils/test_utils.py from pat229988/DR-App: direct link, hf CLI and curl.
- Browser
- Download file 7.74 kB
-
https://huggingface.co/spaces/pat229988/DR-App/resolve/main/object_detection/utils/test_utils.py
- Command line
-
hf download hf://spaces/pat229988/DR-App/object_detection/utils/test_utils.py
-
curl -L -o test_utils.py https://huggingface.co/spaces/pat229988/DR-App/resolve/main/object_detection/utils/test_utils.py
7.74 kB
| # Copyright 2017 The TensorFlow Authors. All Rights Reserved. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # ============================================================================== | |
| """Contains functions which are convenient for unit testing.""" | |
| import numpy as np | |
| import tensorflow as tf | |
| from object_detection.core import anchor_generator | |
| from object_detection.core import box_coder | |
| from object_detection.core import box_list | |
| from object_detection.core import box_predictor | |
| from object_detection.core import matcher | |
| from object_detection.utils import shape_utils | |
| # Default size (both width and height) used for testing mask predictions. | |
| DEFAULT_MASK_SIZE = 5 | |
| class MockBoxCoder(box_coder.BoxCoder): | |
| """Simple `difference` BoxCoder.""" | |
| def code_size(self): | |
| return 4 | |
| def _encode(self, boxes, anchors): | |
| return boxes.get() - anchors.get() | |
| def _decode(self, rel_codes, anchors): | |
| return box_list.BoxList(rel_codes + anchors.get()) | |
| class MockMaskHead(object): | |
| """Simple maskhead that returns all zeros as mask predictions.""" | |
| def __init__(self, num_classes): | |
| self._num_classes = num_classes | |
| def predict(self, features): | |
| batch_size = tf.shape(features)[0] | |
| return tf.zeros((batch_size, 1, self._num_classes, DEFAULT_MASK_SIZE, | |
| DEFAULT_MASK_SIZE), | |
| dtype=tf.float32) | |
| class MockBoxPredictor(box_predictor.BoxPredictor): | |
| """Simple box predictor that ignores inputs and outputs all zeros.""" | |
| def __init__(self, is_training, num_classes, add_background_class=True): | |
| super(MockBoxPredictor, self).__init__(is_training, num_classes) | |
| self._add_background_class = add_background_class | |
| def _predict(self, image_features, num_predictions_per_location): | |
| image_feature = image_features[0] | |
| combined_feature_shape = shape_utils.combined_static_and_dynamic_shape( | |
| image_feature) | |
| batch_size = combined_feature_shape[0] | |
| num_anchors = (combined_feature_shape[1] * combined_feature_shape[2]) | |
| code_size = 4 | |
| zero = tf.reduce_sum(0 * image_feature) | |
| num_class_slots = self.num_classes | |
| if self._add_background_class: | |
| num_class_slots = num_class_slots + 1 | |
| box_encodings = zero + tf.zeros( | |
| (batch_size, num_anchors, 1, code_size), dtype=tf.float32) | |
| class_predictions_with_background = zero + tf.zeros( | |
| (batch_size, num_anchors, num_class_slots), dtype=tf.float32) | |
| predictions_dict = { | |
| box_predictor.BOX_ENCODINGS: | |
| box_encodings, | |
| box_predictor.CLASS_PREDICTIONS_WITH_BACKGROUND: | |
| class_predictions_with_background | |
| } | |
| return predictions_dict | |
| class MockKerasBoxPredictor(box_predictor.KerasBoxPredictor): | |
| """Simple box predictor that ignores inputs and outputs all zeros.""" | |
| def __init__(self, is_training, num_classes, add_background_class=True): | |
| super(MockKerasBoxPredictor, self).__init__( | |
| is_training, num_classes, False, False) | |
| self._add_background_class = add_background_class | |
| def _predict(self, image_features, **kwargs): | |
| image_feature = image_features[0] | |
| combined_feature_shape = shape_utils.combined_static_and_dynamic_shape( | |
| image_feature) | |
| batch_size = combined_feature_shape[0] | |
| num_anchors = (combined_feature_shape[1] * combined_feature_shape[2]) | |
| code_size = 4 | |
| zero = tf.reduce_sum(0 * image_feature) | |
| num_class_slots = self.num_classes | |
| if self._add_background_class: | |
| num_class_slots = num_class_slots + 1 | |
| box_encodings = zero + tf.zeros( | |
| (batch_size, num_anchors, 1, code_size), dtype=tf.float32) | |
| class_predictions_with_background = zero + tf.zeros( | |
| (batch_size, num_anchors, num_class_slots), dtype=tf.float32) | |
| predictions_dict = { | |
| box_predictor.BOX_ENCODINGS: | |
| box_encodings, | |
| box_predictor.CLASS_PREDICTIONS_WITH_BACKGROUND: | |
| class_predictions_with_background | |
| } | |
| return predictions_dict | |
| class MockAnchorGenerator(anchor_generator.AnchorGenerator): | |
| """Mock anchor generator.""" | |
| def name_scope(self): | |
| return 'MockAnchorGenerator' | |
| def num_anchors_per_location(self): | |
| return [1] | |
| def _generate(self, feature_map_shape_list): | |
| num_anchors = sum([shape[0] * shape[1] for shape in feature_map_shape_list]) | |
| return box_list.BoxList(tf.zeros((num_anchors, 4), dtype=tf.float32)) | |
| class MockMatcher(matcher.Matcher): | |
| """Simple matcher that matches first anchor to first groundtruth box.""" | |
| def _match(self, similarity_matrix, valid_rows): | |
| return tf.constant([0, -1, -1, -1], dtype=tf.int32) | |
| def create_diagonal_gradient_image(height, width, depth): | |
| """Creates pyramid image. Useful for testing. | |
| For example, pyramid_image(5, 6, 1) looks like: | |
| # [[[ 5. 4. 3. 2. 1. 0.] | |
| # [ 6. 5. 4. 3. 2. 1.] | |
| # [ 7. 6. 5. 4. 3. 2.] | |
| # [ 8. 7. 6. 5. 4. 3.] | |
| # [ 9. 8. 7. 6. 5. 4.]]] | |
| Args: | |
| height: height of image | |
| width: width of image | |
| depth: depth of image | |
| Returns: | |
| pyramid image | |
| """ | |
| row = np.arange(height) | |
| col = np.arange(width)[::-1] | |
| image_layer = np.expand_dims(row, 1) + col | |
| image_layer = np.expand_dims(image_layer, 2) | |
| image = image_layer | |
| for i in range(1, depth): | |
| image = np.concatenate((image, image_layer * pow(10, i)), 2) | |
| return image.astype(np.float32) | |
| def create_random_boxes(num_boxes, max_height, max_width): | |
| """Creates random bounding boxes of specific maximum height and width. | |
| Args: | |
| num_boxes: number of boxes. | |
| max_height: maximum height of boxes. | |
| max_width: maximum width of boxes. | |
| Returns: | |
| boxes: numpy array of shape [num_boxes, 4]. Each row is in form | |
| [y_min, x_min, y_max, x_max]. | |
| """ | |
| y_1 = np.random.uniform(size=(1, num_boxes)) * max_height | |
| y_2 = np.random.uniform(size=(1, num_boxes)) * max_height | |
| x_1 = np.random.uniform(size=(1, num_boxes)) * max_width | |
| x_2 = np.random.uniform(size=(1, num_boxes)) * max_width | |
| boxes = np.zeros(shape=(num_boxes, 4)) | |
| boxes[:, 0] = np.minimum(y_1, y_2) | |
| boxes[:, 1] = np.minimum(x_1, x_2) | |
| boxes[:, 2] = np.maximum(y_1, y_2) | |
| boxes[:, 3] = np.maximum(x_1, x_2) | |
| return boxes.astype(np.float32) | |
| def first_rows_close_as_set(a, b, k=None, rtol=1e-6, atol=1e-6): | |
| """Checks if first K entries of two lists are close, up to permutation. | |
| Inputs to this assert are lists of items which can be compared via | |
| numpy.allclose(...) and can be sorted. | |
| Args: | |
| a: list of items which can be compared via numpy.allclose(...) and are | |
| sortable. | |
| b: list of items which can be compared via numpy.allclose(...) and are | |
| sortable. | |
| k: a non-negative integer. If not provided, k is set to be len(a). | |
| rtol: relative tolerance. | |
| atol: absolute tolerance. | |
| Returns: | |
| boolean, True if input lists a and b have the same length and | |
| the first k entries of the inputs satisfy numpy.allclose() after | |
| sorting entries. | |
| """ | |
| if not isinstance(a, list) or not isinstance(b, list) or len(a) != len(b): | |
| return False | |
| if not k: | |
| k = len(a) | |
| k = min(k, len(a)) | |
| a_sorted = sorted(a[:k]) | |
| b_sorted = sorted(b[:k]) | |
| return all([ | |
| np.allclose(entry_a, entry_b, rtol, atol) | |
| for (entry_a, entry_b) in zip(a_sorted, b_sorted) | |
| ]) | |