AlbumentationsExplore
DocumentationExploreAdoptionPricingBlog
GitHub

AnnotationArtifacts

Targets:
image
volume
Image Types:uint8, float32

Add synthetic text, arrows, boxes, guide lines, and callouts that mimic scientific markup. Use to harden models against annotation artifacts.

This transform simulates sparse human annotation artifacts commonly found in scientific figures, medical images, microscopy screenshots, and competition data. It draws short text tokens, rectangles, arrows, horizontal or vertical guide lines, and zoom-callout boxes directly on the image.

Arguments
element_types
tuple[['text', 'rectangle', 'arrow', 'line', 'callout'], ...]
[text, rectangle, arrow, line, callout]

Artifact types to sample. Default: ("text", "rectangle", "arrow", "line", "callout").

element_probabilities
tuple[float, ...]
[0.35, 0.2, 0.2, 0.15, 0.1]

Sampling weights matching element_types. Values must be non-negative and at least one value must be positive. Default: (0.35, 0.2, 0.2, 0.15, 0.1).

count_range
tuple[int, int]
[1, 3]

Range for the number of artifacts drawn per image. Default: (1, 3).

text_length_range
tuple[int, int]
[1, 5]

Range for generated text token length. Text uses uppercase ASCII letters and digits. Default: (1, 5).

font_scale_range
tuple[float, float]
[0.3, 1.2]

Range for OpenCV Hershey font scale. Default: (0.3, 1.2).

thickness_range
tuple[int, int]
[1, 3]

Range for line, rectangle, arrow, and text thickness. Default: (1, 3).

size_ratio_range
tuple[float, float]
[0.1, 0.35]

Range for rectangle and callout size as a fraction of image width and height. Default: (0.1, 0.35).

line_length_ratio_range
tuple[float, float]
[0.1, 0.8]

Range for line and arrow length as a fraction of the smaller image dimension. Default: (0.1, 0.8).

tip_length_range
tuple[float, float]
[0.2, 0.4]

Range for arrowhead length as a fraction of arrow length. Default: (0.2, 0.4).

corner_prob
float
0.6

Probability of placing artifacts near image corners or edges instead of uniformly inside the image. Default: 0.6.

black_white_prob
float
0.85

Probability of choosing black or white instead of red for an artifact. Default: 0.85.

line_geometry
axis_aligned | random_endpoints | random_angle
axis_aligned

Geometry used for line artifacts. "axis_aligned" preserves horizontal and vertical lines. "random_endpoints" samples both endpoints independently. "random_angle" samples a start point, angle, and length. Default: "axis_aligned".

line_styles
tuple[['solid', 'dashed', 'dotted'], ...]
[solid, dashed, dotted]

Line styles sampled for lines, arrows, and callouts. Default: ("solid", "dashed", "dotted").

line_style_probabilities
tuple[float, ...]
[0.55, 0.35, 0.1]

Sampling weights matching line_styles. Values must be non-negative and at least one value must be positive. Default: (0.55, 0.35, 0.1).

random_color_prob
float
0

Probability of sampling every image channel independently and uniformly from [0, 255]. The remaining probability uses color_palette when provided, otherwise the legacy black/white/red policy. Default: 0.0.

color_palette
tuple[tuple[int, ...], ...] | None

Optional artifact colors in [0, 255]. Colors are truncated or extended using their last value to match the image channels. Default: None.

color_palette_probabilities
tuple[float, ...] | None

Optional sampling weights matching color_palette. When omitted, palette colors are sampled uniformly. Default: None.

line_length_range
tuple[int, int] | None

Optional length range in pixels for "random_angle" lines. When omitted, line_length_ratio_range controls their length. Default: None.

p
float
0.5

Probability of applying the transform. Default: 0.5.

Examples
>>> import numpy as np
>>> import albumentations as A
>>>
>>> image = np.random.randint(0, 256, (320, 320, 3), dtype=np.uint8)
>>> transform = A.Compose([
...     A.AnnotationArtifacts(
...         element_types=("text", "rectangle", "arrow", "line", "callout"),
...         element_probabilities=(0.35, 0.2, 0.2, 0.15, 0.1),
...         count_range=(1, 3),
...         corner_prob=0.6,
...         p=1.0,
...     )
... ])
>>> result = transform(image=image)
>>> augmented_image = result["image"]
Notes
  • This is an image-only transform: masks, bounding boxes, and keypoints are not modified.
  • Colors are adapted to the number of channels; black and white affect all channels, while red maps to the first channel and pads remaining channels with zero.
  • Palette and uniformly sampled colors use uint8-scale values. Float32 images are rendered through the transform's dtype adapter, which maps those values to [0, 1].
  • Random values are sampled before drawing, so replay and deterministic pipelines preserve the exact generated artifacts.
See Also
  • TextImage: Metadata-driven rendering of text inside known bounding boxes.
  • OverlayElements: Paste supplied overlay images or masks onto an image.
  • CoarseDropout: Remove rectangular regions instead of adding annotation markup.
References
  • Uladzislau Leketushhttps://www.linkedin.com/in/leketush/
  • Original augmentation gisthttps://gist.github.com/vlad3996/00724aafce45374214e16eb9eb07e893
  • Kaggle 1st place solutionhttps://github.com/vlad3996/forgeryscope/
  • Competitionhttps://www.kaggle.com/competitions/recodai-luc-scientific-image-forgery-detection