Commit 86f9dc7a authored by Jingwei Zhang's avatar Jingwei Zhang Committed by Zaida Zhou
Browse files

[Enhance] Support different border modes in imrotate (#2141)

* support different border_mode in imrotate

* fix docstring

* small fix

* reorder the border_mode arg in imrotate

* fix lint

* polish docstring

* polish docstring
parent 12406e21
# Copyright (c) OpenMMLab. All rights reserved. # Copyright (c) OpenMMLab. All rights reserved.
import numbers import numbers
import warnings
from typing import Optional, Tuple
import cv2 import cv2
import numpy as np import numpy as np
...@@ -37,6 +39,16 @@ cv2_interp_codes = { ...@@ -37,6 +39,16 @@ cv2_interp_codes = {
'lanczos': cv2.INTER_LANCZOS4 'lanczos': cv2.INTER_LANCZOS4
} }
cv2_border_modes = {
'constant': cv2.BORDER_CONSTANT,
'replicate': cv2.BORDER_REPLICATE,
'reflect': cv2.BORDER_REFLECT,
'wrap': cv2.BORDER_WRAP,
'reflect_101': cv2.BORDER_REFLECT_101,
'transparent': cv2.BORDER_TRANSPARENT,
'isolated': cv2.BORDER_ISOLATED
}
# Pillow >=v9.1.0 use a slightly different naming scheme for filters. # Pillow >=v9.1.0 use a slightly different naming scheme for filters.
# Set pillow_interp_codes according to the naming scheme used. # Set pillow_interp_codes according to the naming scheme used.
if Image is not None: if Image is not None:
...@@ -301,31 +313,40 @@ def imflip_(img, direction='horizontal'): ...@@ -301,31 +313,40 @@ def imflip_(img, direction='horizontal'):
return cv2.flip(img, -1, img) return cv2.flip(img, -1, img)
def imrotate(img, def imrotate(img: np.ndarray,
angle, angle: float,
center=None, center: Optional[Tuple[float, float]] = None,
scale=1.0, scale: float = 1.0,
border_value=0, border_value: int = 0,
interpolation='bilinear', interpolation: str = 'bilinear',
auto_bound=False): auto_bound: bool = False,
border_mode: str = 'constant') -> np.ndarray:
"""Rotate an image. """Rotate an image.
Args: Args:
img (ndarray): Image to be rotated. img (np.ndarray): Image to be rotated.
angle (float): Rotation angle in degrees, positive values mean angle (float): Rotation angle in degrees, positive values mean
clockwise rotation. clockwise rotation.
center (tuple[float], optional): Center point (w, h) of the rotation in center (tuple[float], optional): Center point (w, h) of the rotation in
the source image. If not specified, the center of the image will be the source image. If not specified, the center of the image will be
used. used.
scale (float): Isotropic scale factor. scale (float): Isotropic scale factor.
border_value (int): Border value. border_value (int): Border value used in case of a constant border.
Defaults to 0.
interpolation (str): Same as :func:`resize`. interpolation (str): Same as :func:`resize`.
auto_bound (bool): Whether to adjust the image size to cover the whole auto_bound (bool): Whether to adjust the image size to cover the whole
rotated image. rotated image.
border_mode (str): Pixel extrapolation method. Defaults to 'constant'.
Returns: Returns:
ndarray: The rotated image. np.ndarray: The rotated image.
""" """
warnings.warn("We have added an arg 'border_mode' in this func "
'and will reorder the args in the future as: '
'( ..., scale: float = 1.0, '
"border_mode: str = 'constant', "
'border_value: int = 0, ... ). '
'Please use keyword arguments to call this function.')
if center is not None and auto_bound: if center is not None and auto_bound:
raise ValueError('`auto_bound` conflicts with `center`') raise ValueError('`auto_bound` conflicts with `center`')
h, w = img.shape[:2] h, w = img.shape[:2]
...@@ -347,6 +368,7 @@ def imrotate(img, ...@@ -347,6 +368,7 @@ def imrotate(img,
img, img,
matrix, (w, h), matrix, (w, h),
flags=cv2_interp_codes[interpolation], flags=cv2_interp_codes[interpolation],
borderMode=cv2_border_modes[border_mode],
borderValue=border_value) borderValue=border_value)
return rotated return rotated
......
...@@ -527,6 +527,9 @@ class TestGeometric: ...@@ -527,6 +527,9 @@ class TestGeometric:
assert_array_equal(mmcv.imrotate(img, 90, border_value=255), img_r) assert_array_equal(mmcv.imrotate(img, 90, border_value=255), img_r)
img_r = np.array([[5, 1], [6, 2], [7, 3], [8, 4]]) img_r = np.array([[5, 1], [6, 2], [7, 3], [8, 4]])
assert_array_equal(mmcv.imrotate(img, 90, auto_bound=True), img_r) assert_array_equal(mmcv.imrotate(img, 90, auto_bound=True), img_r)
img_r = np.array([[6, 6, 2, 2], [7, 7, 3, 3]])
assert_array_equal(
mmcv.imrotate(img, 90, border_mode='replicate'), img_r)
with pytest.raises(ValueError): with pytest.raises(ValueError):
mmcv.imrotate(img, 90, center=(0, 0), auto_bound=True) mmcv.imrotate(img, 90, center=(0, 0), auto_bound=True)
......
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