Source code for compimg.pads

"""
This module defines means to apply padding to images.

"""
import abc
import numpy as np

from abc import ABC
from numbers import Number
from typing import Callable
from compimg._internals._decorators import _raise_if_pad_amount_is_negative


[docs]class Pad(ABC): """ When performing convolution one needs to decide what to do filter is near border(s). Instances implementing this class address that problem. """
[docs] @abc.abstractmethod def apply(self, image: np.ndarray) -> np.ndarray: """ Pads given image. :param image: Image to pad. :return: Padded image. """
[docs]class NoPad(Pad): """ Helper class when one has to pass Pad object but does not want apply any padding. """
[docs] def apply(self, image: np.ndarray) -> np.ndarray: return image
[docs]class FromFunctionPad(Pad): def __init__(self, function: Callable[[np.ndarray], np.ndarray]): self._function = function
[docs] def apply(self, image: np.ndarray) -> np.ndarray: """ Pads given image. :param image: Image to pad. :return: Padded image. """ return self._function(image)
[docs]class ConstantPad(Pad): """ Adds rows/columns of chosen value at the edges of an image. """ @_raise_if_pad_amount_is_negative def __init__(self, value: Number, amount: int): """ :param value: Value to pad with (New edges will be filled with that value. :param amount: Amount of rows/columns to be added. :raises: When amount is negative. """ self._value = value self._amount = amount if self._amount == 0: self.apply = lambda x: x
[docs] def apply(self, image: np.ndarray) -> np.ndarray: pad_width = [[self._amount, self._amount], [self._amount, self._amount]] if image.ndim == 3: pad_width.append([0, 0]) return np.pad( image, pad_width, mode="constant", constant_values=self._value )
[docs]class EdgePad(Pad): """ Replicates neighbouring pixels at edges. """ @_raise_if_pad_amount_is_negative def __init__(self, amount: int): """ :param amount: Amount of rows/columns to be added. :raises: When amount is negative. """ self._amount = amount if self._amount == 0: self.apply = lambda x: x
[docs] def apply(self, image: np.ndarray) -> np.ndarray: pad_width = [[self._amount, self._amount], [self._amount, self._amount]] if image.ndim == 3: pad_width.append([0, 0]) return np.pad(image, pad_width, mode="edge")