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