AlbumentationsX vs PIL/Pillow

Compare AlbumentationsX with PIL/Pillow for image augmentation: API differences, CPU benchmark results, and migration examples.

What Is Different?

Pillow is an image toolkit. AlbumentationsX is an augmentation pipeline library. That sounds subtle, but it changes the shape of the code: Pillow gives you image operations; AlbumentationsX gives you randomized, reproducible transforms that keep images, masks, bounding boxes, and keypoints synchronized.

  • Pillow works with PIL Image objects; AlbumentationsX works with NumPy arrays and returns a dictionary of augmented targets.
  • Pillow is great for loading, saving, drawing, and simple image edits; AlbumentationsX is built for training-time augmentation pipelines.
  • AlbumentationsX has first-class random composition, probabilities, target synchronization, and bbox/keypoint parameter handling.
  • Pillow code usually becomes manual orchestration when masks or labels must follow the image; AlbumentationsX keeps that in the pipeline contract.

Benchmark vs PIL/Pillow

The benchmark data is generated during the site build from the published benchmark artifacts. Results are shown for the full PyTorch DataLoader pipeline and for the single-operation RGB micro benchmark. Published GPU artifacts are shown in the DataLoader table where they exist; the RGB micro table on this page is CPU.

DataLoader Pipeline

End-to-end in-memory DataLoader throughput with 8 workers, batch size 256, normalization, tensor conversion, batching, and collation included. The table shows the variable transform name only. Higher images/second is better. CPU and GPU columns are shown where published artifacts exist.

26 / 26
pipelines where AlbumentationsX is faster
1.41x
median speedup
1.35x-1.70x IQR
2.2.6 vs 12.2.0
library versions
from generated benchmark metadata
TransformSpeedup
Albx / best
AlbumentationsX
CPU · 2.2.6
PIL/Pillow
CPU · 12.2.0
Resize≥67x1350 ± 0≤20
MedianBlur24x4038 ± 0167 ± 0
UnsharpMask2.2x4635 ± 02129 ± 0
GaussianBlur2.0x5029 ± 02474 ± 0
EnhanceEdge1.8x4923 ± 02688 ± 0
EnhanceDetail1.7x5033 ± 02922 ± 0
RandomResizedCrop1.7x5056 ± 02961 ± 0
Contrast1.7x5435 ± 03244 ± 0
Blur1.7x5507 ± 03326 ± 0
Shear1.6x4141 ± 02621 ± 0
Affine1.6x4528 ± 02902 ± 0
Brightness1.5x5310 ± 03551 ± 0
Invert1.4x5569 ± 03890 ± 0
Posterize1.4x5431 ± 03897 ± 0
Solarize1.4x5407 ± 03890 ± 0
Pad1.4x4996 ± 03603 ± 0
JpegCompression1.4x4267 ± 03140 ± 0
Saturation1.4x4646 ± 03436 ± 0
VerticalFlip1.4x5512 ± 04078 ± 0
Grayscale1.3x5378 ± 03984 ± 0
Transpose1.3x5338 ± 04081 ± 0
AutoContrast1.3x4646 ± 03577 ± 0
Equalize1.3x4511 ± 03528 ± 0
RandomCrop2241.3x5130 ± 04034 ± 0
HorizontalFlip1.2x5002 ± 04074 ± 0
Rotate1.2x4865 ± 03981 ± 0
CLAHE3505 ± 0
ChannelDropout5314 ± 0
ChannelShuffle5467 ± 0
ColorJiggle4255 ± 0
ColorJitter4299 ± 0
CornerIllumination3969 ± 0
Elastic2878 ± 0
Erasing5415 ± 0
GaussianIllumination3656 ± 0
GaussianNoise3415 ± 0
Hue4723 ± 0
LinearIllumination4179 ± 0
LongestMaxSize1363 ± 0
MotionBlur4785 ± 0
OpticalDistortion3579 ± 0
Perspective4132 ± 0
PhotoMetricDistort4269 ± 0
PlankianJitter4979 ± 0
PlasmaBrightness2727 ± 0
PlasmaContrast2291 ± 0
PlasmaShadow2797 ± 0
RGBShift4977 ± 0
Rain4198 ± 0
RandomGamma5450 ± 0
RandomJigsaw4863 ± 0
RandomRotate905087 ± 0
SaltAndPepper4508 ± 0
Sharpen4978 ± 0
SmallestMaxSize1370 ± 0
Snow4135 ± 0
ThinPlateSpline743 ± 0

Micro Benchmark

The benchmark below compares single-threaded RGB image augmentation throughput. Pillow receives PIL images; AlbumentationsX receives OpenCV-loaded RGB NumPy arrays. Higher images/second is better.

