Source code for nabu.processing.padding_base
import numpy as np
from ..utils import check_supported
[docs]
class PaddingBase:
"""
A class for performing padding based on coordinate transform.
The Cuda and OpenCL backends will subclass this class.
"""
supported_modes = ["constant", "edge", "reflect", "symmetric", "wrap"]
def __init__(self, shape, pad_width, mode="constant", **kwargs):
"""
Initialize a Padding object.
Parameters
----------
shape: tuple
Image shape
pad_width: tuple
Padding width for each axis. Please see the documentation of numpy.pad().
mode: str
Padding mode
Other parameters
----------------
constant_values: tuple
Tuple containing the values to fill when mode="constant" (as in numpy.pad)
"""
if len(shape) != 2:
raise ValueError("This class only works on images")
self.shape = shape
self._set_mode(mode, **kwargs)
self._get_padding_arrays(pad_width)
def _set_mode(self, mode, **kwargs):
# COMPAT.
if mode == "edges":
mode = "edge"
#
check_supported(mode, self.supported_modes, "padding mode")
self.mode = mode
self._kwargs = kwargs
def _get_padding_arrays(self, pad_width):
self.pad_width = pad_width
if isinstance(pad_width, tuple) and isinstance(pad_width[0], np.ndarray):
# user-defined coordinate transform
err_msg = "pad_width must be either a scalar, a tuple in the form ((a, b), (c, d)), or a tuple of two one-dimensional numpy arrays (eg. use numpy.indices(..., sparse=True))"
if len(pad_width) != 2:
raise ValueError(err_msg)
if any([np.squeeze(pw).ndim > 1 for pw in pad_width]):
raise ValueError(err_msg)
if self.mode == "constant":
raise ValueError("Custom coordinate transform does not work with mode='constant'")
self.mode = "custom"
self.coords_rows, self.coords_cols = pad_width
else:
if self.mode == "constant":
# no need for coordinate transform here
constant_values = self._kwargs.get("constant_values", 0)
self.padded_array_constant = np.pad(
np.zeros(self.shape, dtype="f"), self.pad_width, mode="constant", constant_values=constant_values
)
self.padded_shape = self.padded_array_constant.shape
return
R, C = np.indices(self.shape, dtype=np.int32, sparse=True)
self.coords_rows = np.pad(R.ravel(), self.pad_width[0], mode=self.mode)
self.coords_cols = np.pad(C.ravel(), self.pad_width[1], mode=self.mode)
self.padded_shape = (self.coords_rows.size, self.coords_cols.size)