Release 2.3.1

Summary

  • New fill="grayscale" mode for the region/object dropout family, including arbitrary channel counts for multispectral images.
  • Compose and direct transform RNG state now resynchronizes correctly inside PyTorch DataLoader workers, including worker respawns, persistent workers, and pickled pipeline objects.
  • Instance binding now preserves KeypointParams.label_mapping when keypoint label fields are rewritten internally, and label swaps stay scoped to each instance.
  • CI and local quality gates were modernized with uv dev dependencies, Pyrefly, CodeQL, pip-audit, zizmor, Dependabot, pinned GitHub Actions, and a fast local quality gate.
  • Documentation now points transform links to the merged albumentations.ai/explore/transform/... routes.

Breaking changes

None.

New features

Grayscale fill for dropout transforms

This release adds the new dropout fill mode fill="grayscale".

It is supported by the shared BaseDropout path used by:

MaskDropout also supports fill="grayscale" for object-shaped dropout regions.

This feature does not apply to PixelDropout or ChannelDropout, because those transforms use different fill/drop-value APIs.

The grayscale fill path converts only the dropped image regions to grayscale while preserving shape, dtype, and channel count. It supports 1-channel, RGB, and multispectral images; regression tests cover 1, 3, and 5 channels for both uint8 and float32.

For single-channel images, grayscale fill is a no-op for the image values. For multi-channel images, every changed pixel gets repeated grayscale values across all channels.

For the BaseDropout transforms above, fill_mask must be None when fill="grayscale" because the image region is transformed rather than replaced with a mask fill value. MaskDropout keeps its separate fill_mask behavior for the mask target.

Example:

import albumentations as A

transform = A.CoarseDropout(
    num_holes_range=(1, 3),
    hole_height_range=(0.1, 0.2),
    hole_width_range=(0.1, 0.2),
    fill="grayscale",
    p=1.0,
)

Bug fixes

Grayscale fill mask handling (63bc7e5)

Object dropout masks are cast to boolean before grayscale indexing, so MaskDropout applies grayscale fill to the intended dropped pixels.

PyTorch DataLoader worker RNG synchronization (#272, #273)

Pipelines copied into PyTorch DataLoader workers now refresh their runtime RNG state from the active worker seed instead of replaying stale RNG state from the parent process. This fixes repeated augmentation geometry in unseeded pipelines after worker respawns.

Seeded pipelines remain reproducible when the same Compose seed and DataLoader generator seed are reused. Persistent workers keep advancing their RNG stream across epochs, and explicit user-provided RNG objects from set_random_state remain under user control.

The same worker-aware synchronization now applies to direct transform usage, not only Compose.

Instance-bound keypoint label mappings (#261)

When instance_binding rewrites public keypoint label fields to internal fields, KeypointParams.label_mapping is now remapped alongside them. Public serialization and initialization parameters are cleaned back to the user-facing field names.

Keypoint label swaps are also scoped per instance, so paired labels such as left/right landmarks are not swapped across different object instances.

Compose subtraction error compatibility (#268)

Compose subtraction now raises ComposeTransformNotFoundError as both an ArithmeticError and a ValueError, preserving the documented ValueError compatibility while aligning with operator semantics.

Misc

  • README.md transform links now use https://albumentations.ai/explore/transform/<TransformName>/.
  • Release-note guidance and transform docs generation were updated to use the same explore URL format.
  • CONTRIBUTING.md now points to the correct contributor license agreement URL.
  • Assistant rules and project skills moved from Cursor-specific paths into .codex/; CLAUDE.md was removed and the shared guidance was renamed to docs/contributing/codex_guidelines.md.
  • pyproject.toml gained a uv dependency-groups.dev section and Pyrefly configuration.
  • CI now includes security checks; Pyrefly was folded into the main CI/pre-commit flow after cleanup.
  • tools/quality_gate.py adds a fast local quality gate covering repo checks, pre-commit, tests, import smoke checks, and Pyrefly.
  • CI, pre-commit, security, and publish workflow dependencies were folded forward from dependency update PRs.
  • No runtime dependency bump is included in this range.

Commits

CommitPRDescription
18f6026#260docs: fix contributing CLA link
eec2c46#261fix(compose): preserve keypoint label mappings with instance binding
35e4146#263docs: update explore transform links
3aa9ab1#265add repository manifest URL
35ff868#262feat(erasing): initial fill="grayscale" implementation for Erasing
1e9d3c5#267chore: migrate assistant assets to .codex
8c493a3#268modernize quality gates, CI security checks, Pyrefly typing, and Compose subtraction compatibility
9d9eb8d#272fix(compose): refresh unseeded worker RNG from PyTorch DataLoader
0baec43#273fix(compose): sync RNG state in DataLoader workers
b5c86ce-fix(dropout): ship fill="grayscale" across dropout fill transforms with any channel count
63bc7e5-fix(dropout): harden grayscale fill mask handling
7b092ca-docs(dropout): clarify grayscale fill mask constraints
9b33bd6-cleanup Pyrefly workflow and pre-commit integration
f451a0e-chore(deps): fold in dependency update PRs