Spaces:
Sleeping
Sleeping
| # Copyright 2023 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. | |
| """Generates fake feature for testing and validation.""" | |
| import collections | |
| from typing import Optional, Tuple, Union | |
| import numpy as np | |
| _RGB_CHANNELS = 3 | |
| def generate_image_np(height: int, | |
| width: int, | |
| num_channels: int = _RGB_CHANNELS) -> np.ndarray: | |
| """Returns a fake numpy image matrix array.""" | |
| return np.reshape( | |
| np.mod(np.arange(height * width * num_channels), 255).astype(np.uint8), | |
| newshape=(height, width, num_channels)) | |
| def generate_normalized_boxes_np(num_boxes: int) -> np.ndarray: | |
| """Returns a fake numpy normalized boxes array.""" | |
| xmins = np.reshape(np.arange(num_boxes) / (2 * num_boxes), (num_boxes, 1)) | |
| ymins = np.reshape(np.arange(num_boxes) / (2 * num_boxes), (num_boxes, 1)) | |
| xmaxs = xmins + .5 | |
| ymaxs = ymins + .5 | |
| return np.concatenate((ymins, xmins, ymaxs, xmaxs), axis=-1) | |
| def generate_boxes_np(height: int, width: int, num_boxes: int) -> np.ndarray: | |
| """Returns a fake numpy absolute boxes array.""" | |
| normalized_boxes = generate_normalized_boxes_np(num_boxes) | |
| normalized_boxes[:, 1::2] *= height | |
| normalized_boxes[:, 0::2] *= width | |
| return normalized_boxes | |
| def generate_classes_np(num_classes: int, | |
| size: Optional[int] = None) -> Union[int, np.ndarray]: | |
| """Returns a fake class or a fake numpy classes array.""" | |
| if size is None: | |
| return num_classes - 1 | |
| return np.arange(size) % num_classes | |
| def generate_confidences_np( | |
| size: Optional[int] = None) -> Union[float, np.ndarray]: | |
| """Returns a fake confidence score or a fake numpy confidence score array.""" | |
| if size is None: | |
| return 0.5 | |
| return np.arange(size) / size | |
| def generate_instance_masks_np(height: int, | |
| width: int, | |
| boxes_np: np.ndarray, | |
| normalized: bool = True) -> np.ndarray: | |
| """Returns a fake numpy instance mask matrices array.""" | |
| num_boxes = len(boxes_np) | |
| instance_masks_np = np.zeros((num_boxes, height, width, 1)) | |
| if normalized: | |
| boxes_np[:, 1::2] *= height | |
| boxes_np[:, ::2] *= width | |
| xmins = boxes_np[:, 0].astype(int) | |
| ymins = boxes_np[:, 1].astype(int) | |
| box_widths = boxes_np[:, 2].astype(int) - xmins | |
| box_heights = boxes_np[:, 3].astype(int) - ymins | |
| for i, (x, y, w, h) in enumerate(zip(xmins, ymins, box_widths, box_heights)): | |
| instance_masks_np[i, y:y + h, x:x + w, :] = np.reshape( | |
| np.mod(np.arange(h * w), 2).astype(np.uint8), newshape=(h, w, 1)) | |
| return instance_masks_np | |
| def generate_semantic_mask_np(height: int, width: int, | |
| num_classes: int) -> np.ndarray: | |
| """Returns a fake numpy semantic mask array.""" | |
| return generate_image_np(height, width, num_channels=1) % num_classes | |
| def generate_panoptic_masks_np( | |
| semantic_mask: np.ndarray, instance_masks: np.ndarray, | |
| instance_classes: np.ndarray, | |
| stuff_classes_offset: int) -> Tuple[np.ndarray, np.ndarray]: | |
| """Returns fake numpy panoptic category and instance mask arrays.""" | |
| panoptic_category_mask = np.zeros_like(semantic_mask) | |
| panoptic_instance_mask = np.zeros_like(semantic_mask) | |
| instance_ids = collections.defaultdict(int) | |
| for instance_mask, instance_class in zip(instance_masks, instance_classes): | |
| if instance_class == 0: | |
| continue | |
| instance_ids[instance_class] += 1 | |
| # If a foreground pixel is labelled previously, replace the old category | |
| # class and instance ID with the new one. | |
| foreground_indices = np.where(np.equal(instance_mask, 1)) | |
| # Note that instance class start from index 1. | |
| panoptic_category_mask[foreground_indices] = instance_class + 1 | |
| panoptic_instance_mask[foreground_indices] = instance_ids[instance_class] | |
| # If there are pixels remains unlablled (labelled as background), then the | |
| # semantic labels will be used (if it has one). | |
| # Note that in panoptic FPN, the panoptic labels are expected in this order, | |
| # 0 (background), 1 ..., N (stuffs), N + 1, ..., N + M - 2 (things) | |
| # N classes for stuff classes, without background class, and M classes for | |
| # thing classes, with 0 representing the background class and 1 representing | |
| # all stuff classes. | |
| background_indices = np.where(np.equal(panoptic_category_mask, 0)) | |
| panoptic_category_mask[background_indices] = ( | |
| semantic_mask[background_indices] + stuff_classes_offset) | |
| return panoptic_category_mask, panoptic_instance_mask | |