Pixelate Annotator

Apply pixelation effect to detected regions for privacy protection with a distinctive blocky appearance.

Output
PixelFlow Pixelate Annotator

Overview

The pixelate() annotator creates a blocky, mosaic-like effect on detected regions by downscaling and upscaling with nearest neighbor interpolation. Unlike Gaussian blur which creates smooth gradients, pixelation produces sharp, clearly artificial blocks - making it obvious that privacy redaction has been applied.

Python
pf.annotators.pixelate(image, detections)

Function Signature

Python
def pixelate(    image: np.ndarray,    detections: Detections,    pixel_size: Optional[int] = None,    padding_percent: float = 0.05) -> np.ndarray

Parameters

Parameter Type Default Description
image np.ndarray required Input image in BGR format. Modified in-place.
detections Detections required PixelFlow detections with bounding boxes.
pixel_size int or None None Size of pixel blocks. Larger = blockier. None = auto.
padding_percent float 0.05 Extra padding around detection as % of bbox size (0.0-0.5).

Returns:
np.ndarray - The input image with pixelated regions (same array, modified in-place).

Basic Usage

Python
import cv2import pixelflow as pffrom ultralytics import YOLO# Load image and detect facesimage = cv2.imread("crowd.jpg")model = YOLO("yolov8n-face.pt")results = model.predict(image)detections = pf.from_ultralytics(results)# Pixelate all detected facesimage = pf.annotators.pixelate(image, detections)cv2.imshow("Privacy Protected", image)cv2.waitKey(0)

How It Works

The pixelation effect is created through a two-step resize process:

Text only
Original Region          Downscaled            Upscaled (Pixelated)┌─────────────────┐      ┌─────┐              ┌─────────────────┐│                 │      │█░█░█│              │███░░░███░░░███░││  Detailed       │  →   │░█░█░│      →       │███░░░███░░░███░││  Image          │      │█░█░█│              │░░░███░░░███░░░░││                 │      └─────┘              │░░░███░░░███░░░░│└─────────────────┘     (tiny size)           │███░░░███░░░███░│                                              └─────────────────┘                                              (back to original size                                               with blocky pixels)
  1. Downscale: Region is shrunk using linear interpolation (averages colors)
  2. Upscale: Tiny image is enlarged back using nearest neighbor (creates blocks)

Pixel Size Control

The pixel_size parameter controls how large each block appears. Larger values create more obvious, blockier pixelation.

pixel_size Effect Use Case
3-5 Fine pixelation Subtle, details somewhat visible
8-12 Medium pixelation Standard privacy protection
15-20 Coarse pixelation Strong anonymization
25+ Heavy pixelation Extreme obscuring, few blocks visible
Python
# Subtle pixelation - some detail remainsimage = pf.annotators.pixelate(image, detections, pixel_size=5)# Standard pixelationimage = pf.annotators.pixelate(image, detections, pixel_size=12)# Heavy pixelation - just colored blocksimage = pf.annotators.pixelate(image, detections, pixel_size=25)
Output
pixel_size=5
Output
pixel_size=12 (medium)

Padding Control

The padding_percent parameter expands the pixelated region beyond the bounding box, ensuring complete coverage when detections are slightly tight.

Python
# No padding - exact bounding boximage = pf.annotators.pixelate(image, detections, padding_percent=0.0)# Default 5% paddingimage = pf.annotators.pixelate(image, detections, padding_percent=0.05)# Generous padding for complete coverageimage = pf.annotators.pixelate(image, detections, padding_percent=0.15)

Blur vs Pixelate

Both annotators provide privacy protection but with different visual styles:

Feature blur() pixelate()
Appearance Smooth, natural Blocky, artificial
Edges Soft gradients Sharp block boundaries
Intent Subtle, blends in Obvious redaction
Style Professional/news Retro/gaming aesthetic
Performance Slightly faster Very fast
Output
blur()
Output
pixelate()

Common Use Cases

Face Anonymization

Python
face_model = YOLO("yolov8n-face.pt")results = face_model.predict(image)faces = pf.from_ultralytics(results)# Strong pixelation with extra paddingimage = pf.annotators.pixelate(image, faces, pixel_size=15, padding_percent=0.1)

Selective Pixelation

Python
# Detect all objectsresults = model.predict(image)detections = pf.from_ultralytics(results)# Pixelate only people, show boxes on everything elsepeople = detections.filter_by_class_id([0])others = detections.filter_by_class_id([0], exclude=True)image = pf.annotators.pixelate(image, people)image = pf.annotators.box(image, others)image = pf.annotators.label(image, others)

With Labels

Python
# Pixelate faces but show redaction labelsimage = pf.annotators.pixelate(image, faces)image = pf.annotators.box(image, faces)image = pf.annotators.label(image, faces, "[REDACTED]")

Adaptive Sizing

When pixel_size=None, the block size automatically adapts to image resolution:

Image Resolution Auto pixel_size
640x480 ~5px
1280x720 ~8px
1920x1080 ~10px
3840x2160 (4K) ~20px

Performance

The pixelate() annotator is extremely fast due to OpenCV's optimized resize operations:

Notes

  • In-place modification: The input image is modified directly. Use image.copy() if you need the original preserved.
  • Minimum pixel_size: Values below 1 are automatically clamped to 1.
  • Small regions: Regions smaller than pixel_size are skipped to prevent artifacts.
  • Boundary handling: Bounding boxes are automatically clipped to image boundaries.
  • Padding limits: The padding_percent is clamped to range [0.0, 0.5].

See Also

  • blur() - Alternative privacy method using Gaussian blur
  • mask() - Overlay colored masks on detections
  • filter_by_class_id() - Filter detections before pixelating