Reduce colors via dithering: ordered Bayer, error diffusion, or random. num_levels, method. Good for retro look or limited-color output.
Dithering is like creating a newspaper photo - it uses patterns of dots to create the illusion of more colors than are actually present. When you have a limited color palette (like only black and white), dithering arranges these limited colors in patterns that trick your eye into seeing intermediate shades.
Think of it like pointillist paintings - up close you see individual dots, but from a distance they blend together to create smooth gradients and subtle color variations.
This transform works with ANY number of channels - it processes each channel independently, whether you have a standard RGB image (3 channels), RGBA with transparency (4 channels), multispectral satellite imagery (dozens of channels), or even single-channel grayscale images.
methodWhich dithering algorithm to use. Each has different characteristics:
n_colorsHow many different color levels to keep per channel. Must be between 2 and 256.
color_modeHow to handle color channels:
error_diffusion_algorithmUsed only in "error_diffusion" method. Which specific algorithm:
bayer_matrix_sizeUsed only in "ordered" method. The size of the repeating pattern (2, 4, 8, or 16).
serpentineUsed only in "error_diffusion" method. Whether to process rows in alternating directions (left-to-right, then right-to-left). This can reduce visible "worm" artifacts that sometimes appear as diagonal lines. Slightly slower. Default: False
noise_rangeUsed only in "random" method. How much random noise to add before quantization. Larger range = more variation in the dithering pattern. Range: (-1.0, 1.0). Default: (-0.5, 0.5)
pProbability of applying this transform. Default: 0.5
>>> import numpy as np
>>> import albumentations as A
>>> # Prepare sample data
>>> image = np.random.randint(0, 256, (100, 100, 3), dtype=np.uint8)
>>>
>>> # Black and white dithering with Floyd-Steinberg
>>> transform = A.Compose([
... A.Dithering(
... method="error_diffusion",
... n_colors=2,
... error_diffusion_algorithm="floyd_steinberg",
... color_mode="grayscale",
... p=1.0
... )
... ])
>>> transformed = transform(image=image)
>>> dithered_image = transformed['image'] # Black and white dithered image
>>>
>>> # Ordered dithering with 16 colors per channel
>>> transform = A.Compose([
... A.Dithering(
... method="ordered",
... n_colors=16,
... bayer_matrix_size=8,
... color_mode="per_channel",
... p=1.0
... )
... ])
>>> transformed = transform(image=image)
>>> dithered_image = transformed['image'] # Reduced color depth with Bayer pattern
>>>
>>> # Random dithering
>>> transform = A.Compose([
... A.Dithering(
... method="random",
... n_colors=4,
... noise_range=(-0.3, 0.3),
... p=1.0
... )
... ])
>>> transformed = transform(image=image)
>>> dithered_image = transformed['image'] # Noisy dithered appearance