Download utils/formatting_utils.py from ICML2022/resefa: direct link, hf CLI and curl.
- Browser
- Download file 5.9 kB
-
https://huggingface.co/spaces/ICML2022/resefa/resolve/main/utils/formatting_utils.py
- Command line
-
hf download hf://spaces/ICML2022/resefa/utils/formatting_utils.py
-
curl -L -o formatting_utils.py https://huggingface.co/spaces/ICML2022/resefa/resolve/main/utils/formatting_utils.py
5.9 kB
| # python3.7 | |
| """Contains utility functions used for formatting.""" | |
| import cv2 | |
| import numpy as np | |
| __all__ = [ | |
| 'format_time', 'format_range', 'format_image_size', 'format_image', | |
| 'raw_label_to_one_hot', 'one_hot_to_raw_label' | |
| ] | |
| def format_time(seconds): | |
| """Formats seconds to readable time string. | |
| Args: | |
| seconds: Number of seconds to format. | |
| Returns: | |
| The formatted time string. | |
| Raises: | |
| ValueError: If the input `seconds` is less than 0. | |
| """ | |
| if seconds < 0: | |
| raise ValueError(f'Input `seconds` should be greater than or equal to ' | |
| f'0, but `{seconds}` is received!') | |
| # Returns seconds as float if less than 1 minute. | |
| if seconds < 10: | |
| return f'{seconds:7.3f} s' | |
| if seconds < 60: | |
| return f'{seconds:7.2f} s' | |
| seconds = int(seconds + 0.5) | |
| days, seconds = divmod(seconds, 86400) | |
| hours, seconds = divmod(seconds, 3600) | |
| minutes, seconds = divmod(seconds, 60) | |
| if days: | |
| return f'{days:2d} d {hours:02d} h' | |
| if hours: | |
| return f'{hours:2d} h {minutes:02d} m' | |
| return f'{minutes:2d} m {seconds:02d} s' | |
| def format_range(obj, min_val=None, max_val=None): | |
| """Formats the given object to a valid range. | |
| If `min_val` or `max_val` is provided, both the starting value and the end | |
| value will be clamped to range `[min_val, max_val]`. | |
| NOTE: (a, b) is regarded as a valid range if and only if `a <= b`. | |
| Args: | |
| obj: The input object to format. | |
| min_val: The minimum value to cut off the input range. If not provided, | |
| the default minimum value is negative infinity. (default: None) | |
| max_val: The maximum value to cut off the input range. If not provided, | |
| the default maximum value is infinity. (default: None) | |
| Returns: | |
| A two-elements tuple, indicating the start and the end of the range. | |
| Raises: | |
| ValueError: If the input object is an invalid range. | |
| """ | |
| if not isinstance(obj, (tuple, list)): | |
| raise ValueError(f'Input object must be a tuple or a list, ' | |
| f'but `{type(obj)}` received!') | |
| if len(obj) != 2: | |
| raise ValueError(f'Input object is expected to contain two elements, ' | |
| f'but `{len(obj)}` received!') | |
| if obj[0] > obj[1]: | |
| raise ValueError(f'The second element is expected to be equal to or ' | |
| f'greater than the first one, ' | |
| f'but `({obj[0]}, {obj[1]})` received!') | |
| obj = list(obj) | |
| if min_val is not None: | |
| obj[0] = max(obj[0], min_val) | |
| obj[1] = max(obj[1], min_val) | |
| if max_val is not None: | |
| obj[0] = min(obj[0], max_val) | |
| obj[1] = min(obj[1], max_val) | |
| return tuple(obj) | |
| def format_image_size(size): | |
| """Formats the given image size to a two-element tuple. | |
| A valid image size can be an integer, indicating both the height and the | |
| width, OR can be a two-element list or tuple. Both height and width are | |
| assumed to be positive integer. | |
| Args: | |
| size: The input size to format. | |
| Returns: | |
| A two-elements tuple, indicating the height and the width, respectively. | |
| Raises: | |
| ValueError: If the input size is invalid. | |
| """ | |
| if not isinstance(size, (int, tuple, list)): | |
| raise ValueError(f'Input size must be an integer, a tuple, or a list, ' | |
| f'but `{type(size)}` received!') | |
| if isinstance(size, int): | |
| size = (size, size) | |
| else: | |
| if len(size) == 1: | |
| size = (size[0], size[0]) | |
| if not len(size) == 2: | |
| raise ValueError(f'Input size is expected to have two numbers at ' | |
| f'most, but `{len(size)}` numbers received!') | |
| if not isinstance(size[0], int) or size[0] < 0: | |
| raise ValueError(f'The height is expected to be a non-negative ' | |
| f'integer, but `{size[0]}` received!') | |
| if not isinstance(size[1], int) or size[1] < 0: | |
| raise ValueError(f'The width is expected to be a non-negative ' | |
| f'integer, but `{size[1]}` received!') | |
| return tuple(size) | |
| def format_image(image): | |
| """Formats an image read from `cv2`. | |
| NOTE: This function will always return a 3-dimensional image (i.e., with | |
| shape [H, W, C]) in pixel range [0, 255]. For color images, the channel | |
| order of the input is expected to be with `BGR` or `BGRA`, which is the | |
| raw image decoded by `cv2`; while the channel order of the output is set to | |
| `RGB` or `RGBA` by default. | |
| Args: | |
| image: `np.ndarray`, an image read by `cv2.imread()` or | |
| `cv2.imdecode()`. | |
| Returns: | |
| An image with shape [H, W, C] (where `C = 1` for grayscale image). | |
| """ | |
| if image.ndim == 2: # add additional axis if given a grayscale image | |
| image = image[:, :, np.newaxis] | |
| assert isinstance(image, np.ndarray) | |
| assert image.dtype == np.uint8 | |
| assert image.ndim == 3 and image.shape[2] in [1, 3, 4] | |
| if image.shape[2] == 3: # BGR image | |
| return cv2.cvtColor(image, cv2.COLOR_BGR2RGB) | |
| if image.shape[2] == 4: # BGRA image | |
| return cv2.cvtColor(image, cv2.COLOR_BGRA2RGBA) | |
| return image | |
| def raw_label_to_one_hot(raw_label, num_classes): | |
| """Converts a single label into one-hot vector. | |
| Args: | |
| raw_label: The raw label. | |
| num_classes: Total number of classes. | |
| Returns: | |
| one-hot vector of the given raw label. | |
| """ | |
| one_hot = np.zeros(num_classes, dtype=np.float32) | |
| one_hot[raw_label] = 1.0 | |
| return one_hot | |
| def one_hot_to_raw_label(one_hot): | |
| """Converts a one-hot vector to a single value label. | |
| Args: | |
| one_hot: `np.ndarray`, a one-hot encoded vector. | |
| Returns: | |
| A single integer to represent the category. | |
| """ | |
| return np.argmax(one_hot) | |