AlbumentationsExplore
DocumentationExploreAdoptionCommercial LicenseBlog
GitHub

BBoxSubsetSafeRandomCrop

Targets:
image
mask
bboxes
keypoints
volume
mask3d
Image Types:uint8, float32

Random crop around the union of a randomly sampled subset of bboxes, for use when preserving every box is unnecessary and a variable-size crop is preferable.

Unlike BBoxSafeRandomCrop, which guarantees every bbox survives the crop, this transform samples a random subset of the available bboxes (sized between subset_fraction_range[0] and subset_fraction_range[1] of the total count), computes the union of only that subset, and crops around it. Bboxes outside the sampled subset may remain complete, be clipped, or be removed entirely depending on where they fall relative to the crop.

This makes BBoxSubsetSafeRandomCrop useful for:

  • Dense-detection datasets with many overlapping/nearby objects, where forcing every box into one crop would be too restrictive
  • Training pipelines that benefit from varied, object-focused crops without a fixed output size

The algorithm:

  1. If no bboxes exist, follows BBoxSafeRandomCrop's erosion-based random crop behavior.
  2. Otherwise, samples one count and one unique subset of bboxes.
  3. Computes their eroded union, then directly samples integer crop dimensions and position that contain it and satisfy the requested aspect-ratio range.
  4. If no such crop exists, returns the full image to preserve the selected subset.
Arguments
subset_fraction_range
tuple[float, float]
[0.5, 1]

Fraction of bboxes to select for the union, as (min_fraction, max_fraction). Must satisfy 0 < min_fraction <= max_fraction <= 1. A value of (1.0, 1.0) always selects every bbox. Defaults to (0.5, 1.0).

erosion_rate
float
0

Controls how much the valid crop region can deviate from the selected bboxes' union. Must be in range [0.0, 1.0].

  • 0.0: crop must contain the exact union of the selected bboxes (guarantees every selected bbox is preserved)
  • 1.0: no selected bbox is protected Defaults to 0.0.
aspect_ratio_range
tuple[float, float]
[0.5, 2]

Inclusive (height / width) range for the sampled crop when a feasible crop exists. Defaults to (0.5, 2.0).

p
float
1

Probability of applying the transform. Defaults to 1.0.

Examples
>>> import numpy as np
>>> import albumentations as A
>>>
>>> image = np.random.randint(0, 256, (200, 200, 3), dtype=np.uint8)
>>> mask = np.random.randint(0, 2, (200, 200), dtype=np.uint8)
>>> bboxes = np.array(
...     [[10, 10, 40, 40], [60, 60, 90, 90], [120, 20, 150, 50], [30, 120, 70, 160]],
...     dtype=np.float32,
... )
>>> bbox_labels = [1, 2, 3, 4]
>>>
>>> transform = A.Compose(
...     [
...         A.BBoxSubsetSafeRandomCrop(
...             subset_fraction_range=(0.5, 1.0),
...             erosion_rate=0.2,
...             aspect_ratio_range=(0.5, 2.0),
...         ),
...     ],
...     bbox_params=A.BboxParams(coord_format="pascal_voc", label_fields=["bbox_labels"]),
... )
>>>
>>> result = transform(image=image, mask=mask, bboxes=bboxes, bbox_labels=bbox_labels)
>>> transformed_image = result["image"]
>>> transformed_bboxes = result["bboxes"]
Notes
  • IMPORTANT: only bboxes selected in the sampled subset are guaranteed to survive when erosion_rate=0.0. Non-selected bboxes may be clipped or removed like any ordinary crop.
  • If no crop can contain the selected union and satisfy aspect_ratio_range, the full image is returned. Its aspect ratio can fall outside the requested range.
  • The crop size is not fixed; add A.Resize afterward for a fixed output shape.