Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
MMCV
Commits
9e3ff5f9
Unverified
Commit
9e3ff5f9
authored
Jul 17, 2020
by
Jerry Jiarui XU
Committed by
GitHub
Jul 17, 2020
Browse files
Support pillow resize (#426)
* Support pillow resize * add more types
parent
34ee69e0
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
74 additions
and
17 deletions
+74
-17
mmcv/image/geometric.py
mmcv/image/geometric.py
+54
-9
mmcv/image/io.py
mmcv/image/io.py
+8
-8
tests/test_image/test_geometric.py
tests/test_image/test_geometric.py
+12
-0
No files found.
mmcv/image/geometric.py
View file @
9e3ff5f9
...
...
@@ -4,6 +4,13 @@ import numbers
import
cv2
import
numpy
as
np
from
.io
import
imread_backend
try
:
from
PIL
import
Image
except
ImportError
:
Image
=
None
def
_scale_size
(
size
,
scale
):
"""Rescale a size by a ratio.
...
...
@@ -19,7 +26,7 @@ def _scale_size(size, scale):
return
int
(
w
*
float
(
scale
)
+
0.5
),
int
(
h
*
float
(
scale
)
+
0.5
)
interp_codes
=
{
cv2_
interp_codes
=
{
'nearest'
:
cv2
.
INTER_NEAREST
,
'bilinear'
:
cv2
.
INTER_LINEAR
,
'bicubic'
:
cv2
.
INTER_CUBIC
,
...
...
@@ -27,12 +34,23 @@ interp_codes = {
'lanczos'
:
cv2
.
INTER_LANCZOS4
}
if
Image
is
not
None
:
pillow_interp_codes
=
{
'nearest'
:
Image
.
NEAREST
,
'bilinear'
:
Image
.
BILINEAR
,
'bicubic'
:
Image
.
BICUBIC
,
'box'
:
Image
.
BOX
,
'lanczos'
:
Image
.
LANCZOS
,
'hamming'
:
Image
.
HAMMING
}
def
imresize
(
img
,
size
,
return_scale
=
False
,
interpolation
=
'bilinear'
,
out
=
None
):
out
=
None
,
backend
=
None
):
"""Resize image to a given size.
Args:
...
...
@@ -40,16 +58,32 @@ def imresize(img,
size (tuple[int]): Target size (w, h).
return_scale (bool): Whether to return `w_scale` and `h_scale`.
interpolation (str): Interpolation method, accepted values are
"nearest", "bilinear", "bicubic", "area", "lanczos".
"nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2'
backend, "nearest", "bilinear" for 'pillow' backend.
out (ndarray): The output destination.
backend (str | None): The image resize backend type. Options are `cv2`,
`pillow`, `None`. If backend is None, the global imread_backend
specified by ``mmcv.use_backend()`` will be used. Default: None.
Returns:
tuple | ndarray: (`resized_img`, `w_scale`, `h_scale`) or
`resized_img`.
"""
h
,
w
=
img
.
shape
[:
2
]
resized_img
=
cv2
.
resize
(
img
,
size
,
dst
=
out
,
interpolation
=
interp_codes
[
interpolation
])
if
backend
is
None
:
backend
=
imread_backend
if
backend
not
in
[
'cv2'
,
'pillow'
]:
raise
ValueError
(
f
'backend:
{
backend
}
is not supported for resize.'
f
"Supported backends are 'cv2', 'pillow'"
)
if
backend
==
'pillow'
:
assert
img
.
dtype
==
np
.
uint8
,
'Pillow backend only support uint8 type'
pil_image
=
Image
.
fromarray
(
img
)
pil_image
=
pil_image
.
resize
(
size
,
pillow_interp_codes
[
interpolation
])
resized_img
=
np
.
array
(
pil_image
)
else
:
resized_img
=
cv2
.
resize
(
img
,
size
,
dst
=
out
,
interpolation
=
cv2_interp_codes
[
interpolation
])
if
not
return_scale
:
return
resized_img
else
:
...
...
@@ -58,7 +92,11 @@ def imresize(img,
return
resized_img
,
w_scale
,
h_scale
def
imresize_like
(
img
,
dst_img
,
return_scale
=
False
,
interpolation
=
'bilinear'
):
def
imresize_like
(
img
,
dst_img
,
return_scale
=
False
,
interpolation
=
'bilinear'
,
backend
=
None
):
"""Resize image to the same size of a given image.
Args:
...
...
@@ -66,13 +104,14 @@ def imresize_like(img, dst_img, return_scale=False, interpolation='bilinear'):
dst_img (ndarray): The target image.
return_scale (bool): Whether to return `w_scale` and `h_scale`.
interpolation (str): Same as :func:`resize`.
backend (str | None): Same as :func:`resize`.
Returns:
tuple or ndarray: (`resized_img`, `w_scale`, `h_scale`) or
`resized_img`.
"""
h
,
w
=
dst_img
.
shape
[:
2
]
return
imresize
(
img
,
(
w
,
h
),
return_scale
,
interpolation
)
return
imresize
(
img
,
(
w
,
h
),
return_scale
,
interpolation
,
backend
=
backend
)
def
rescale_size
(
old_size
,
scale
,
return_scale
=
False
):
...
...
@@ -112,7 +151,11 @@ def rescale_size(old_size, scale, return_scale=False):
return
new_size
def
imrescale
(
img
,
scale
,
return_scale
=
False
,
interpolation
=
'bilinear'
):
def
imrescale
(
img
,
scale
,
return_scale
=
False
,
interpolation
=
'bilinear'
,
backend
=
None
):
"""Resize image while keeping the aspect ratio.
Args:
...
...
@@ -124,13 +167,15 @@ def imrescale(img, scale, return_scale=False, interpolation='bilinear'):
return_scale (bool): Whether to return the scaling factor besides the
rescaled image.
interpolation (str): Same as :func:`resize`.
backend (str | None): 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
)
rescaled_img
=
imresize
(
img
,
new_size
,
interpolation
=
interpolation
,
backend
=
backend
)
if
return_scale
:
return
rescaled_img
,
scale_factor
else
:
...
...
mmcv/image/io.py
View file @
9e3ff5f9
...
...
@@ -131,10 +131,10 @@ def imread(img_or_path, flag='color', channel_order='bgr', backend=None):
candidates are `color`, `grayscale` and `unchanged`.
Note that the `turbojpeg` backened does not support `unchanged`.
channel_order (str): Order of channel, candidates are `bgr` and `rgb`.
backend (str
|
None): The image decoding backend type. Options are
`cv2`,
`pillow`, `turbojpeg`, `None`. If backend is None, the
global
imread_backend specified by ``mmcv.use_backend()`` will be
used.
Default: None.
backend (str
|
None): The image decoding backend type. Options are
`cv2`,
`pillow`, `turbojpeg`, `None`. If backend is None, the
global
imread_backend specified by ``mmcv.use_backend()`` will be
used.
Default: None.
Returns:
ndarray: Loaded image array.
...
...
@@ -181,10 +181,10 @@ def imfrombytes(content, flag='color', channel_order='bgr', backend=None):
Args:
content (bytes): Image bytes got from files or other streams.
flag (str): Same as :func:`imread`.
backend (str
|
None): The image decoding backend type. Options are
`cv2`,
`pillow`, `turbojpeg`, `None`. If backend is None, the
global
imread_backend specified by ``mmcv.use_backend()`` will be
used.
Default: None.
backend (str
|
None): The image decoding backend type. Options are
`cv2`,
`pillow`, `turbojpeg`, `None`. If backend is None, the
global
imread_backend specified by ``mmcv.use_backend()`` will be
used.
Default: None.
Returns:
ndarray: Loaded image array.
...
...
tests/test_image/test_geometric.py
View file @
9e3ff5f9
...
...
@@ -35,6 +35,18 @@ class TestGeometric:
self
.
img
,
(
1000
,
600
),
interpolation
=
mode
)
assert
resized_img
.
shape
==
(
600
,
1000
,
3
)
# test pillow resize
for
mode
in
[
'nearest'
,
'bilinear'
,
'bicubic'
,
'box'
,
'lanczos'
,
'hamming'
]:
resized_img
=
mmcv
.
imresize
(
self
.
img
,
(
1000
,
600
),
interpolation
=
mode
,
backend
=
'pillow'
)
assert
resized_img
.
shape
==
(
600
,
1000
,
3
)
# resize backend must be 'cv2' or 'pillow'
with
pytest
.
raises
(
ValueError
):
mmcv
.
imresize
(
self
.
img
,
(
1000
,
600
),
backend
=
'not support'
)
def
test_imresize_like
(
self
):
a
=
np
.
zeros
((
100
,
200
,
3
))
resized_img
=
mmcv
.
imresize_like
(
self
.
img
,
a
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment