doctr.transforms#
Data transformations for training and inference. Inspired by
torchvision, they are expressed as composable modules. Image transforms apply to
the image only; sample transforms (wrapped in SampleCompose) also update the target, e.g. the boxes of a
rotated image.
from torchvision.transforms.v2 import Compose
from doctr import transforms as T
img_transforms = Compose([
T.Resize((32, 128), preserve_aspect_ratio=True),
T.RandomApply(T.ColorInversion(), 0.1),
T.RandomApply(T.GaussianNoise(mean=0.1, std=0.1), 0.1),
])
Image transformations#
- class Resize(
- size,
- interpolation=F.InterpolationMode.BILINEAR,
- preserve_aspect_ratio=False,
- symmetric_pad=False,
- return_padding_mask=False,
Resize the input image to the given size
>>> import torch >>> from doctr.transforms import Resize >>> from doctr.utils import Sample >>> transfo = Resize((64, 64), preserve_aspect_ratio=True, symmetric_pad=True) >>> out = transfo(Sample(image=torch.rand((3, 64, 64))))
- Parameters:
size (int | tuple[int, int]) – output size in pixels, either a tuple (height, width) or a single integer for square images
interpolation – interpolation mode to use for resizing, default is bilinear
preserve_aspect_ratio (bool) – whether to preserve the aspect ratio of the image, if True, the image will be resized to fit within the target size while maintaining its aspect ratio
symmetric_pad (bool) – whether to symmetrically pad the image to the target size, if True, the image will be padded equally on both sides to fit the target size
return_padding_mask (bool) – whether to return a boolean mask alongside the image, with True on valid (image content) pixels and False on padded areas. This matches how masks propagate through the other transforms (padding and rotation fill new areas with False).
- class RandomResize(
- scale_range=(0.3, 0.9),
- preserve_aspect_ratio=False,
- symmetric_pad=False,
- p=0.5,
Randomly resize the input image and align corresponding targets
>>> import torch >>> from doctr.transforms import RandomResize >>> from doctr.utils import Sample >>> transfo = RandomResize((0.3, 0.9), preserve_aspect_ratio=True, symmetric_pad=True, p=0.5) >>> out = transfo(Sample(image=torch.rand((3, 64, 64))))
- Parameters:
scale_range (tuple[float, float]) – range of the resizing factor for width and height (independently)
preserve_aspect_ratio (bool | float) – whether to preserve the aspect ratio of the image,
value (given a float)
probability (the symmetric padding will be applied with this)
symmetric_pad (bool | float) – whether to symmetrically pad the image,
value
probability
p (float) – probability to apply the transformation
- class GaussianNoise(mean=0.0, std=1.0)[source]#
Adds Gaussian Noise to the input tensor
>>> import torch >>> from doctr.transforms import GaussianNoise >>> from doctr.utils import Sample >>> transfo = GaussianNoise(0., 1.) >>> out = transfo(Sample(image=torch.rand((3, 224, 224))))
- class GaussianBlur(sigma)[source]#
Apply Gaussian Blur to the input tensor
>>> import torch >>> from doctr.transforms import GaussianBlur >>> from doctr.utils import Sample >>> transfo = GaussianBlur(sigma=(0.0, 1.0)) >>> out = transfo(Sample(image=torch.rand((3, 224, 224))))
- class ChannelShuffle[source]#
Randomly shuffle channel order of a given image
>>> import torch >>> from doctr.transforms import ChannelShuffle >>> from doctr.utils import Sample >>> transfo = ChannelShuffle() >>> out = transfo(Sample(image=torch.rand((3, 224, 224))))
- class ColorInversion(min_val=0.5)[source]#
Applies the following tranformation to a tensor (image or batch of images): convert to grayscale, colorize (shift 0-values randomly), and then invert colors
>>> import torch >>> from doctr.transforms import ColorInversion >>> from doctr.utils import Sample >>> transfo = ColorInversion(min_val=0.6) >>> out = transfo(Sample(image=torch.rand(8, 64, 64, 3)))
- Parameters:
min_val (float) – range [min_val, 1] to colorize RGB pixels
- class RandomShadow(opacity_range=None)[source]#
Adds random shade to the input image
>>> import torch >>> from doctr.transforms import RandomShadow >>> from doctr.utils import Sample >>> transfo = RandomShadow((0., 1.)) >>> out = transfo(Sample(image=torch.rand((3, 64, 64))))
- class RandomGlare(opacity_range=None, num_spots=(1, 3))[source]#
Adds soft bright reflections to the image, like a light source mirrored on a photographed screen or a glossy sheet
>>> import torch >>> from doctr.transforms import RandomGlare >>> from doctr.utils import Sample >>> transfo = RandomGlare((0.2, 0.7)) >>> out = transfo(Sample(image=torch.rand((3, 64, 64))))
- class RandomLighting(strength_range=None)[source]#
Multiplies the image by a smooth low-frequency brightness field: uneven lighting, the shading of a crumpled or curved sheet, vignetting
>>> import torch >>> from doctr.transforms import RandomLighting >>> from doctr.utils import Sample >>> transfo = RandomLighting((0.1, 0.4)) >>> out = transfo(Sample(image=torch.rand((3, 64, 64))))
Geometric transformations#
- class RandomHorizontalFlip(p=0.5)[source]#
Randomly flip the input image horizontally
>>> import torch >>> from doctr.transforms import RandomHorizontalFlip >>> from doctr.utils import Sample >>> transfo = RandomHorizontalFlip(p=1.0) >>> out = transfo(Sample(image=torch.rand((3, 224, 224)), target=np.array([[0.1, 0.2, 0.3, 0.4]])))
- class RandomRotate(max_angle=5.0, expand=False)[source]#
Randomly rotate a tensor image and its boxes
>>> import torch >>> from doctr.transforms import RandomRotate >>> transfo = RandomRotate(max_angle=30, expand=True) >>> out = transfo(Sample(image=torch.rand(1, 64, 64, 3), target=np.array([[0.1, 0.1, 0.9, 0.9]]), mask=None))
- class RandomCrop(scale=(0.08, 1.0), ratio=(0.75, 1.33))[source]#
Randomly crop a tensor image and its boxes
>>> import torch >>> from doctr.transforms import RandomCrop >>> from doctr.utils import Sample >>> transfo = RandomCrop(scale=(0.5, 1.0), ratio=(0.75, 1.33)) >>> out = transfo(Sample(image=torch.rand(1, 64, 64, 3), target=np.array([[0.1, 0.1, 0.9, 0.9]]), mask=None))
- class RandomPerspective(distortion=0.2)[source]#
Warps the image and its boxes with a random perspective, as if the page were photographed at an angle
>>> import numpy as np >>> import torch >>> from doctr.transforms import RandomPerspective >>> from doctr.utils import Sample >>> transfo = RandomPerspective(distortion=0.2) >>> out = transfo(Sample(image=torch.rand((3, 64, 64)), target=np.array([[0.1, 0.1, 0.5, 0.5]])))
- Parameters:
distortion (float) – maximum relative displacement of every image corner (0.2 = up to 20% of the width / height)
Composition#
- class SampleCompose(transforms)[source]#
Implements a wrapper that will apply transformations sequentially on both image and target
>>> import numpy as np >>> import torch >>> from doctr.transforms import SampleCompose, ImageTransform, ColorInversion, RandomRotate >>> from doctr.utils import Sample >>> transfos = SampleCompose([ImageTransform(ColorInversion((32, 32))), RandomRotate(30)]) >>> out, out_boxes = transfos(Sample(image=torch.rand(8, 64, 64, 3), target=np.zeros((2, 4))))
- class ImageTransform(transform)[source]#
Implements a transform wrapper to turn an image-only transformation into an image+target transform
>>> import torch >>> from doctr.transforms import ImageTransform, ColorInversion >>> from doctr.utils import Sample >>> transfo = ImageTransform(ColorInversion((32, 32))) >>> out = transfo(Sample(image=torch.rand(8, 64, 64, 3)))
- class ImageTorchvisionTransform(transform)[source]#
Implements a transform wrapper to turn a torchvision image-only transformation into an image+target transform
>>> import torch >>> from torchvision import transforms >>> from doctr.transforms import ImageTorchvisionTransform >>> from doctr.utils import Sample >>> transfo = ImageTorchvisionTransform(transforms.ColorJitter(brightness=0.5)) >>> out, _ = transfo(Sample(image=torch.rand(8, 64, 64, 3)))
- class OneOf(transforms)[source]#
Randomly apply one of the input transformations
>>> import torch >>> from doctr.transforms import OneOf, JpegQuality, Gamma >>> from doctr.utils import Sample >>> transfo = OneOf([JpegQuality(), Gamma()]) >>> out = transfo(Sample(image=torch.rand(1, 64, 64, 3)))
- class RandomApply(transform, p=0.5)[source]#
Apply with a probability p the input transformation
>>> import torch >>> from doctr.transforms import RandomApply, Gamma >>> from doctr.utils import Sample >>> transfo = RandomApply(Gamma(), p=.5) >>> out = transfo(Sample(image=torch.rand(1, 64, 64, 3), target=np.array([[0.1, 0.1, 0.9, 0.9]]), mask=None))