Spaces:
Runtime error
Runtime error
# Copyright (c) OpenMMLab. All rights reserved. | |
from typing import Optional, Union | |
import cv2 | |
import mmcv | |
import numpy as np | |
from mmcv.transforms import BaseTransform | |
from mmcv.transforms.utils import cache_randomness | |
from mmdet.registry import TRANSFORMS | |
from mmdet.structures.bbox import autocast_box_type | |
from .augment_wrappers import _MAX_LEVEL, level_to_mag | |
class GeomTransform(BaseTransform): | |
"""Base class for geometric transformations. All geometric transformations | |
need to inherit from this base class. ``GeomTransform`` unifies the class | |
attributes and class functions of geometric transformations (ShearX, | |
ShearY, Rotate, TranslateX, and TranslateY), and records the homography | |
matrix. | |
Required Keys: | |
- img | |
- gt_bboxes (BaseBoxes[torch.float32]) (optional) | |
- gt_masks (BitmapMasks | PolygonMasks) (optional) | |
- gt_seg_map (np.uint8) (optional) | |
Modified Keys: | |
- img | |
- gt_bboxes | |
- gt_masks | |
- gt_seg_map | |
Added Keys: | |
- homography_matrix | |
Args: | |
prob (float): The probability for performing the geometric | |
transformation and should be in range [0, 1]. Defaults to 1.0. | |
level (int, optional): The level should be in range [0, _MAX_LEVEL]. | |
If level is None, it will generate from [0, _MAX_LEVEL] randomly. | |
Defaults to None. | |
min_mag (float): The minimum magnitude for geometric transformation. | |
Defaults to 0.0. | |
max_mag (float): The maximum magnitude for geometric transformation. | |
Defaults to 1.0. | |
reversal_prob (float): The probability that reverses the geometric | |
transformation magnitude. Should be in range [0,1]. | |
Defaults to 0.5. | |
img_border_value (int | float | tuple): The filled values for | |
image border. If float, the same fill value will be used for | |
all the three channels of image. If tuple, it should be 3 elements. | |
Defaults to 128. | |
mask_border_value (int): The fill value used for masks. Defaults to 0. | |
seg_ignore_label (int): The fill value used for segmentation map. | |
Note this value must equals ``ignore_label`` in ``semantic_head`` | |
of the corresponding config. Defaults to 255. | |
interpolation (str): Interpolation method, accepted values are | |
"nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2' | |
backend, "nearest", "bilinear" for 'pillow' backend. Defaults | |
to 'bilinear'. | |
""" | |
def __init__(self, | |
prob: float = 1.0, | |
level: Optional[int] = None, | |
min_mag: float = 0.0, | |
max_mag: float = 1.0, | |
reversal_prob: float = 0.5, | |
img_border_value: Union[int, float, tuple] = 128, | |
mask_border_value: int = 0, | |
seg_ignore_label: int = 255, | |
interpolation: str = 'bilinear') -> None: | |
assert 0 <= prob <= 1.0, f'The probability of the transformation ' \ | |
f'should be in range [0,1], got {prob}.' | |
assert level is None or isinstance(level, int), \ | |
f'The level should be None or type int, got {type(level)}.' | |
assert level is None or 0 <= level <= _MAX_LEVEL, \ | |
f'The level should be in range [0,{_MAX_LEVEL}], got {level}.' | |
assert isinstance(min_mag, float), \ | |
f'min_mag should be type float, got {type(min_mag)}.' | |
assert isinstance(max_mag, float), \ | |
f'max_mag should be type float, got {type(max_mag)}.' | |
assert min_mag <= max_mag, \ | |
f'min_mag should smaller than max_mag, ' \ | |
f'got min_mag={min_mag} and max_mag={max_mag}' | |
assert isinstance(reversal_prob, float), \ | |
f'reversal_prob should be type float, got {type(max_mag)}.' | |
assert 0 <= reversal_prob <= 1.0, \ | |
f'The reversal probability of the transformation magnitude ' \ | |
f'should be type float, got {type(reversal_prob)}.' | |
if isinstance(img_border_value, (float, int)): | |
img_border_value = tuple([float(img_border_value)] * 3) | |
elif isinstance(img_border_value, tuple): | |
assert len(img_border_value) == 3, \ | |
f'img_border_value as tuple must have 3 elements, ' \ | |
f'got {len(img_border_value)}.' | |
img_border_value = tuple([float(val) for val in img_border_value]) | |
else: | |
raise ValueError( | |
'img_border_value must be float or tuple with 3 elements.') | |
assert np.all([0 <= val <= 255 for val in img_border_value]), 'all ' \ | |
'elements of img_border_value should between range [0,255].' \ | |
f'got {img_border_value}.' | |
self.prob = prob | |
self.level = level | |
self.min_mag = min_mag | |
self.max_mag = max_mag | |
self.reversal_prob = reversal_prob | |
self.img_border_value = img_border_value | |
self.mask_border_value = mask_border_value | |
self.seg_ignore_label = seg_ignore_label | |
self.interpolation = interpolation | |
def _transform_img(self, results: dict, mag: float) -> None: | |
"""Transform the image.""" | |
pass | |
def _transform_masks(self, results: dict, mag: float) -> None: | |
"""Transform the masks.""" | |
pass | |
def _transform_seg(self, results: dict, mag: float) -> None: | |
"""Transform the segmentation map.""" | |
pass | |
def _get_homography_matrix(self, results: dict, mag: float) -> np.ndarray: | |
"""Get the homography matrix for the geometric transformation.""" | |
return np.eye(3, dtype=np.float32) | |
def _transform_bboxes(self, results: dict, mag: float) -> None: | |
"""Transform the bboxes.""" | |
results['gt_bboxes'].project_(self.homography_matrix) | |
results['gt_bboxes'].clip_(results['img_shape']) | |
def _record_homography_matrix(self, results: dict) -> None: | |
"""Record the homography matrix for the geometric transformation.""" | |
if results.get('homography_matrix', None) is None: | |
results['homography_matrix'] = self.homography_matrix | |
else: | |
results['homography_matrix'] = self.homography_matrix @ results[ | |
'homography_matrix'] | |
def _random_disable(self): | |
"""Randomly disable the transform.""" | |
return np.random.rand() > self.prob | |
def _get_mag(self): | |
"""Get the magnitude of the transform.""" | |
mag = level_to_mag(self.level, self.min_mag, self.max_mag) | |
return -mag if np.random.rand() > self.reversal_prob else mag | |
def transform(self, results: dict) -> dict: | |
"""Transform function for images, bounding boxes, masks and semantic | |
segmentation map. | |
Args: | |
results (dict): Result dict from loading pipeline. | |
Returns: | |
dict: Transformed results. | |
""" | |
if self._random_disable(): | |
return results | |
mag = self._get_mag() | |
self.homography_matrix = self._get_homography_matrix(results, mag) | |
self._record_homography_matrix(results) | |
self._transform_img(results, mag) | |
if results.get('gt_bboxes', None) is not None: | |
self._transform_bboxes(results, mag) | |
if results.get('gt_masks', None) is not None: | |
self._transform_masks(results, mag) | |
if results.get('gt_seg_map', None) is not None: | |
self._transform_seg(results, mag) | |
return results | |
def __repr__(self) -> str: | |
repr_str = self.__class__.__name__ | |
repr_str += f'(prob={self.prob}, ' | |
repr_str += f'level={self.level}, ' | |
repr_str += f'min_mag={self.min_mag}, ' | |
repr_str += f'max_mag={self.max_mag}, ' | |
repr_str += f'reversal_prob={self.reversal_prob}, ' | |
repr_str += f'img_border_value={self.img_border_value}, ' | |
repr_str += f'mask_border_value={self.mask_border_value}, ' | |
repr_str += f'seg_ignore_label={self.seg_ignore_label}, ' | |
repr_str += f'interpolation={self.interpolation})' | |
return repr_str | |
class ShearX(GeomTransform): | |
"""Shear the images, bboxes, masks and segmentation map horizontally. | |
Required Keys: | |
- img | |
- gt_bboxes (BaseBoxes[torch.float32]) (optional) | |
- gt_masks (BitmapMasks | PolygonMasks) (optional) | |
- gt_seg_map (np.uint8) (optional) | |
Modified Keys: | |
- img | |
- gt_bboxes | |
- gt_masks | |
- gt_seg_map | |
Added Keys: | |
- homography_matrix | |
Args: | |
prob (float): The probability for performing Shear and should be in | |
range [0, 1]. Defaults to 1.0. | |
level (int, optional): The level should be in range [0, _MAX_LEVEL]. | |
If level is None, it will generate from [0, _MAX_LEVEL] randomly. | |
Defaults to None. | |
min_mag (float): The minimum angle for the horizontal shear. | |
Defaults to 0.0. | |
max_mag (float): The maximum angle for the horizontal shear. | |
Defaults to 30.0. | |
reversal_prob (float): The probability that reverses the horizontal | |
shear magnitude. Should be in range [0,1]. Defaults to 0.5. | |
img_border_value (int | float | tuple): The filled values for | |
image border. If float, the same fill value will be used for | |
all the three channels of image. If tuple, it should be 3 elements. | |
Defaults to 128. | |
mask_border_value (int): The fill value used for masks. Defaults to 0. | |
seg_ignore_label (int): The fill value used for segmentation map. | |
Note this value must equals ``ignore_label`` in ``semantic_head`` | |
of the corresponding config. Defaults to 255. | |
interpolation (str): Interpolation method, accepted values are | |
"nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2' | |
backend, "nearest", "bilinear" for 'pillow' backend. Defaults | |
to 'bilinear'. | |
""" | |
def __init__(self, | |
prob: float = 1.0, | |
level: Optional[int] = None, | |
min_mag: float = 0.0, | |
max_mag: float = 30.0, | |
reversal_prob: float = 0.5, | |
img_border_value: Union[int, float, tuple] = 128, | |
mask_border_value: int = 0, | |
seg_ignore_label: int = 255, | |
interpolation: str = 'bilinear') -> None: | |
assert 0. <= min_mag <= 90., \ | |
f'min_mag angle for ShearX should be ' \ | |
f'in range [0, 90], got {min_mag}.' | |
assert 0. <= max_mag <= 90., \ | |
f'max_mag angle for ShearX should be ' \ | |
f'in range [0, 90], got {max_mag}.' | |
super().__init__( | |
prob=prob, | |
level=level, | |
min_mag=min_mag, | |
max_mag=max_mag, | |
reversal_prob=reversal_prob, | |
img_border_value=img_border_value, | |
mask_border_value=mask_border_value, | |
seg_ignore_label=seg_ignore_label, | |
interpolation=interpolation) | |
def _get_mag(self): | |
"""Get the magnitude of the transform.""" | |
mag = level_to_mag(self.level, self.min_mag, self.max_mag) | |
mag = np.tan(mag * np.pi / 180) | |
return -mag if np.random.rand() > self.reversal_prob else mag | |
def _get_homography_matrix(self, results: dict, mag: float) -> np.ndarray: | |
"""Get the homography matrix for ShearX.""" | |
return np.array([[1, mag, 0], [0, 1, 0], [0, 0, 1]], dtype=np.float32) | |
def _transform_img(self, results: dict, mag: float) -> None: | |
"""Shear the image horizontally.""" | |
results['img'] = mmcv.imshear( | |
results['img'], | |
mag, | |
direction='horizontal', | |
border_value=self.img_border_value, | |
interpolation=self.interpolation) | |
def _transform_masks(self, results: dict, mag: float) -> None: | |
"""Shear the masks horizontally.""" | |
results['gt_masks'] = results['gt_masks'].shear( | |
results['img_shape'], | |
mag, | |
direction='horizontal', | |
border_value=self.mask_border_value, | |
interpolation=self.interpolation) | |
def _transform_seg(self, results: dict, mag: float) -> None: | |
"""Shear the segmentation map horizontally.""" | |
results['gt_seg_map'] = mmcv.imshear( | |
results['gt_seg_map'], | |
mag, | |
direction='horizontal', | |
border_value=self.seg_ignore_label, | |
interpolation='nearest') | |
class ShearY(GeomTransform): | |
"""Shear the images, bboxes, masks and segmentation map vertically. | |
Required Keys: | |
- img | |
- gt_bboxes (BaseBoxes[torch.float32]) (optional) | |
- gt_masks (BitmapMasks | PolygonMasks) (optional) | |
- gt_seg_map (np.uint8) (optional) | |
Modified Keys: | |
- img | |
- gt_bboxes | |
- gt_masks | |
- gt_seg_map | |
Added Keys: | |
- homography_matrix | |
Args: | |
prob (float): The probability for performing ShearY and should be in | |
range [0, 1]. Defaults to 1.0. | |
level (int, optional): The level should be in range [0,_MAX_LEVEL]. | |
If level is None, it will generate from [0, _MAX_LEVEL] randomly. | |
Defaults to None. | |
min_mag (float): The minimum angle for the vertical shear. | |
Defaults to 0.0. | |
max_mag (float): The maximum angle for the vertical shear. | |
Defaults to 30.0. | |
reversal_prob (float): The probability that reverses the vertical | |
shear magnitude. Should be in range [0,1]. Defaults to 0.5. | |
img_border_value (int | float | tuple): The filled values for | |
image border. If float, the same fill value will be used for | |
all the three channels of image. If tuple, it should be 3 elements. | |
Defaults to 128. | |
mask_border_value (int): The fill value used for masks. Defaults to 0. | |
seg_ignore_label (int): The fill value used for segmentation map. | |
Note this value must equals ``ignore_label`` in ``semantic_head`` | |
of the corresponding config. Defaults to 255. | |
interpolation (str): Interpolation method, accepted values are | |
"nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2' | |
backend, "nearest", "bilinear" for 'pillow' backend. Defaults | |
to 'bilinear'. | |
""" | |
def __init__(self, | |
prob: float = 1.0, | |
level: Optional[int] = None, | |
min_mag: float = 0.0, | |
max_mag: float = 30., | |
reversal_prob: float = 0.5, | |
img_border_value: Union[int, float, tuple] = 128, | |
mask_border_value: int = 0, | |
seg_ignore_label: int = 255, | |
interpolation: str = 'bilinear') -> None: | |
assert 0. <= min_mag <= 90., \ | |
f'min_mag angle for ShearY should be ' \ | |
f'in range [0, 90], got {min_mag}.' | |
assert 0. <= max_mag <= 90., \ | |
f'max_mag angle for ShearY should be ' \ | |
f'in range [0, 90], got {max_mag}.' | |
super().__init__( | |
prob=prob, | |
level=level, | |
min_mag=min_mag, | |
max_mag=max_mag, | |
reversal_prob=reversal_prob, | |
img_border_value=img_border_value, | |
mask_border_value=mask_border_value, | |
seg_ignore_label=seg_ignore_label, | |
interpolation=interpolation) | |
def _get_mag(self): | |
"""Get the magnitude of the transform.""" | |
mag = level_to_mag(self.level, self.min_mag, self.max_mag) | |
mag = np.tan(mag * np.pi / 180) | |
return -mag if np.random.rand() > self.reversal_prob else mag | |
def _get_homography_matrix(self, results: dict, mag: float) -> np.ndarray: | |
"""Get the homography matrix for ShearY.""" | |
return np.array([[1, 0, 0], [mag, 1, 0], [0, 0, 1]], dtype=np.float32) | |
def _transform_img(self, results: dict, mag: float) -> None: | |
"""Shear the image vertically.""" | |
results['img'] = mmcv.imshear( | |
results['img'], | |
mag, | |
direction='vertical', | |
border_value=self.img_border_value, | |
interpolation=self.interpolation) | |
def _transform_masks(self, results: dict, mag: float) -> None: | |
"""Shear the masks vertically.""" | |
results['gt_masks'] = results['gt_masks'].shear( | |
results['img_shape'], | |
mag, | |
direction='vertical', | |
border_value=self.mask_border_value, | |
interpolation=self.interpolation) | |
def _transform_seg(self, results: dict, mag: float) -> None: | |
"""Shear the segmentation map vertically.""" | |
results['gt_seg_map'] = mmcv.imshear( | |
results['gt_seg_map'], | |
mag, | |
direction='vertical', | |
border_value=self.seg_ignore_label, | |
interpolation='nearest') | |
class Rotate(GeomTransform): | |
"""Rotate the images, bboxes, masks and segmentation map. | |
Required Keys: | |
- img | |
- gt_bboxes (BaseBoxes[torch.float32]) (optional) | |
- gt_masks (BitmapMasks | PolygonMasks) (optional) | |
- gt_seg_map (np.uint8) (optional) | |
Modified Keys: | |
- img | |
- gt_bboxes | |
- gt_masks | |
- gt_seg_map | |
Added Keys: | |
- homography_matrix | |
Args: | |
prob (float): The probability for perform transformation and | |
should be in range 0 to 1. Defaults to 1.0. | |
level (int, optional): The level should be in range [0, _MAX_LEVEL]. | |
If level is None, it will generate from [0, _MAX_LEVEL] randomly. | |
Defaults to None. | |
min_mag (float): The maximum angle for rotation. | |
Defaults to 0.0. | |
max_mag (float): The maximum angle for rotation. | |
Defaults to 30.0. | |
reversal_prob (float): The probability that reverses the rotation | |
magnitude. Should be in range [0,1]. Defaults to 0.5. | |
img_border_value (int | float | tuple): The filled values for | |
image border. If float, the same fill value will be used for | |
all the three channels of image. If tuple, it should be 3 elements. | |
Defaults to 128. | |
mask_border_value (int): The fill value used for masks. Defaults to 0. | |
seg_ignore_label (int): The fill value used for segmentation map. | |
Note this value must equals ``ignore_label`` in ``semantic_head`` | |
of the corresponding config. Defaults to 255. | |
interpolation (str): Interpolation method, accepted values are | |
"nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2' | |
backend, "nearest", "bilinear" for 'pillow' backend. Defaults | |
to 'bilinear'. | |
""" | |
def __init__(self, | |
prob: float = 1.0, | |
level: Optional[int] = None, | |
min_mag: float = 0.0, | |
max_mag: float = 30.0, | |
reversal_prob: float = 0.5, | |
img_border_value: Union[int, float, tuple] = 128, | |
mask_border_value: int = 0, | |
seg_ignore_label: int = 255, | |
interpolation: str = 'bilinear') -> None: | |
assert 0. <= min_mag <= 180., \ | |
f'min_mag for Rotate should be in range [0,180], got {min_mag}.' | |
assert 0. <= max_mag <= 180., \ | |
f'max_mag for Rotate should be in range [0,180], got {max_mag}.' | |
super().__init__( | |
prob=prob, | |
level=level, | |
min_mag=min_mag, | |
max_mag=max_mag, | |
reversal_prob=reversal_prob, | |
img_border_value=img_border_value, | |
mask_border_value=mask_border_value, | |
seg_ignore_label=seg_ignore_label, | |
interpolation=interpolation) | |
def _get_homography_matrix(self, results: dict, mag: float) -> np.ndarray: | |
"""Get the homography matrix for Rotate.""" | |
img_shape = results['img_shape'] | |
center = ((img_shape[1] - 1) * 0.5, (img_shape[0] - 1) * 0.5) | |
cv2_rotation_matrix = cv2.getRotationMatrix2D(center, -mag, 1.0) | |
return np.concatenate( | |
[cv2_rotation_matrix, | |
np.array([0, 0, 1]).reshape((1, 3))]).astype(np.float32) | |
def _transform_img(self, results: dict, mag: float) -> None: | |
"""Rotate the image.""" | |
results['img'] = mmcv.imrotate( | |
results['img'], | |
mag, | |
border_value=self.img_border_value, | |
interpolation=self.interpolation) | |
def _transform_masks(self, results: dict, mag: float) -> None: | |
"""Rotate the masks.""" | |
results['gt_masks'] = results['gt_masks'].rotate( | |
results['img_shape'], | |
mag, | |
border_value=self.mask_border_value, | |
interpolation=self.interpolation) | |
def _transform_seg(self, results: dict, mag: float) -> None: | |
"""Rotate the segmentation map.""" | |
results['gt_seg_map'] = mmcv.imrotate( | |
results['gt_seg_map'], | |
mag, | |
border_value=self.seg_ignore_label, | |
interpolation='nearest') | |
class TranslateX(GeomTransform): | |
"""Translate the images, bboxes, masks and segmentation map horizontally. | |
Required Keys: | |
- img | |
- gt_bboxes (BaseBoxes[torch.float32]) (optional) | |
- gt_masks (BitmapMasks | PolygonMasks) (optional) | |
- gt_seg_map (np.uint8) (optional) | |
Modified Keys: | |
- img | |
- gt_bboxes | |
- gt_masks | |
- gt_seg_map | |
Added Keys: | |
- homography_matrix | |
Args: | |
prob (float): The probability for perform transformation and | |
should be in range 0 to 1. Defaults to 1.0. | |
level (int, optional): The level should be in range [0, _MAX_LEVEL]. | |
If level is None, it will generate from [0, _MAX_LEVEL] randomly. | |
Defaults to None. | |
min_mag (float): The minimum pixel's offset ratio for horizontal | |
translation. Defaults to 0.0. | |
max_mag (float): The maximum pixel's offset ratio for horizontal | |
translation. Defaults to 0.1. | |
reversal_prob (float): The probability that reverses the horizontal | |
translation magnitude. Should be in range [0,1]. Defaults to 0.5. | |
img_border_value (int | float | tuple): The filled values for | |
image border. If float, the same fill value will be used for | |
all the three channels of image. If tuple, it should be 3 elements. | |
Defaults to 128. | |
mask_border_value (int): The fill value used for masks. Defaults to 0. | |
seg_ignore_label (int): The fill value used for segmentation map. | |
Note this value must equals ``ignore_label`` in ``semantic_head`` | |
of the corresponding config. Defaults to 255. | |
interpolation (str): Interpolation method, accepted values are | |
"nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2' | |
backend, "nearest", "bilinear" for 'pillow' backend. Defaults | |
to 'bilinear'. | |
""" | |
def __init__(self, | |
prob: float = 1.0, | |
level: Optional[int] = None, | |
min_mag: float = 0.0, | |
max_mag: float = 0.1, | |
reversal_prob: float = 0.5, | |
img_border_value: Union[int, float, tuple] = 128, | |
mask_border_value: int = 0, | |
seg_ignore_label: int = 255, | |
interpolation: str = 'bilinear') -> None: | |
assert 0. <= min_mag <= 1., \ | |
f'min_mag ratio for TranslateX should be ' \ | |
f'in range [0, 1], got {min_mag}.' | |
assert 0. <= max_mag <= 1., \ | |
f'max_mag ratio for TranslateX should be ' \ | |
f'in range [0, 1], got {max_mag}.' | |
super().__init__( | |
prob=prob, | |
level=level, | |
min_mag=min_mag, | |
max_mag=max_mag, | |
reversal_prob=reversal_prob, | |
img_border_value=img_border_value, | |
mask_border_value=mask_border_value, | |
seg_ignore_label=seg_ignore_label, | |
interpolation=interpolation) | |
def _get_homography_matrix(self, results: dict, mag: float) -> np.ndarray: | |
"""Get the homography matrix for TranslateX.""" | |
mag = int(results['img_shape'][1] * mag) | |
return np.array([[1, 0, mag], [0, 1, 0], [0, 0, 1]], dtype=np.float32) | |
def _transform_img(self, results: dict, mag: float) -> None: | |
"""Translate the image horizontally.""" | |
mag = int(results['img_shape'][1] * mag) | |
results['img'] = mmcv.imtranslate( | |
results['img'], | |
mag, | |
direction='horizontal', | |
border_value=self.img_border_value, | |
interpolation=self.interpolation) | |
def _transform_masks(self, results: dict, mag: float) -> None: | |
"""Translate the masks horizontally.""" | |
mag = int(results['img_shape'][1] * mag) | |
results['gt_masks'] = results['gt_masks'].translate( | |
results['img_shape'], | |
mag, | |
direction='horizontal', | |
border_value=self.mask_border_value, | |
interpolation=self.interpolation) | |
def _transform_seg(self, results: dict, mag: float) -> None: | |
"""Translate the segmentation map horizontally.""" | |
mag = int(results['img_shape'][1] * mag) | |
results['gt_seg_map'] = mmcv.imtranslate( | |
results['gt_seg_map'], | |
mag, | |
direction='horizontal', | |
border_value=self.seg_ignore_label, | |
interpolation='nearest') | |
class TranslateY(GeomTransform): | |
"""Translate the images, bboxes, masks and segmentation map vertically. | |
Required Keys: | |
- img | |
- gt_bboxes (BaseBoxes[torch.float32]) (optional) | |
- gt_masks (BitmapMasks | PolygonMasks) (optional) | |
- gt_seg_map (np.uint8) (optional) | |
Modified Keys: | |
- img | |
- gt_bboxes | |
- gt_masks | |
- gt_seg_map | |
Added Keys: | |
- homography_matrix | |
Args: | |
prob (float): The probability for perform transformation and | |
should be in range 0 to 1. Defaults to 1.0. | |
level (int, optional): The level should be in range [0, _MAX_LEVEL]. | |
If level is None, it will generate from [0, _MAX_LEVEL] randomly. | |
Defaults to None. | |
min_mag (float): The minimum pixel's offset ratio for vertical | |
translation. Defaults to 0.0. | |
max_mag (float): The maximum pixel's offset ratio for vertical | |
translation. Defaults to 0.1. | |
reversal_prob (float): The probability that reverses the vertical | |
translation magnitude. Should be in range [0,1]. Defaults to 0.5. | |
img_border_value (int | float | tuple): The filled values for | |
image border. If float, the same fill value will be used for | |
all the three channels of image. If tuple, it should be 3 elements. | |
Defaults to 128. | |
mask_border_value (int): The fill value used for masks. Defaults to 0. | |
seg_ignore_label (int): The fill value used for segmentation map. | |
Note this value must equals ``ignore_label`` in ``semantic_head`` | |
of the corresponding config. Defaults to 255. | |
interpolation (str): Interpolation method, accepted values are | |
"nearest", "bilinear", "bicubic", "area", "lanczos" for 'cv2' | |
backend, "nearest", "bilinear" for 'pillow' backend. Defaults | |
to 'bilinear'. | |
""" | |
def __init__(self, | |
prob: float = 1.0, | |
level: Optional[int] = None, | |
min_mag: float = 0.0, | |
max_mag: float = 0.1, | |
reversal_prob: float = 0.5, | |
img_border_value: Union[int, float, tuple] = 128, | |
mask_border_value: int = 0, | |
seg_ignore_label: int = 255, | |
interpolation: str = 'bilinear') -> None: | |
assert 0. <= min_mag <= 1., \ | |
f'min_mag ratio for TranslateY should be ' \ | |
f'in range [0,1], got {min_mag}.' | |
assert 0. <= max_mag <= 1., \ | |
f'max_mag ratio for TranslateY should be ' \ | |
f'in range [0,1], got {max_mag}.' | |
super().__init__( | |
prob=prob, | |
level=level, | |
min_mag=min_mag, | |
max_mag=max_mag, | |
reversal_prob=reversal_prob, | |
img_border_value=img_border_value, | |
mask_border_value=mask_border_value, | |
seg_ignore_label=seg_ignore_label, | |
interpolation=interpolation) | |
def _get_homography_matrix(self, results: dict, mag: float) -> np.ndarray: | |
"""Get the homography matrix for TranslateY.""" | |
mag = int(results['img_shape'][0] * mag) | |
return np.array([[1, 0, 0], [0, 1, mag], [0, 0, 1]], dtype=np.float32) | |
def _transform_img(self, results: dict, mag: float) -> None: | |
"""Translate the image vertically.""" | |
mag = int(results['img_shape'][0] * mag) | |
results['img'] = mmcv.imtranslate( | |
results['img'], | |
mag, | |
direction='vertical', | |
border_value=self.img_border_value, | |
interpolation=self.interpolation) | |
def _transform_masks(self, results: dict, mag: float) -> None: | |
"""Translate masks vertically.""" | |
mag = int(results['img_shape'][0] * mag) | |
results['gt_masks'] = results['gt_masks'].translate( | |
results['img_shape'], | |
mag, | |
direction='vertical', | |
border_value=self.mask_border_value, | |
interpolation=self.interpolation) | |
def _transform_seg(self, results: dict, mag: float) -> None: | |
"""Translate segmentation map vertically.""" | |
mag = int(results['img_shape'][0] * mag) | |
results['gt_seg_map'] = mmcv.imtranslate( | |
results['gt_seg_map'], | |
mag, | |
direction='vertical', | |
border_value=self.seg_ignore_label, | |
interpolation='nearest') | |