Skip to content

Augmentation layers and models


Implementations of layers for augmenting images

Augmentation

Bases: Layer

Base augmentation class

Used to create Random Augmentation layers

Methods:

random_execute: returns boolean variable based on given probability. Determines whether the layer should activate on given batch augment_single_image: abstract method. Should be implemented by child classes. Distorts a single image random_augment_single_image: randomly augment an image with given probability call: run the layer on a batch of images

Source code in conftrainer/augmentation/layers.py
class Augmentation(Layer):
    """
    Base augmentation class

    Used to create Random Augmentation layers

    Methods:
    --------
    random_execute:
        returns boolean variable based on given probability. Determines whether the layer should
     activate on given batch
    augment_single_image:
        abstract method. Should be implemented by child classes. Distorts a single image
    random_augment_single_image:
        randomly augment an image with given probability
    call:
        run the layer on a batch of images
    """

    def __init__(self, factor, shape=None, **kwargs):
        super().__init__(**kwargs)
        self.shape = shape
        self.factor = factor

    @staticmethod
    def random_execute(probability):
        """
        Return boolean variable based on given probability

        Generate random float from 0 to 1 and return whether it's smaller than given float

        Parameters
        ----------
        probability: float
            probability to return True

        Returns
        -------
        out: bool
            whether generated value is smaller than given prob

        Raises
        ------
        NotImplementedError: if the child class doesn't implement this method
        """

        return tf.random.uniform([], minval=0, maxval=1) < probability

    def augment_single_image(self, image):
        """
        Abstract method for augmenting a single image.

        Should be implemented by child classes

        Parameters
        ----------
        image: tf.Tensor
            image to distort

        Returns
        -------
        out: tf.Tensor
            distorted image
        """

        raise NotImplementedError

    def random_augment_single_image(self, image):
        """
        Randomly augment a single image with given probabilty

        Parameters
        ----------
        image: tf.Tensor
            image to augment

        Returns
        --------
        out: tf.Tensor

        """

        if self.random_execute(self.factor):
            augmented = self.augment_single_image(image=image)
            return tf.clip_by_value(augmented, clip_value_min=0, clip_value_max=255)
        return image

    def call(self, inputs, training):
        """
        Randomly run the layer on given inputs

        Parameters
        ----------
        inputs: tf.Tensor
                batch of input images
        training: bool
                whether to run the layer in training or inference mode. The layer is inactive in
                inference mode and returns the inputs as is

        Returns
        -------
        out: tf.Tensor
            distorted version of images with given probability, original ones otherwise
        """
        if training:
            inputs = tf.image.convert_image_dtype(inputs, dtype=self.compute_dtype)
            return tf.map_fn(fn=self.random_augment_single_image, elems=inputs,
                             fn_output_signature=self.compute_dtype)
        return inputs

random_execute(probability) staticmethod

Return boolean variable based on given probability

Generate random float from 0 to 1 and return whether it's smaller than given float

Parameters:

Name Type Description Default
probability

probability to return True

required

Returns:

Name Type Description
out bool

whether generated value is smaller than given prob

Raises:

Type Description
NotImplementedError: if the child class doesn't implement this method
Source code in conftrainer/augmentation/layers.py
@staticmethod
def random_execute(probability):
    """
    Return boolean variable based on given probability

    Generate random float from 0 to 1 and return whether it's smaller than given float

    Parameters
    ----------
    probability: float
        probability to return True

    Returns
    -------
    out: bool
        whether generated value is smaller than given prob

    Raises
    ------
    NotImplementedError: if the child class doesn't implement this method
    """

    return tf.random.uniform([], minval=0, maxval=1) < probability

augment_single_image(image)

Abstract method for augmenting a single image.

Should be implemented by child classes

Parameters:

Name Type Description Default
image

image to distort

required

Returns:

Name Type Description
out tf.Tensor

