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
Show 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
...
@@ -4,6 +4,13 @@ import numbers
import
cv2
import
cv2
import
numpy
as
np
import
numpy
as
np
from
.io
import
imread_backend
try
:
from
PIL
import
Image
except
ImportError
:
Image
=
None
def
_scale_size
(
size
,
scale
):
def
_scale_size
(
size
,
scale
):
"""Rescale a size by a ratio.
"""Rescale a size by a ratio.
...
@@ -19,7 +26,7 @@ def _scale_size(size, scale):
...
@@ -19,7 +26,7 @@ def _scale_size(size, scale):
return
int
(
w
*
float
(
scale
)
+
0.5
),
int
(
h
*
float
(
scale
)
+
0.5
)
return
int
(
w
*
float
(
scale
)
+
0.5
),
int
(
h
*
float
(
scale
)
+
0.5
)
interp_codes
=
{
cv2_
interp_codes
=
{
'nearest'
:
cv2
.
INTER_NEAREST
,
'nearest'
:
cv2
.
INTER_NEAREST
,
'bilinear'
:
cv2
.
INTER_LINEAR
,
'bilinear'
:
cv2
.
INTER_LINEAR
,
'bicubic'
:
cv2
.
INTER_CUBIC
,
'bicubic'
:
cv2
.
INTER_CUBIC
,
...
@@ -27,12 +34,23 @@ interp_codes = {
...
@@ -27,12 +34,23 @@ interp_codes = {
'lanczos'
:
cv2
.
INTER_LANCZOS4
'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
,
def
imresize
(
img
,
size
,
size
,
return_scale
=
False
,
return_scale
=
False
,
interpolation
=
'bilinear'
,
interpolation
=
'bilinear'
,
out
=
None
):
out
=
None
,
backend
=
None
):
"""Resize image to a given size.
"""Resize image to a given size.
Args:
Args:
...
@@ -40,16 +58,32 @@ def imresize(img,
...
@@ -40,16 +58,32 @@ def imresize(img,
size (tuple[int]): Target size (w, h).
size (tuple[int]): Target size (w, h).
return_scale (bool): Whether to return `w_scale` and `h_scale`.
return_scale (bool): Whether to return `w_scale` and `h_scale`.
interpolation (str): Interpolation method, accepted values are
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.
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:
Returns:
tuple | ndarray: (`resized_img`, `w_scale`, `h_scale`) or
tuple | ndarray: (`resized_img`, `w_scale`, `h_scale`) or
`resized_img`.
`resized_img`.
"""
"""
h
,
w
=
img
.
shape
[:
2
]
h
,
w
=
img
.
shape
[:
2
]
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
(
resized_img
=
cv2
.
resize
(
img
,
size
,
dst
=
out
,
interpolation
=
interp_codes
[
interpolation
])
img
,
size
,
dst
=
out
,
interpolation
=
cv2_
interp_codes
[
interpolation
])
if
not
return_scale
:
if
not
return_scale
:
return
resized_img
return
resized_img
else
:
else
:
...
@@ -58,7 +92,11 @@ def imresize(img,
...
@@ -58,7 +92,11 @@ def imresize(img,
return
resized_img
,
w_scale
,
h_scale
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.
"""Resize image to the same size of a given image.
Args:
Args:
...
@@ -66,13 +104,14 @@ def imresize_like(img, dst_img, return_scale=False, interpolation='bilinear'):
...
@@ -66,13 +104,14 @@ def imresize_like(img, dst_img, return_scale=False, interpolation='bilinear'):
dst_img (ndarray): The target image.
dst_img (ndarray): The target image.
return_scale (bool): Whether to return `w_scale` and `h_scale`.
return_scale (bool): Whether to return `w_scale` and `h_scale`.
interpolation (str): Same as :func:`resize`.
interpolation (str): Same as :func:`resize`.
backend (str | None): Same as :func:`resize`.
Returns:
Returns:
tuple or ndarray: (`resized_img`, `w_scale`, `h_scale`) or
tuple or ndarray: (`resized_img`, `w_scale`, `h_scale`) or
`resized_img`.
`resized_img`.
"""
"""
h
,
w
=
dst_img
.
shape
[:
2
]
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
):
def
rescale_size
(
old_size
,
scale
,
return_scale
=
False
):
...
@@ -112,7 +151,11 @@ 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
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.
"""Resize image while keeping the aspect ratio.
Args:
Args:
...
@@ -124,13 +167,15 @@ def imrescale(img, scale, return_scale=False, interpolation='bilinear'):
...
@@ -124,13 +167,15 @@ def imrescale(img, scale, return_scale=False, interpolation='bilinear'):
return_scale (bool): Whether to return the scaling factor besides the
return_scale (bool): Whether to return the scaling factor besides the
rescaled image.
rescaled image.
interpolation (str): Same as :func:`resize`.
interpolation (str): Same as :func:`resize`.
backend (str | None): Same as :func:`resize`.
Returns:
Returns:
ndarray: The rescaled image.
ndarray: The rescaled image.
"""
"""
h
,
w
=
img
.
shape
[:
2
]
h
,
w
=
img
.
shape
[:
2
]
new_size
,
scale_factor
=
rescale_size
((
w
,
h
),
scale
,
return_scale
=
True
)
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
:
if
return_scale
:
return
rescaled_img
,
scale_factor
return
rescaled_img
,
scale_factor
else
:
else
:
...
...
mmcv/image/io.py
View file @
9e3ff5f9
...
@@ -131,10 +131,10 @@ def imread(img_or_path, flag='color', channel_order='bgr', backend=None):
...
@@ -131,10 +131,10 @@ def imread(img_or_path, flag='color', channel_order='bgr', backend=None):
candidates are `color`, `grayscale` and `unchanged`.
candidates are `color`, `grayscale` and `unchanged`.
Note that the `turbojpeg` backened does not support `unchanged`.
Note that the `turbojpeg` backened does not support `unchanged`.
channel_order (str): Order of channel, candidates are `bgr` and `rgb`.
channel_order (str): Order of channel, candidates are `bgr` and `rgb`.
backend (str
|
None): The image decoding backend type. Options are
`cv2`,
backend (str
|
None): The image decoding backend type. Options are
`pillow`, `turbojpeg`, `None`. If backend is None, the
global
`cv2`,
`pillow`, `turbojpeg`, `None`. If backend is None, the
imread_backend specified by ``mmcv.use_backend()`` will be
used.
global
imread_backend specified by ``mmcv.use_backend()`` will be
Default: None.
used.
Default: None.
Returns:
Returns:
ndarray: Loaded image array.
ndarray: Loaded image array.
...
@@ -181,10 +181,10 @@ def imfrombytes(content, flag='color', channel_order='bgr', backend=None):
...
@@ -181,10 +181,10 @@ def imfrombytes(content, flag='color', channel_order='bgr', backend=None):
Args:
Args:
content (bytes): Image bytes got from files or other streams.
content (bytes): Image bytes got from files or other streams.
flag (str): Same as :func:`imread`.
flag (str): Same as :func:`imread`.
backend (str
|
None): The image decoding backend type. Options are
`cv2`,
backend (str
|
None): The image decoding backend type. Options are
`pillow`, `turbojpeg`, `None`. If backend is None, the
global
`cv2`,
`pillow`, `turbojpeg`, `None`. If backend is None, the
imread_backend specified by ``mmcv.use_backend()`` will be
used.
global
imread_backend specified by ``mmcv.use_backend()`` will be
Default: None.
used.
Default: None.
Returns:
Returns:
ndarray: Loaded image array.
ndarray: Loaded image array.
...
...
tests/test_image/test_geometric.py
View file @
9e3ff5f9
...
@@ -35,6 +35,18 @@ class TestGeometric:
...
@@ -35,6 +35,18 @@ class TestGeometric:
self
.
img
,
(
1000
,
600
),
interpolation
=
mode
)
self
.
img
,
(
1000
,
600
),
interpolation
=
mode
)
assert
resized_img
.
shape
==
(
600
,
1000
,
3
)
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
):
def
test_imresize_like
(
self
):
a
=
np
.
zeros
((
100
,
200
,
3
))
a
=
np
.
zeros
((
100
,
200
,
3
))
resized_img
=
mmcv
.
imresize_like
(
self
.
img
,
a
)
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