RandomRotate90
Randomly rotate the input by 90 degrees zero or more times.
Even with p=1.0, the transform has a 1/4 probability of being identity:
- With probability p * 1/4: no rotation (0 degrees)
- With probability p * 1/4: rotate 90 degrees
- With probability p * 1/4: rotate 180 degrees
- With probability p * 1/4: rotate 270 degrees
For example:
- With p=1.0: Each rotation angle (including 0°) has 0.25 probability
- With p=0.8: Each rotation angle has 0.2 probability, and no transform has 0.2 probability
- With p=0.5: Each rotation angle has 0.125 probability, and no transform has 0.5 probability
Common applications:
- Aerial/satellite imagery: Objects can appear in any orientation
- Medical imaging: Scans/slides may not have a consistent orientation
- Document analysis: Pages or symbols might be rotated
- Microscopy: Cell orientation is often arbitrary
- Game development: Sprites/textures that should work in multiple orientations
Not recommended for:
- Natural scene images where gravity matters (e.g., landscape photography)
- Face detection/recognition tasks
- Text recognition (unless text can appear rotated)
- Tasks where object orientation is important for classification
Note:
If your domain has both 90-degree rotation AND flip symmetries
(e.g., satellite imagery, microscopy), consider using D4 transform instead.
D4 is more efficient and mathematically correct as it:
- Samples uniformly from all 8 possible combinations of rotations and flips
- Properly represents the dihedral group D4 symmetries
- Avoids potential correlation between separate rotation and flip augmentations
`inverse()` requires `group_element` to be set explicitly; raises `ValueError` otherwise.
When group_element is specified, the transform is deterministic—useful for TTA (Test Time
Augmentation) where you need to apply each of the 4 rotations (0°, 90°, 180°, 270°) explicitly
and invert predictions. Uses the same naming as D4: C4 is the rotation subgroup of D4.
Call inverse() on a deterministic instance to get a new transform that undoes the rotation
(r90 ↔ r270, r180 ↔ r180, e ↔ e).
pprobability of applying the transform. Default: 1.0. Note that even with p=1.0, there's still a 0.25 probability of getting a 0-degree rotation (identity transform).
group_elementIf set, always apply this C4 group element: "e"=identity, "r90"=90°, "r180"=180°, "r270"=270° counterclockwise. Use for TTA. Default: None (random choice).
>>> import numpy as np
>>> import albumentations as A
>>> # Create example data
>>> image = np.random.randint(0, 256, (100, 100, 3), dtype=np.uint8)
>>> mask = np.random.randint(0, 2, (100, 100), dtype=np.uint8)
>>> bboxes = np.array([[10, 10, 50, 50], [40, 40, 80, 80]], dtype=np.float32)
>>> bbox_labels = [1, 2] # Class labels for bounding boxes
>>> keypoints = np.array([[20, 30], [60, 70]], dtype=np.float32)
>>> keypoint_labels = [0, 1] # Labels for keypoints
>>> # Define the transform
>>> transform = A.Compose([
... A.RandomRotate90(p=1.0),
... ], bbox_params=A.BboxParams(coord_format='pascal_voc', label_fields=['bbox_labels']),
... keypoint_params=A.KeypointParams(coord_format='xy', label_fields=['keypoint_labels']))
>>> # Apply the transform to all targets
>>> transformed = transform(
... image=image,
... mask=mask,
... bboxes=bboxes,
... bbox_labels=bbox_labels,
... keypoints=keypoints,
... keypoint_labels=keypoint_labels
... )
>>> rotated_image = transformed["image"]
>>> rotated_mask = transformed["mask"]
>>> rotated_bboxes = transformed["bboxes"]
>>> rotated_bbox_labels = transformed["bbox_labels"]
>>> rotated_keypoints = transformed["keypoints"]
>>> rotated_keypoint_labels = transformed["keypoint_labels"]
>>> # TTA: apply each of the 4 rotations, run inference, then undo on the predicted mask
>>> from albumentations.core.type_definitions import c4_group_elements
>>> predictions = []
>>> for element in c4_group_elements:
... aug = A.RandomRotate90(p=1.0, group_element=element)
... aug_image = aug(image=image)["image"]
... pred_mask = np.zeros((100, 100, 1), dtype=np.uint8) # placeholder for model output
... restored = aug.inverse()(image=pred_mask)["image"]
... predictions.append(restored)If your domain has both 90-degree rotation AND flip symmetries
(e.g., satellite imagery, microscopy), consider using D4 transform instead.
D4 is more efficient and mathematically correct as it:
- Samples uniformly from all 8 possible combinations of rotations and flips
- Properly represents the dihedral group D4 symmetries
- Avoids potential correlation between separate rotation and flip augmentations
inverse() requires group_element to be set explicitly; raises ValueError otherwise.
When group_element is specified, the transform is deterministic—useful for TTA (Test Time
Augmentation) where you need to apply each of the 4 rotations (0°, 90°, 180°, 270°) explicitly
and invert predictions. Uses the same naming as D4: C4 is the rotation subgroup of D4.
Call inverse() on a deterministic instance to get a new transform that undoes the rotation
(r90 ↔ r270, r180 ↔ r180, e ↔ e).