distorted image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Abstract method for augmenting a single image.

    Should be implemented by child classes

    Parameters
    ----------
    image: tf.Tensor
        image to distort

    Returns
    -------
    out: tf.Tensor
        distorted image
    """

    raise NotImplementedError

random_augment_single_image(image)

Randomly augment a single image with given probabilty

Parameters:

Name Type Description Default
image

image to augment

required

Returns:

Name Type Description
out tf.Tensor
Source code in conftrainer/augmentation/layers.py
def random_augment_single_image(self, image):
    """
    Randomly augment a single image with given probabilty

    Parameters
    ----------
    image: tf.Tensor
        image to augment

    Returns
    --------
    out: tf.Tensor

    """

    if self.random_execute(self.factor):
        augmented = self.augment_single_image(image=image)
        return tf.clip_by_value(augmented, clip_value_min=0, clip_value_max=255)
    return image

call(inputs, training)

Randomly run the layer on given inputs

Parameters:

Name Type Description Default
inputs

batch of input images

required
training

whether to run the layer in training or inference mode. The layer is inactive in inference mode and returns the inputs as is

required

Returns:

Name Type Description
out tf.Tensor

distorted version of images with given probability, original ones otherwise

Source code in conftrainer/augmentation/layers.py
def call(self, inputs, training):
    """
    Randomly run the layer on given inputs

    Parameters
    ----------
    inputs: tf.Tensor
            batch of input images
    training: bool
            whether to run the layer in training or inference mode. The layer is inactive in
            inference mode and returns the inputs as is

    Returns
    -------
    out: tf.Tensor
        distorted version of images with given probability, original ones otherwise
    """
    if training:
        inputs = tf.image.convert_image_dtype(inputs, dtype=self.compute_dtype)
        return tf.map_fn(fn=self.random_augment_single_image, elems=inputs,
                         fn_output_signature=self.compute_dtype)
    return inputs

RandomColorJitter

Bases: Augmentation

Randomly Jitter a batch of images by adjusting brightness, contrast, saturation and hue

Parameters:

prob: float probability of layer to activate brightness: float upper limit of a random brightness shift. Lower is always 0 contrast: float, list of float shift of contrast. If a list of float is given, min value of that list serves as the lower boundary of contrast shift and the max value as the upper boundary. If a single float is given, lower and upper boundaries are determined as 1-contrast and 1+contrast saturation: float, list of float shift of saturation. If a list of float is given, min value of that list serves as the lower boundary of saturation shift and the second value as the upper boundary. If a single float is given, lower and upper boundaries are determined as 1-saturation and 1+saturation hue: float upper limit of random hue shift. Lower is always 0

Methods:

call: run the layer on given batch of images

Source code in conftrainer/augmentation/layers.py
class RandomColorJitter(Augmentation):
    """
    Randomly Jitter a batch of images by adjusting brightness, contrast, saturation and hue

    Parameters:
    ----------
    prob: float
            probability of layer to activate
    brightness: float
        upper limit of a random brightness shift. Lower is always 0
    contrast: float, list of float
        shift of contrast. If a list of float is given, min value of that list serves as the
        lower boundary of contrast shift and the max value as the upper boundary. If a single
        float is given, lower and upper boundaries are determined as 1-contrast and 1+contrast
    saturation: float, list of float
        shift of saturation. If a list of float is given, min value of that list serves as the
        lower boundary of saturation shift and the second value as the upper boundary. If a single
        float is given, lower and upper boundaries are determined as 1-saturation and 1+saturation
    hue: float
        upper limit of random hue shift. Lower is always 0

    Methods:
    --------
    call: run the layer on given batch of images

    """

    def __init__(self, factor=0.9, brightness=0., contrast=0., saturation=0., hue=0., **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.max_brightness = brightness
        self.max_hue = hue
        if isinstance(contrast, list):
            self.lower_contrast = min(contrast)
            self.upper_contrast = max(contrast)
        else:
            self.lower_contrast, self.upper_contrast = 1 - contrast, 1 + contrast

        if isinstance(saturation, list):
            self.lower_saturation = min(saturation)
            self.upper_saturation = max(saturation)
        else:
            self.lower_saturation, self.upper_saturation = 1 - saturation, 1 + saturation

    def augment_single_image(self, image):
        """
        Randomly adjust the brightness, contrast, saturation and hue of an image
        """

        aug = tf.image.random_brightness(image, self.max_brightness)
        aug = tf.image.random_contrast(aug, self.lower_contrast, self.upper_contrast)
        aug = tf.image.random_saturation(aug, self.lower_saturation, self.upper_saturation)
        aug = tf.image.random_hue(aug, self.max_hue)

        return aug

augment_single_image(image)

Randomly adjust the brightness, contrast, saturation and hue of an image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Randomly adjust the brightness, contrast, saturation and hue of an image
    """

    aug = tf.image.random_brightness(image, self.max_brightness)
    aug = tf.image.random_contrast(aug, self.lower_contrast, self.upper_contrast)
    aug = tf.image.random_saturation(aug, self.lower_saturation, self.upper_saturation)
    aug = tf.image.random_hue(aug, self.max_hue)

    return aug

