Unverified Commit 0bf1e80c authored by Joanna's avatar Joanna Committed by GitHub
Browse files

add fast imresize (#193)



* size hint
Signed-off-by: default avatarlizz <lizz@sensetime.com>

* add fast resize
Signed-off-by: default avatarlixuanyi <lixuanyi@sensetime.com>

* fix
Signed-off-by: default avatarlixuanyi <lixuanyi@sensetime.com>

* add tests
Signed-off-by: default avatarlixuanyi <lixuanyi@sensetime.com>

* fix
Signed-off-by: default avatarlixuanyi <lixuanyi@sensetime.com>

* Update tests/test_image.py

* change format
Signed-off-by: default avatarlixuanyi <lixuanyi@sensetime.com>

* add tests
Signed-off-by: default avatarlixuanyi <lixuanyi@sensetime.com>

* add docstring
Signed-off-by: default avatarlixuanyi <lixuanyi@sensetime.com>
Co-authored-by: default avatarlizz <innerlee@users.noreply.github.com>
parent 9332a1dd
......@@ -4,8 +4,8 @@ from .transforms import (bgr2gray, bgr2hls, bgr2hsv, bgr2rgb, gray2bgr,
gray2rgb, hls2bgr, hsv2bgr, imcrop, imdenormalize,
imflip, imflip_, iminvert, imnormalize, imnormalize_,
impad, impad_to_multiple, imrescale, imresize,
imresize_like, imrotate, posterize, rgb2bgr, rgb2gray,
solarize)
imresize_like, imrotate, posterize, rescale_size,
rgb2bgr, rgb2gray, solarize)
__all__ = [
'solarize', 'posterize', 'imread', 'imwrite', 'imfrombytes', 'bgr2gray',
......@@ -13,5 +13,5 @@ __all__ = [
'hsv2bgr', 'bgr2hls', 'hls2bgr', 'iminvert', 'imflip', 'imflip_',
'imrotate', 'imcrop', 'impad', 'impad_to_multiple', 'imnormalize',
'imnormalize_', 'imdenormalize', 'imresize', 'imresize_like', 'imrescale',
'use_backend', 'supported_backends'
'use_backend', 'supported_backends', 'rescale_size'
]
......@@ -5,12 +5,12 @@ from .colorspace import (bgr2gray, bgr2hls, bgr2hsv, bgr2rgb, gray2bgr,
from .geometry import (imcrop, imflip, imflip_, impad, impad_to_multiple,
imrotate)
from .normalize import imdenormalize, imnormalize, imnormalize_
from .resize import imrescale, imresize, imresize_like
from .resize import imrescale, imresize, imresize_like, rescale_size
__all__ = [
'solarize', 'posterize', 'bgr2gray', 'rgb2gray', 'gray2bgr', 'gray2rgb',
'bgr2rgb', 'rgb2bgr', 'bgr2hsv', 'hsv2bgr', 'bgr2hls', 'hls2bgr',
'iminvert', 'imflip', 'imflip_', 'imrotate', 'imcrop', 'impad',
'impad_to_multiple', 'imnormalize', 'imnormalize_', 'imdenormalize',
'imresize', 'imresize_like', 'imrescale'
'imresize', 'imresize_like', 'imrescale', 'rescale_size'
]
......@@ -27,7 +27,11 @@ interp_codes = {
}
def imresize(img, size, return_scale=False, interpolation='bilinear'):
def imresize(img,
size,
return_scale=False,
interpolation='bilinear',
out=None):
"""Resize image to a given size.
Args:
......@@ -36,6 +40,7 @@ def imresize(img, size, return_scale=False, interpolation='bilinear'):
return_scale (bool): Whether to return `w_scale` and `h_scale`.
interpolation (str): Interpolation method, accepted values are
"nearest", "bilinear", "bicubic", "area", "lanczos".
out (ndarray): The output destination.
Returns:
tuple or ndarray: (`resized_img`, `w_scale`, `h_scale`) or
......@@ -43,7 +48,7 @@ def imresize(img, size, return_scale=False, interpolation='bilinear'):
"""
h, w = img.shape[:2]
resized_img = cv2.resize(
img, size, interpolation=interp_codes[interpolation])
img, size, dst=out, interpolation=interp_codes[interpolation])
if not return_scale:
return resized_img
else:
......@@ -69,23 +74,22 @@ def imresize_like(img, dst_img, return_scale=False, interpolation='bilinear'):
return imresize(img, (w, h), return_scale, interpolation)
def imrescale(img, scale, return_scale=False, interpolation='bilinear'):
"""Resize image while keeping the aspect ratio.
def rescale_size(old_size, scale, return_scale=False):
"""Calculate the new size to be rescaled to.
Args:
img (ndarray): The input image.
old_size (tuple[int]): The old size of image.
scale (float or tuple[int]): The scaling factor or maximum size.
If it is a float number, then the image will be rescaled by this
factor, else if it is a tuple of 2 integers, then the image will
be rescaled as large as possible within the scale.
return_scale (bool): Whether to return the scaling factor besides the
rescaled image.
interpolation (str): Same as :func:`resize`.
rescaled image size.
Returns:
ndarray: The rescaled image.
tuple[int]: The new rescaled image size.
"""
h, w = img.shape[:2]
w, h = old_size
if isinstance(scale, (float, int)):
if scale <= 0:
raise ValueError(
......@@ -100,7 +104,33 @@ def imrescale(img, scale, return_scale=False, interpolation='bilinear'):
raise TypeError(
'Scale must be a number or tuple of int, but got {}'.format(
type(scale)))
new_size = _scale_size((w, h), scale_factor)
if return_scale:
return new_size, scale_factor
else:
return new_size
def imrescale(img, scale, return_scale=False, interpolation='bilinear'):
"""Resize image while keeping the aspect ratio.
Args:
img (ndarray): The input image.
scale (float or tuple[int]): The scaling factor or maximum size.
If it is a float number, then the image will be rescaled by this
factor, else if it is a tuple of 2 integers, then the image will
be rescaled as large as possible within the scale.
return_scale (bool): Whether to return the scaling factor besides the
rescaled image.
interpolation (str): Same as :func:`resize`.
Returns:
ndarray: The rescaled image.
"""
h, w = img.shape[:2]
new_size, scale_factor = rescale_size((w, h), scale, return_scale=True)
rescaled_img = imresize(img, new_size, interpolation=interpolation)
if return_scale:
return rescaled_img, scale_factor
......
......@@ -258,6 +258,11 @@ class TestImage(object):
True)
assert (resized_img.shape == (600, 1000, 3) and w_scale == 2.5
and h_scale == 2.0)
resized_img_dst = np.empty((600, 1000, 3), dtype=self.img.dtype)
resized_img = mmcv.imresize(self.img, (1000, 600), out=resized_img_dst)
assert id(resized_img_dst) == id(resized_img)
assert_array_equal(resized_img_dst,
mmcv.imresize(self.img, (1000, 600)))
for mode in ['nearest', 'bilinear', 'bicubic', 'area', 'lanczos']:
resized_img = mmcv.imresize(
self.img, (1000, 600), interpolation=mode)
......@@ -268,6 +273,34 @@ class TestImage(object):
resized_img = mmcv.imresize_like(self.img, a)
assert resized_img.shape == (100, 200, 3)
def test_rescale_size(self):
new_size, scale_factor = mmcv.rescale_size((400, 300), 1.5, True)
assert new_size == (600, 450) and scale_factor == 1.5
new_size, scale_factor = mmcv.rescale_size((400, 300), 0.934, True)
assert new_size == (374, 280) and scale_factor == 0.934
new_size = mmcv.rescale_size((400, 300), 1.5)
assert new_size == (600, 450)
new_size = mmcv.rescale_size((400, 300), 0.934)
assert new_size == (374, 280)
new_size, scale_factor = mmcv.rescale_size((400, 300), (1000, 600),
True)
assert new_size == (800, 600) and scale_factor == 2.0
new_size, scale_factor = mmcv.rescale_size((400, 300), (180, 200),
True)
assert new_size == (200, 150) and scale_factor == 0.5
new_size = mmcv.rescale_size((400, 300), (1000, 600))
assert new_size == (800, 600)
new_size = mmcv.rescale_size((400, 300), (180, 200))
assert new_size == (200, 150)
with pytest.raises(ValueError):
mmcv.rescale_size((400, 300), -0.5)
with pytest.raises(TypeError):
mmcv.rescale_size()((400, 300), [100, 100])
def test_imrescale(self):
# rescale by a certain factor
resized_img = mmcv.imrescale(self.img, 1.5)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment