|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""Image utilities.""" |
|
|
|
import numpy as np |
|
import PIL.Image |
|
import torch |
|
|
|
|
|
def im_resize(img, size=None, scale=None, mode="linear"): |
|
"""Resize image by the scale or size.""" |
|
if size is None: |
|
if not isinstance(scale, (tuple, list)): |
|
scale = (scale, scale) |
|
h, w = img.shape[:2] |
|
size = int(h * scale[0] + 0.5), int(w * scale[1] + 0.5) |
|
else: |
|
if not isinstance(size, (tuple, list)): |
|
size = (size, size) |
|
resize_modes = {"linear": PIL.Image.BILINEAR} |
|
from torchvision.transforms import ToPILImage |
|
|
|
to_pil = ToPILImage() |
|
img = to_pil(img.to(torch.float32).cpu()) |
|
|
|
return np.array(img.resize(size[::-1], resize_modes[mode])) |
|
|
|
|
|
def im_rescale(img, scales, max_size=0): |
|
"""Rescale image to match the detecting scales.""" |
|
im_shape = img.shape |
|
img_list, img_scales = [], [] |
|
size_min = np.min(im_shape[:2]) |
|
size_max = np.max(im_shape[:2]) |
|
for target_size in scales: |
|
im_scale = float(target_size) / float(size_min) |
|
target_size_max = max_size if max_size > 0 else target_size |
|
if np.round(im_scale * size_max) > target_size_max: |
|
im_scale = float(target_size_max) / float(size_max) |
|
img_list.append(im_resize(img, scale=im_scale)) |
|
img_scales.append((im_scale, im_scale)) |
|
return img_list, img_scales |
|
|
|
|
|
def im_vstack(arrays, fill_value=None, dtype=None, size=None, align=None): |
|
"""Stack image arrays in sequence vertically.""" |
|
if fill_value is None: |
|
return np.vstack(arrays) |
|
|
|
max_shape = np.max(np.stack([arr.shape for arr in arrays]), 0) |
|
if size is not None and min(size) > 0: |
|
max_shape[: len(size)] = size |
|
if align is not None and min(align) > 0: |
|
align_size = np.ceil(max_shape[: len(align)] / align) |
|
max_shape[: len(align)] = align_size.astype("int64") * align |
|
|
|
output_dtype = dtype or arrays[0].dtype |
|
output_shape = [len(arrays)] + list(max_shape) |
|
output = np.empty(output_shape, output_dtype) |
|
output[:] = fill_value |
|
|
|
for i, arr in enumerate(arrays): |
|
copy_slices = (slice(0, d) for d in arr.shape) |
|
output[(i,) + tuple(copy_slices)] = arr |
|
return output |
|
|