Source code for chainercv.transforms.image.resize_contain

from __future__ import division
import numpy as np
import PIL

from chainercv.transforms import resize


[docs]def resize_contain(img, size, fill=0, interpolation=PIL.Image.BILINEAR, return_param=False): """Resize the image to fit in the given area while keeping aspect ratio. If both the height and the width in :obj:`size` are larger than the height and the width of the :obj:`img`, the :obj:`img` is placed on the center with an appropriate padding to match :obj:`size`. Otherwise, the input image is scaled to fit in a canvas whose size is :obj:`size` while preserving aspect ratio. Args: img (~numpy.ndarray): An array to be transformed. This is in CHW format. size (tuple of two ints): A tuple of two elements: :obj:`height, width`. The size of the image after resizing. fill (float, tuple or ~numpy.ndarray): The value of padded pixels. If it is :class:`numpy.ndarray`, its shape should be :math:`(C, 1, 1)`, where :math:`C` is the number of channels of :obj:`img`. interpolation (int): Determines sampling strategy. This is one of :obj:`PIL.Image.NEAREST`, :obj:`PIL.Image.BILINEAR`, :obj:`PIL.Image.BICUBIC`, :obj:`PIL.Image.LANCZOS`. Bilinear interpolation is the default strategy. return_param (bool): Returns information of resizing and offsetting. Returns: ~numpy.ndarray or (~numpy.ndarray, dict): If :obj:`return_param = False`, returns an array :obj:`out_img` that is the result of resizing. If :obj:`return_param = True`, returns a tuple whose elements are :obj:`out_img, param`. :obj:`param` is a dictionary of intermediate parameters whose contents are listed below with key, value-type and the description of the value. * **y_offset** (*int*): The y coodinate of the top left corner of\ the image after placing on the canvas. * **x_offset** (*int*): The x coordinate of the top left corner\ of the image after placing on the canvas. * **scaled_size** (*tuple*): The size to which the image is scaled\ to before placing it on a canvas. This is a tuple of two elements:\ :obj:`height, width`. """ C, H, W = img.shape out_H, out_W = size scale_h = out_H / H scale_w = out_W / W scale = min(min(scale_h, scale_w), 1) scaled_size = (int(H * scale), int(W * scale)) if scale < 1: img = resize(img, scaled_size, interpolation) y_slice, x_slice = _get_pad_slice(img, size=size) out_img = np.empty((C, out_H, out_W), dtype=img.dtype) out_img[:] = np.array(fill).reshape((-1, 1, 1)) out_img[:, y_slice, x_slice] = img if return_param: param = {'y_offset': y_slice.start, 'x_offset': x_slice.start, 'scaled_size': scaled_size} return out_img, param else: return out_img
def _get_pad_slice(img, size): """Get slices needed for padding. Args: img (~numpy.ndarray): This image is in format CHW. size (tuple of two ints): (max_H, max_W). """ _, H, W = img.shape if H < size[0]: margin_y = (size[0] - H) // 2 else: margin_y = 0 y_slice = slice(margin_y, margin_y + H) if W < size[1]: margin_x = (size[1] - W) // 2 else: margin_x = 0 x_slice = slice(margin_x, margin_x + W) return y_slice, x_slice