Source code for augpy
from typing import Tuple
from typing import Union
from typing import Optional
from . import _augpy
from ._augpy import *
import numpy as __np
__version__ = '1.0.0a1'
__all__ = [f for f in dir(_augpy) if not f.startswith('_')]
__all__.extend([
'SCALE_MODE',
'to_numpy_dtype',
'to_augpy_dtype',
'swap_dtype',
'to_temp_dtype',
'make_transform',
])
SCALE_MODE = {
WARP_SCALE_LONGEST: WARP_SCALE_LONGEST,
WARP_SCALE_SHORTEST: WARP_SCALE_SHORTEST,
'shortest': WARP_SCALE_SHORTEST,
'longest': WARP_SCALE_LONGEST,
}
r"""
Dict to canonicalize strings and enum values to :py:class:`WarpScaleMode`.
Example::
SCALE_MODE[WARP_SCALE_LONGEST] == SCALE_MODE['longest'] == WARP_SCALE_LONGEST
SCALE_MODE[WARP_SCALE_SHORTEST] == SCALE_MODE['shortest'] == WARP_SCALE_SHORTEST
"""
_AUGPY_TO_NUMPY_DTYPES = {
uint8: __np.uint8,
uint16: __np.uint16,
uint32: __np.uint32,
uint64: __np.uint64,
int8: __np.int8,
int16: __np.int16,
int32: __np.int32,
int64: __np.int64,
float32: __np.float32,
float64: __np.float64,
}
[docs]def to_numpy_dtype(augpy_dtype: DLDataType) -> type:
r"""
Translate augpy to numpy data types.
Example::
to_numpy_dtype(augpy.uint8) == numpy.uint8
Parameters:
augpy_dtype: augpy type to translate
"""
return _AUGPY_TO_NUMPY_DTYPES[augpy_dtype]
_NUMPY_TO_AUGPY_DTYPES = {
__np.uint8: uint8,
__np.uint16: uint16,
__np.uint32: uint32,
__np.uint64: uint64,
__np.int8: int8,
__np.int16: int16,
__np.int32: int32,
__np.int64: int64,
__np.float32: float32,
__np.float64: float64,
}
[docs]def to_augpy_dtype(numpy_dtype: Union[type, __np.dtype]) -> DLDataType:
r"""
Translate numpy to augpy data types.
Example::
to_augpy_dtype(numpy.uint8) == augpy.uint8
Parameters:
numpy_dtype: numpy type to translate
"""
if isinstance(numpy_dtype, __np.dtype):
numpy_dtype = numpy_dtype.type
return _NUMPY_TO_AUGPY_DTYPES[numpy_dtype]
_DTYPE_MAP = {}
_DTYPE_MAP.update(_AUGPY_TO_NUMPY_DTYPES)
_DTYPE_MAP.update(_NUMPY_TO_AUGPY_DTYPES)
[docs]def swap_dtype(dtype: Union[DLDataType, type, __np.dtype]) -> Union[DLDataType, type]:
r"""
Translate to and from numpy and augpy data types.
Examples::
swap_dtype(augpy.uint8) == numpy.uint8
swap_dtype(numpy.uint8) == augpy.uint8
Parameters:
dtype: type to translate to augpy or numpy
"""
if isinstance(dtype, __np.dtype):
dtype = dtype.type
return _DTYPE_MAP[dtype]
_TEMP_DTYPES = {
# augpy types
uint8: float32,
uint16: float32,
uint32: float64,
uint64: float64,
int8: float32,
int16: float32,
int32: float64,
int64: float64,
float32: float32,
float64: float64,
# numpy types
__np.uint8: __np.float32,
__np.uint16: __np.float32,
__np.uint32: __np.float64,
__np.uint64: __np.float64,
__np.int8: __np.float32,
__np.int16: __np.float32,
__np.int32: __np.float64,
__np.int64: __np.float64,
__np.float32: __np.float32,
__np.float64: __np.float64,
}
[docs]def to_temp_dtype(dtype: Union[DLDataType, type, __np.dtype]) -> Union[DLDataType, type]:
r"""
augpy defines a temp type for each tensor data type.
This temp type is used internally for processing and sometimes
returns. This dict maps from augpy and numpy dtypes
and their temp types.
This function returns the temp type for given data type.
Parameters:
dtype: augpy or numpy dtype
Returns:
temp type
"""
if isinstance(dtype, __np.dtype):
dtype = dtype.type
return _TEMP_DTYPES[dtype]
[docs]def make_transform(
source_size: Tuple[int, int],
target_size: Tuple[int, int],
angle: float = 0,
scale: float = 1,
aspect: float = 1,
shift: Optional[Tuple[float, float]] = None,
shear: Optional[Tuple[float, float]] = None,
hmirror: bool = False,
vmirror: bool = False,
scale_mode: Union[str, WarpScaleMode] = WARP_SCALE_SHORTEST,
max_supersampling: int = 3,
out: Optional[__np.ndarray] = None,
__template__=__np.zeros((2, 3), dtype=__np.float32),
**__
) -> Tuple[__np.ndarray, int]:
r"""
Convenience wrapper for :py:func:`make_affine_matrix`.
See:
:py:func:`make_affine_matrix` slightly faster,
less convenient version of this function.
Parameters:
source_size: source height (:math:`h_s`) and width (:math:`w_s`)
target_size: target height (:math:`h_t`) and width (:math:`w_t`)
angle: clockwise angle in degrees
with image center as rotation axis
scale: scale factor relative to output size;
1 means fill target height or width wise depending
on ``scale_mode`` and whichever is longest/shortest;
larger values will crop,
smaller values leave empty space in the output canvas
aspect: controls the aspect ratio;
1 means same as input, values greater 1
increase the width and reduce the height
shift: ``(shifty, shiftx)`` or ``None`` for ``(0, 0)``;
shift the image in y (vertical) and x (horizontal) direction;
0 centers the image on the output canvas;
-1 means shift up/left as much as possible;
1 means shfit down/right as much as possible;
the maximum distance to shift is
:math:`max(scale \cdot h_s - h_t, h_t - scale \cdot h_s)`
shear: ``(sheary, shearx)`` or ``None`` for ``(0, 0)``;
controls up/down and left/right shear;
for every pixel in the x direction move ``sheary`` pixels
in y direction, same for y direction
hmirror: if ``True`` flip image horizontally
vmirror: if ``True`` flip image vertically
scale_mode: if :py:attr:`WarpScaleMode.WARP_SCALE_SHORTEST` scale
is relative to shortest side;
this fills the output canvas, cropping the image
if necessary;
if :py:attr:`WarpScaleMode.WARP_SCALE_LONGEST` scale
is relative to longest side;
this ensures the image is contained inside the
output canvas, but leaves empty space
max_supersampling: upper limit for recommended supersampling
out: optional :math:`2 \times 3` ``float`` output array
Returns:
transformation matrix and suggested supersampling factor
"""
out = out if out is not None else __template__.copy()
shift = shift or (0, 0)
shear = shear or (0, 0)
supersampling = make_affine_matrix(
out,
source_size[0], source_size[1],
target_size[0], target_size[1],
angle,
scale,
aspect,
shift[0], shift[1],
shear[0], shear[1],
hmirror,
vmirror,
SCALE_MODE[scale_mode],
max_supersampling
)
return out, supersampling