Spaces:
Runtime error
Runtime error
# 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 | |