Source code for pytorch_lightning_spells.cutmix_utils

from typing import Tuple, Optional, Union, List

import numpy as np


[docs] def rand_bbox(img_shape:Tuple, lam: float, margin: float=0., count: Optional[int]=None): """ Standard CutMix bounding-box Generates a random square bbox based on lambda value. This impl includes support for enforcing a border margin as percent of bbox dimensions. Args: img_shape: Image shape as tuple lam: Cutmix lambda value margin: Percentage of bbox dimension to enforce as margin (reduce amount of box outside image) count: Number of bbox to generate """ ratio = np.sqrt(1 - lam) img_h, img_w = img_shape[-2:] cut_h, cut_w = int(img_h * ratio), int(img_w * ratio) margin_y, margin_x = int(margin * cut_h), int(margin * cut_w) cy = np.random.randint(0 + margin_y, img_h - margin_y, size=count) cx = np.random.randint(0 + margin_x, img_w - margin_x, size=count) yl = np.clip(cy - cut_h // 2, 0, img_h) yh = np.clip(cy + cut_h // 2, 0, img_h) xl = np.clip(cx - cut_w // 2, 0, img_w) xh = np.clip(cx + cut_w // 2, 0, img_w) return yl, yh, xl, xh
[docs] def rand_bbox_minmax(img_shape: Tuple, minmax: Union[Tuple, List], count: Optional[int]=None): """ Min-Max CutMix bounding-box Inspired by Darknet cutmix impl, generates a random rectangular bbox based on min/max percent values applied to each dimension of the input image. Typical defaults for minmax are usually in the .2-.3 for min and .8-.9 range for max. Args: img_shape: Image shape as tuple minmax: Min and max bbox ratios (as percent of image size) count: Number of bbox to generate """ assert len(minmax) == 2 img_h, img_w = img_shape[-2:] cut_h = np.random.randint( int(img_h * minmax[0]), int(img_h * minmax[1]), size=count) cut_w = np.random.randint( int(img_w * minmax[0]), int(img_w * minmax[1]), size=count) yl = np.random.randint(0, img_h - cut_h, size=count) xl = np.random.randint(0, img_w - cut_w, size=count) yu = yl + cut_h xu = xl + cut_w return yl, yu, xl, xu
[docs] def cutmix_bbox_and_lam(img_shape: Tuple, lam, ratio_minmax=None, correct_lam=True, count: Optional[int]=None): """ Generate bbox and apply lambda correction. """ if ratio_minmax is not None: yl, yu, xl, xu = rand_bbox_minmax(img_shape, ratio_minmax, count=count) else: yl, yu, xl, xu = rand_bbox(img_shape, lam, count=count) if correct_lam or ratio_minmax is not None: bbox_area = (yu - yl) * (xu - xl) lam = 1. - bbox_area / float(img_shape[-2] * img_shape[-1]) return (yl, yu, xl, xu), lam