RandomZoomCrop

Bases: Augmentation

Randomly zoom and crop an image

Parameters:

prob: float the probability of layer to activate min_area: float minimal ratio of area of the original image to leave after cropping shape: tuple of int input/output shape of the images

Methods:

call: run the layer on a given batch of images

Source code in conftrainer/augmentation/layers.py
class RandomZoomCrop(Augmentation):
    """
    Randomly zoom and crop an image

    Parameters:
    ----------
    prob: float
        the probability of layer to activate
    min_area: float
        minimal ratio of area of the original image to leave after cropping
    shape: tuple of int
        input/output shape of the images

    Methods:
    --------
    call: run the layer on a given batch of images
    """

    def __init__(self, min_area, factor, **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.min_area = min_area

    def augment_single_image(self, image):
        """
        Generate a random crop window, crop the image and resize it to given shape
        """

        orig_height, orig_width = self.shape[:2]
        area = tf.cast(orig_width * orig_height, dtype=tf.float32)
        target_area = tf.random.uniform([], self.min_area, 1.0, dtype=tf.float32) * area
        log_ratio = (tf.math.log(3 / 4), tf.math.log(4 / 3))
        aspect_ratio = tf.math.exp(
                tf.random.uniform([], *log_ratio, dtype=tf.float32))

        width = tf.cast(tf.round(tf.sqrt(target_area * aspect_ratio)), tf.int32)
        height = tf.cast(tf.round(tf.sqrt(target_area / aspect_ratio)), tf.int32)

        width = tf.minimum(width, orig_width)
        height = tf.minimum(height, orig_height)

        offset_w = tf.random.uniform((),
                                     minval=0,
                                     maxval=orig_width - width + 1,
                                     dtype=tf.int32)
        offset_h = tf.random.uniform((),
                                     minval=0,
                                     maxval=orig_height - height + 1,
                                     dtype=tf.int32)

        cropped = tf.image.crop_to_bounding_box(image=image, offset_height=offset_h,
                                                offset_width=offset_w,
                                                target_height=height, target_width=width)
        resized = tf.image.resize(cropped, self.shape[:2])
        resized = tf.image.convert_image_dtype(resized, self.compute_dtype)
        return resized

augment_single_image(image)

Generate a random crop window, crop the image and resize it to given shape

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Generate a random crop window, crop the image and resize it to given shape
    """

    orig_height, orig_width = self.shape[:2]
    area = tf.cast(orig_width * orig_height, dtype=tf.float32)
    target_area = tf.random.uniform([], self.min_area, 1.0, dtype=tf.float32) * area
    log_ratio = (tf.math.log(3 / 4), tf.math.log(4 / 3))
    aspect_ratio = tf.math.exp(
            tf.random.uniform([], *log_ratio, dtype=tf.float32))

    width = tf.cast(tf.round(tf.sqrt(target_area * aspect_ratio)), tf.int32)
    height = tf.cast(tf.round(tf.sqrt(target_area / aspect_ratio)), tf.int32)

    width = tf.minimum(width, orig_width)
    height = tf.minimum(height, orig_height)

    offset_w = tf.random.uniform((),
                                 minval=0,
                                 maxval=orig_width - width + 1,
                                 dtype=tf.int32)
    offset_h = tf.random.uniform((),
                                 minval=0,
                                 maxval=orig_height - height + 1,
                                 dtype=tf.int32)

    cropped = tf.image.crop_to_bounding_box(image=image, offset_height=offset_h,
                                            offset_width=offset_w,
                                            target_height=height, target_width=width)
    resized = tf.image.resize(cropped, self.shape[:2])
    resized = tf.image.convert_image_dtype(resized, self.compute_dtype)
    return resized

RandomSolarize

Bases: Augmentation

Randomly solarize a batch of images, inverting pixels with low values.

Expects the inputs to be in range [0,255]

Parameters:

prob: float the probability of layer to activate threshold: int upper bound of pixels to invert

Methods:

call: run the layer on a given batch of images

Notes:

When paired with RandomInvert, the pixels of high values will be inverted instead

Source code in conftrainer/augmentation/layers.py
class RandomSolarize(Augmentation):
    """
    Randomly solarize a batch of images, inverting pixels with low values.

    Expects the inputs to be in range [0,255]

    Parameters:
    ----------
    prob: float
        the probability of layer to activate
    threshold: int
        upper bound of pixels to invert

    Methods:
    --------
    call: run the layer on a given batch of images

    Notes:
    ------
    When paired with RandomInvert, the pixels of high values will be inverted instead
    """

    def __init__(self, factor, threshold=128, **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.threshold = threshold

    def augment_single_image(self, image):
        """
        Solarize an image
        """
        return tf.where(image > self.threshold, image, 255 - image)

augment_single_image(image)

Solarize an image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Solarize an image
    """
    return tf.where(image > self.threshold, image, 255 - image)

RandomInvert

Bases: Augmentation

Randomly invert pixel values of a batch of images

Expects the inputs to be in range [0,255]

Parameters:

prob: float the probability of layer to activate

Methods:

call: run the layer on a given batch of images

Notes:

When paired with RandomSolarize, only the part of the pixels is inverted

Source code in conftrainer/augmentation/layers.py
class RandomInvert(Augmentation):
    """
    Randomly invert pixel values of a batch of images

    Expects the inputs to be in range [0,255]

    Parameters:
    ----------
    prob: float
        the probability of layer to activate

    Methods:
    --------
    call: run the layer on a given batch of images

    Notes:
    ------
    When paired with RandomSolarize, only the part of the pixels is inverted
    """

    def __init__(self, factor, **kwargs):
        super().__init__(factor=factor, **kwargs)

    def augment_single_image(self, image):
        """
        Invert pixel values of a single image
        """
        return tf.add(255., - image)

augment_single_image(image)

Invert pixel values of a single image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Invert pixel values of a single image
    """
    return tf.add(255., - image)

RandomBlur

Bases: Augmentation

Randomly blur a batch of images by applying a 2d Gaussian filter with a random sigma. For more info about the filter and its arguments, see tensorflow_addons.image.gaussian_filter2d

Parameters:

factor: float the probability of layer to activate filter_shape: tuple of int shape of the blur filter to apply. If tuple with more than 2 items is passed, only the first 2 number will be used sigma_low: float, default: 0.1 lower boundary of random sigma parameter to use when blurring sigma_high: float, default: 2 upper boundary of random sigma parameter to use when blurring

Methods:

call: run the layer on a given batch of images

Source code in conftrainer/augmentation/layers.py
class RandomBlur(Augmentation):
    """
    Randomly blur a batch of images by applying a 2d Gaussian filter with a random sigma.
    For more info about the filter and its arguments, see tensorflow_addons.image.gaussian_filter2d

    Parameters:
    ----------
    factor: float
        the probability of layer to activate
    filter_shape: tuple of int
        shape of the blur filter to apply. If tuple with more than 2 items is passed, only the
        first 2 number will be used
    sigma_low: float, default: 0.1
        lower boundary of random sigma parameter to use when blurring
    sigma_high: float, default: 2
        upper boundary of random sigma parameter to use when blurring

    Methods:
    --------
    call: run the layer on a given batch of images
    """

    def __init__(self, factor, kernel_size, sigma_low=0.1, sigma_high=2, **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.kernel_x, self.kernel_y = kernel_size[:2]
        self.sigma_low = sigma_low
        self.sigma_high = sigma_high

    def get_random_transformation(self):
        """Create gaussian kernels to augment the image"""
        sigma_x = tf.random.uniform((1,), minval=self.sigma_low, maxval=self.sigma_high)
        sigma_y = tf.random.uniform((1,), minval=self.sigma_low, maxval=self.sigma_high)
        blur_w = self.get_kernel(sigma_y, self.kernel_y)
        blur_h = self.get_kernel(sigma_x, self.kernel_x)
        blur_w = tf.reshape(blur_w, [self.kernel_y, 1, 1, 1])
        blur_h = tf.reshape(blur_h, [1, self.kernel_x, 1, 1])
        return blur_w, blur_h

    def augment_single_image(self, image):
        """Apply gaussian blurring to single image"""
        image = tf.expand_dims(image, axis=0)

        num_channels = tf.shape(image)[-1]
        blur_w, blur_h = self.get_random_transformation()
        blur_h = tf.cast(tf.tile(blur_h, [1, 1, num_channels, 1]), dtype=self.compute_dtype)
        blur_w = tf.cast(tf.tile(blur_w, [1, 1, num_channels, 1]), dtype=self.compute_dtype)

        blurred = tf.nn.depthwise_conv2d(image, blur_h, strides=[1, 1, 1, 1], padding="SAME")
        blurred = tf.nn.depthwise_conv2d(blurred, blur_w, strides=[1, 1, 1, 1], padding="SAME")

        return tf.squeeze(blurred, axis=0)

    @staticmethod
    def get_kernel(sigma, filter_size):
        """Create a gaussian kernel with given sigma and shape"""
        # Run in tf.float32 to avoid image corruption
        x = tf.cast(
                tf.range(-filter_size // 2 + 1, filter_size // 2 + 1),
                dtype=tf.float32,
        )
        blur_filter = tf.exp(
                -tf.pow(x, 2.0)
                / (2.0 * tf.pow(tf.cast(sigma, dtype=tf.float32), 2.0))
        )
        blur_filter /= tf.reduce_sum(blur_filter)
        return blur_filter

get_random_transformation()

Create gaussian kernels to augment the image

Source code in conftrainer/augmentation/layers.py
def get_random_transformation(self):
    """Create gaussian kernels to augment the image"""
    sigma_x = tf.random.uniform((1,), minval=self.sigma_low, maxval=self.sigma_high)
    sigma_y = tf.random.uniform((1,), minval=self.sigma_low, maxval=self.sigma_high)
    blur_w = self.get_kernel(sigma_y, self.kernel_y)
    blur_h = self.get_kernel(sigma_x, self.kernel_x)
    blur_w = tf.reshape(blur_w, [self.kernel_y, 1, 1, 1])
    blur_h = tf.reshape(blur_h, [1, self.kernel_x, 1, 1])
    return blur_w, blur_h

augment_single_image(image)

Apply gaussian blurring to single image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """Apply gaussian blurring to single image"""
    image = tf.expand_dims(image, axis=0)

    num_channels = tf.shape(image)[-1]
    blur_w, blur_h = self.get_random_transformation()
    blur_h = tf.cast(tf.tile(blur_h, [1, 1, num_channels, 1]), dtype=self.compute_dtype)
    blur_w = tf.cast(tf.tile(blur_w, [1, 1, num_channels, 1]), dtype=self.compute_dtype)

    blurred = tf.nn.depthwise_conv2d(image, blur_h, strides=[1, 1, 1, 1], padding="SAME")
    blurred = tf.nn.depthwise_conv2d(blurred, blur_w, strides=[1, 1, 1, 1], padding="SAME")

    return tf.squeeze(blurred, axis=0)

get_kernel(sigma, filter_size) staticmethod

Create a gaussian kernel with given sigma and shape

Source code in conftrainer/augmentation/layers.py
@staticmethod
def get_kernel(sigma, filter_size):
    """Create a gaussian kernel with given sigma and shape"""
    # Run in tf.float32 to avoid image corruption
    x = tf.cast(
            tf.range(-filter_size // 2 + 1, filter_size // 2 + 1),
            dtype=tf.float32,
    )
    blur_filter = tf.exp(
            -tf.pow(x, 2.0)
            / (2.0 * tf.pow(tf.cast(sigma, dtype=tf.float32), 2.0))
    )
    blur_filter /= tf.reduce_sum(blur_filter)
    return blur_filter

RandomGrayscale

Bases: Augmentation

Randomly turn a batch of images to Grayscale

Parameters:

prob: float the probability of layer to activate

Methods:

call: run the layer on a given batch of images

Source code in conftrainer/augmentation/layers.py
class RandomGrayscale(Augmentation):
    """
    Randomly turn a batch of images to Grayscale

    Parameters:
    ----------
    prob: float
        the probability of layer to activate

    Methods:
    --------
    call: run the layer on a given batch of images
    """

    def __init__(self, factor, **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.rgb_weights = RGB_WEIGHTS

    def augment_single_image(self, image):
        """
        Turn an image to grayscale
        """
        gray = tf.reduce_sum(image * self.rgb_weights, axis=-1)
        gray_3d = tf.stack([gray, gray, gray], axis=-1)

        return gray_3d

augment_single_image(image)

Turn an image to grayscale

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Turn an image to grayscale
    """
    gray = tf.reduce_sum(image * self.rgb_weights, axis=-1)
    gray_3d = tf.stack([gray, gray, gray], axis=-1)

    return gray_3d

RandomSepia

Bases: Augmentation

Randomly turn images to sepia color scheme

Parameters:

Name Type Description Default
factor

probability of the layer to activate

required
Source code in conftrainer/augmentation/layers.py
class RandomSepia(Augmentation):
    """
    Randomly turn images to sepia color scheme

    Parameters
    ----------
    factor: float
        probability of the layer to activate
    """

    def __init__(self, factor, **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.red, self.green, self.blue = SEPIA_RGB_WEIGHTS

    def augment_single_image(self, image):
        """
        Turn a single image to sepia
        """
        red = tf.math.reduce_sum(image * self.red, axis=-1)
        blue = tf.math.reduce_sum(image * self.blue, axis=-1)
        green = tf.math.reduce_sum(image * self.green, axis=-1)
        return tf.stack([red, green, blue], axis=-1)

augment_single_image(image)

Turn a single image to sepia

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Turn a single image to sepia
    """
    red = tf.math.reduce_sum(image * self.red, axis=-1)
    blue = tf.math.reduce_sum(image * self.blue, axis=-1)
    green = tf.math.reduce_sum(image * self.green, axis=-1)
    return tf.stack([red, green, blue], axis=-1)

RandomChannelShuffle

Bases: Augmentation

Randomly Shuffle the order of channels of RGB images

Parameters:

Name Type Description Default
factor

probability of layer to activate on each call

required
Source code in conftrainer/augmentation/layers.py
class RandomChannelShuffle(Augmentation):
    """
    Randomly Shuffle the order of channels of RGB images

    Parameters
    ----------
    factor: float
        probability of layer to activate on each call
    """

    def __init__(self, factor, **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.channel_order = [0, 1, 2]

    def augment_single_image(self, image):
        """
        Shuffle the order of channels of a single image
        """
        channel_order = tf.random.shuffle(self.channel_order)
        return tf.gather(params=image, indices=channel_order, axis=-1)

augment_single_image(image)

Shuffle the order of channels of a single image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Shuffle the order of channels of a single image
    """
    channel_order = tf.random.shuffle(self.channel_order)
    return tf.gather(params=image, indices=channel_order, axis=-1)

RandomChannelShift

Bases: Augmentation

Randomly shift one or multiple channel's of RGB images. Expects the pixel values to be in range [0, 255]

Parameters:

Name Type Description Default
factor

probability of the layer to activate

required
channels

list of indices of channels to shift

None
delta

maximal magnitude of distortions

0
Source code in conftrainer/augmentation/layers.py
class RandomChannelShift(Augmentation):
    """
    Randomly shift one or multiple channel's of RGB images. Expects the pixel values to be in
    range [0, 255]

    Parameters
    ----------
    factor: float
        probability of the layer to activate
    channels: list of int
        list of indices of channels to shift
    delta: int
        maximal magnitude of distortions
    """

    def __init__(self, factor, channels=None, delta=0, **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.channels = [0, 0, 0]
        if channels:
            for ind in channels:
                self.channels[ind] = 1
        self.delta = delta

    def augment_single_image(self, image):
        """
        Shift pixel values of given channels of a single image by random values
        """
        shift_per_channel = tf.random.uniform(shape=(1, 3),
                                              minval=-self.delta,
                                              maxval=self.delta)
        shift = shift_per_channel * self.channels

        return tf.clip_by_value(tf.add(image, shift), 0, 255)

augment_single_image(image)

Shift pixel values of given channels of a single image by random values

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Shift pixel values of given channels of a single image by random values
    """
    shift_per_channel = tf.random.uniform(shape=(1, 3),
                                          minval=-self.delta,
                                          maxval=self.delta)
    shift = shift_per_channel * self.channels

    return tf.clip_by_value(tf.add(image, shift), 0, 255)

RandomAdjustJpegQuality

Bases: Augmentation

Randomly compress the Jpeg quality of a batch of images.

The pixel values of images are expected to be in range [0, 255]

Parameters:

Name Type Description Default
factor

probability of the layer to activate

required
min_quality

positive integer < 100, minimal quality of image ofter distortion

25
Source code in conftrainer/augmentation/layers.py
class RandomAdjustJpegQuality(Augmentation):
    """
    Randomly compress the Jpeg quality of a batch of images.

    The pixel values of images are expected to be in range [0, 255]

    Parameters
    ----------
    factor: float
        probability of the layer to activate
    min_quality: int
        positive integer < 100, minimal quality of image ofter distortion
    """

    def __init__(self, factor, min_quality=25, max_quality=100, **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.min_quality = min_quality
        self.max_quality = max_quality

    def augment_single_image(self, image):
        """
        Randomly adjust jpeg quality of a single image
        """
        return 255 * tf.image.random_jpeg_quality(image / 255,
                                                  min_jpeg_quality=self.min_quality,
                                                  max_jpeg_quality=self.max_quality)

augment_single_image(image)

Randomly adjust jpeg quality of a single image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Randomly adjust jpeg quality of a single image
    """
    return 255 * tf.image.random_jpeg_quality(image / 255,
                                              min_jpeg_quality=self.min_quality,
                                              max_jpeg_quality=self.max_quality)

RandomPixelDropout

Bases: Augmentation

Randomly turn pixel values of an image to 0

Parameters:

Name Type Description Default
factor

probability of the layer to activate

required
dropout_probability

probability of each pixel value to be turned to 0

0.001
Source code in conftrainer/augmentation/layers.py
class RandomPixelDropout(Augmentation):
    """
    Randomly turn pixel values of an image to 0

    Parameters
    ----------
    factor: float
        probability of the layer to activate
    dropout_probability: float
        probability of each pixel value to be turned to 0
    """

    def __init__(self, factor, dropout_probability=0.001, **kwargs):
        super().__init__(factor=factor, **kwargs)
        self.dropout_probability = dropout_probability

    def augment_single_image(self, image):
        """
        Randomly dropout pixel values of a single image
        """

        mask = tf.random.uniform(shape=tf.shape(image)[:2], minval=0, maxval=1)
        mask = tf.where(mask > self.dropout_probability, 1., 0.)
        mask = tf.stack([mask, mask, mask], axis=-1)
        return image * mask

augment_single_image(image)

Randomly dropout pixel values of a single image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Randomly dropout pixel values of a single image
    """

    mask = tf.random.uniform(shape=tf.shape(image)[:2], minval=0, maxval=1)
    mask = tf.where(mask > self.dropout_probability, 1., 0.)
    mask = tf.stack([mask, mask, mask], axis=-1)
    return image * mask

RandomHorizontalFlip

Bases: Augmentation

Randomly flip images horizontally

Source code in conftrainer/augmentation/layers.py
class RandomHorizontalFlip(Augmentation):
    """
    Randomly flip images horizontally
    """

    def __init__(self, factor, **kwargs):
        super().__init__(factor=factor, **kwargs)

    def augment_single_image(self, image):
        """
        Flip single image
        """
        return tf.image.flip_left_right(image)

augment_single_image(image)

Flip single image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Flip single image
    """
    return tf.image.flip_left_right(image)

RandomVerticalFlip

Bases: Augmentation

Randomly flip images vertically

Source code in conftrainer/augmentation/layers.py
class RandomVerticalFlip(Augmentation):
    """
    Randomly flip images vertically
    """

    def __init__(self, factor, **kwargs):
        super().__init__(factor=factor, **kwargs)

    def augment_single_image(self, image):
        """
        Flip single image
        """
        return tf.image.flip_up_down(image)

augment_single_image(image)

Flip single image

Source code in conftrainer/augmentation/layers.py
def augment_single_image(self, image):
    """
    Flip single image
    """
    return tf.image.flip_up_down(image)