23 / 24
transforms where AlbumentationsX is faster
4.56x
median speedup
3.01x-7.69x IQR
2.2.6 vs 12.2.0
library versions
from generated benchmark metadata
TransformSpeedup
Albx / best
albumentationsx
2.2.6
PIL/Pillow
12.2.0
MedianBlur≥42x843 ± 4≤20
Contrast16x6933 ± 30443 ± 1
GaussianBlur14x2343 ± 4169 ± 1
Brightness11x6912 ± 13609 ± 4
Blur11x4449 ± 17409 ± 3
EnhanceDetail7.7-7.9x2148 ± 13275 ± 1
Invert7.5-7.8x15095 ± 611974 ± 26
Posterize7.2-7.3x14399 ± 581977 ± 7
UnsharpMask6.7-6.8x906 ± 2134 ± 0
EnhanceEdge6.2-6.4x1373 ± 16219 ± 0
Resize6.1-6.4x2463 ± 37396 ± 4
Solarize4.9-5.0x9760 ± 341966 ± 6
Pad4.1-4.2x13181 ± 1183167 ± 37
VerticalFlip3.8-3.9x14051 ± 553670 ± 21
Shear3.6x784 ± 6217 ± 0
Affine3.3-3.4x872 ± 8264 ± 2
Grayscale3.2-3.3x5194 ± 11591 ± 15
HorizontalFlip3.2-3.3x8416 ± 192612 ± 21
Transpose2.3-2.4x4627 ± 261934 ± 35
Saturation1.7x847 ± 17500 ± 3
AutoContrast1.4x1243 ± 19899 ± 4
Rotate1.3-1.4x1408 ± 401045 ± 13
JpegCompression1.3-1.4x692 ± 7515 ± 1
Equalize0.9x807 ± 3882 ± 12
CLAHE283 ± 1
ChannelDropout6810 ± 65
ChannelShuffle4337 ± 13
ColorJiggle639 ± 5
ColorJitter641 ± 1
CornerIllumination425 ± 2
Elastic191 ± 0
Erasing9511 ± 74
GaussianIllumination388 ± 1
GaussianNoise225 ± 0
Hue967 ± 1
LinearIllumination521 ± 1
LongestMaxSize2825 ± 42
MotionBlur1953 ± 21
OpticalDistortion274 ± 1
Perspective559 ± 2
PhotoMetricDistort581 ± 4
PlankianJitter2253 ± 17
PlasmaBrightness267 ± 1
PlasmaContrast143 ± 0
PlasmaShadow420 ± 3
RGBShift2292 ± 3
Rain1259 ± 2
RandomCrop22438380 ± 192
RandomGamma9938 ± 46
RandomJigsaw5172 ± 16
RandomResizedCrop7150 ± 19
RandomRotate905990 ± 85
SaltAndPepper738 ± 10
Sharpen1388 ± 5
SmallestMaxSize2017 ± 25
Snow489 ± 3
ThinPlateSpline52 ± 0

See the aggregate image benchmark or inspect the benchmark source code.

Conversion Guide

The main conversion is to move from calling Pillow methods one at a time to defining an AlbumentationsX Compose pipeline.

  • Convert PIL images to NumPy arrays before augmentation.
  • Replace manual randomness with transform-level p values.
  • Keep image-adjacent targets in the same Compose call instead of transforming them separately.
  • Convert back to PIL only if downstream code specifically needs PIL objects.
Pillow
from PIL import Image, ImageEnhance
import random

image = Image.open("image.jpg").convert("RGB")

if random.random() < 0.5:
    image = image.transpose(Image.Transpose.FLIP_LEFT_RIGHT)

if random.random() < 0.5:
    image = ImageEnhance.Brightness(image).enhance(1.2)
AlbumentationsX
import albumentations as A
import cv2

transform = A.Compose([
    A.HorizontalFlip(p=0.5),
    A.RandomBrightnessContrast(brightness_limit=0.2, contrast_limit=0.0, p=0.5),
])

image = cv2.cvtColor(cv2.imread("image.jpg"), cv2.COLOR_BGR2RGB)
image = transform(image=image)["image"]

Use AlbumentationsX When

  • Training-time augmentation where randomness, replayability, and target synchronization matter.
  • Segmentation, detection, keypoint, OCR, document, satellite, medical, or any multi-target computer vision workflow.
  • CPU data-loader pipelines where augmentation speed can become the training bottleneck.

Use PIL/Pillow When

  • Image IO, format conversion, drawing, thumbnails, and lightweight one-off image manipulation.
  • Small scripts where you only touch a single image and do not need labels, masks, or reproducible random policies.