1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
import numpy as np
import PIL.Image
from . import utils
try:
import cv2
except ImportError:
cv2 = None # type: ignore
def _resize_pillow(src, height, width, interpolation):
if interpolation == "linear":
interpolation = PIL.Image.BILINEAR
elif interpolation == "nearest":
interpolation = PIL.Image.NEAREST
else:
raise ValueError("unsupported interpolation: {}".format(interpolation))
if np.issubdtype(src.dtype, np.integer):
dst = utils.numpy_to_pillow(src)
dst = dst.resize((width, height), resample=interpolation)
dst = utils.pillow_to_numpy(dst)
else:
assert np.issubdtype(src.dtype, np.floating)
ndim = src.ndim
if ndim == 2:
src = src[:, :, None]
C = src.shape[2]
dst = np.zeros((height, width, C), dtype=src.dtype)
for c in range(C):
src_c = src[:, :, c]
src_c = utils.numpy_to_pillow(src_c)
dst[:, :, c] = src_c.resize((width, height), resample=interpolation)
if ndim == 2:
dst = dst[:, :, 0]
return dst
def _resize_opencv(src, height, width, interpolation):
if interpolation == "linear":
interpolation = cv2.INTER_LINEAR
elif interpolation == "nearest":
interpolation = cv2.INTER_NEAREST
else:
raise ValueError("unsupported interpolation: {}".format(interpolation))
dst = cv2.resize(src, (width, height), interpolation=interpolation)
return dst
def resize(
src,
height=None,
width=None,
interpolation="linear",
backend="auto",
):
"""Resize image.
Parameters
----------
src: numpy.ndarray, (H, W) or (H, W, C)
Input image.
height: int, optional
Height of image. If not given,
the image is resized based on width keeping image ratio.
width: int, optional
Width of image. If not given,
the image is resized based on height keeping image ratio.
interpolation: str
Resizing interpolation (default: 'linear').
'linear':
Linear interpolation.
'nearest':
Interpolate with the nearest value.
backend: str
Resizing backend (default: 'auto').
'pillow':
Pillow is used.
'opencv':
OpenCV is used.
Returns
-------
dst: numpy.ndarray
Resized image.
"""
if not isinstance(src, np.ndarray):
raise TypeError("src type must be numpy.ndarray")
if backend == "auto":
backend = "pillow" if cv2 is None else "opencv"
src_height, src_width = src.shape[:2]
if isinstance(width, float):
scale_width = width
width = int(round(scale_width * src_width))
if isinstance(height, float):
scale_height = height
height = int(round(scale_height * src_height))
if height is None:
assert width is not None
scale_height = 1.0 * width / src_width
height = int(round(scale_height * src_height))
if width is None:
assert height is not None
scale_width = 1.0 * height / src_height
width = int(round(scale_width * src_width))
if backend == "pillow":
dst = _resize_pillow(src, height, width, interpolation)
elif backend == "opencv":
dst = _resize_opencv(src, height, width, interpolation)
else:
raise ValueError("unsupported backend: {}".format(backend))
return dst
|