CropNonEmptyMaskIfExists

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

Crop area with mask if mask is non-empty, else make random crop.

This transform attempts to crop a region containing a mask (non-zero pixels). If the mask is empty or not provided, it falls back to a random crop. This is particularly useful for segmentation tasks where you want to focus on regions of interest defined by the mask.

Arguments
height
int

Vertical size of crop in pixels. Must be > 0.

width
int

Horizontal size of crop in pixels. Must be > 0.

ignore_values
list[int] | None

Values to ignore in mask, 0 values are always ignored. For example, if background value is 5, set ignore_values=[5] to ignore it. Default: None.

ignore_channels
list[int] | None

Channels to ignore in mask. For example, if background is the first channel, set ignore_channels=[0] to ignore it. Default: None.

p
float
1

Probability of applying the transform. Default: 1.0.

Examples
>>> import numpy as np
>>> import albumentations as A
>>>
>>> # Prepare sample data
>>> image = np.random.randint(0, 256, (100, 100, 3), dtype=np.uint8)
>>> # Create a mask with non-empty region in the center
>>> mask = np.zeros((100, 100), dtype=np.uint8)
>>> mask[25:75, 25:75] = 1  # Create a non-empty region in the mask
>>>
>>> # Create bounding boxes and keypoints in the mask region
>>> bboxes = np.array([
...     [20, 20, 60, 60],     # Box overlapping with non-empty region
...     [30, 30, 70, 70],     # Box mostly inside non-empty region
... ], dtype=np.float32)
>>> bbox_labels = ['cat', 'dog']
>>>
>>> # Add some keypoints inside mask region
>>> keypoints = np.array([
...     [40, 40],             # Inside non-empty region
...     [60, 60],             # At edge of non-empty region
...     [90, 90]              # Outside non-empty region
... ], dtype=np.float32)
>>> keypoint_labels = ['eye', 'nose', 'ear']
>>>
>>> # Define transform that will crop around the non-empty mask region
>>> transform = A.Compose([
...     A.CropNonEmptyMaskIfExists(
...         height=50,
...         width=50,
...         ignore_values=None,
...         ignore_channels=None,
...         p=1.0
...     ),
... ], bbox_params=A.BboxParams(
...     format='pascal_voc',
...     label_fields=['bbox_labels']
... ), keypoint_params=A.KeypointParams(
...     format='xy',
...     label_fields=['keypoint_labels']
... ))
>>>
>>> # Apply the transform
>>> transformed = transform(
...     image=image,
...     mask=mask,
...     bboxes=bboxes,
...     bbox_labels=bbox_labels,
...     keypoints=keypoints,
...     keypoint_labels=keypoint_labels
... )
>>>
>>> # Get the transformed data
>>> transformed_image = transformed['image']  # 50x50 image centered on mask region
>>> transformed_mask = transformed['mask']    # 50x50 mask showing part of non-empty region
>>> transformed_bboxes = transformed['bboxes']  # Bounding boxes adjusted to new coordinates
>>> transformed_bbox_labels = transformed['bbox_labels']  # Labels preserved for visible boxes
>>> transformed_keypoints = transformed['keypoints']  # Keypoints adjusted to new coordinates
>>> transformed_keypoint_labels = transformed['keypoint_labels']  # Labels for visible keypoints
Notes
  • If a mask is provided, the transform will try to crop an area containing non-zero (or non-ignored) pixels.
  • If no suitable area is found in the mask or no mask is provided, it will perform a random crop.
  • The crop size (height, width) must not exceed the original image dimensions.
  • Bounding boxes and keypoints are also cropped along with the image and mask.