Skip to content

quality

Quality measurement module.

This module handles measuring image quality using various metrics including SSIMULACRA2, PSNR, SSIM, and Butteraugli.

Quality measurement tools often have limited format support, so encoded images are converted to PNG before measurement.

Important: Quality measurements compare encoded images against their source_image (the preprocessed version used for encoding), NOT the original_image. This ensures images are compared at the same resolution, which is required by all quality measurement tools.


to_png(image_path: Path, output_path: Path) → None

Convert an image to PNG format for measurement tools.

Many quality measurement tools have limited format support (e.g., ssimulacra2 and butteraugli can’t read AVIF or JXL directly). This function converts any image format to PNG.

For most formats, Pillow is used. For formats Pillow doesn’t support (like JPEG XL), format-specific decoders are used.

Args:

  • image_path: Path to the source image (any format)
  • output_path: Path where PNG will be written

Raises:

  • OSError: If image cannot be read or written

extract_fragment(
image_path: Path,
fragment: dict[str, int],
output_path: Path
) → Path

Extract a rectangular fragment from an image.

The fragment is specified in the image’s own coordinate space. The output is always saved as PNG.

Args:

  • image_path: Path to the source image (any format supported
  • by : func:to_png / Pillow).
  • fragment: Region to extract as
  • ```{“x”`: int, “y”: int, “width”: int, “height”: int}“.
  • output_path: Destination PNG path.

Returns: output_path.


get_measurement_tool_version(tool: str) → str | None

Get version string for a measurement tool.

Args:

  • tool: Name of measurement tool (ssimulacra2, butteraugli, ffmpeg)

Returns: Version string or None if unable to determine


read_pfm(pfm_path: Path) → ndarray

Read a PFM (Portable Float Map) file into a 2-D float64 numpy array.

Handles both grayscale (Pf) and colour (PF) PFM files. For colour PFM the maximum across the three channels is returned so that the highest distortion value at each pixel is preserved.

PFM stores rows bottom-to-top; this function flips the result to the conventional top-to-bottom orientation used everywhere else.

Args:

  • pfm_path: Path to the .pfm file.

Returns: 2-D array of shape (H, W) with distortion values.

Raises:

  • ValueError: If the file is not a valid PFM.

find_worst_region_in_array(arr: ndarray, crop_size: int) → WorstRegion

Find the worst region in a 2-D distortion value array.

Core sliding-window computation that works with any float array, whether it comes from a raw PFM file, an averaged map, or a variance map.

Args:

  • arr: 2-D float array of shape (H, W) with per-pixel distortion values. Higher values mean more distortion.
  • crop_size: Side length of the square sliding window in pixels.

Returns:

  • :class: WorstRegion for the window position with the highest sum.

Container for quality measurement results.

__init__(
ssimulacra2: float | None = None,
psnr: float | None = None,
ssim: float | None = None,
butteraugli: float | None = None,
error_message: str | None = None
) → None

Information about the most degraded region in an image.

Attributes:

  • x: Left coordinate of the crop region.
  • y: Top coordinate of the crop region.
  • width: Width of the crop region in pixels.
  • height: Height of the crop region in pixels.
  • avg_distortion: Average distortion score in this region.

__init__(x: int, y: int, width: int, height: int, avg_distortion: float) → None

Handles quality measurements for encoded images.


measure_all(
original: Path,
compressed: Path,
distmap_path: Path | None = None
) → QualityMetrics

Measure all available quality metrics.

When distmap_path is provided, the Butteraugli measurement additionally produces a raw PFM distortion map at that path. This avoids a separate butteraugli_main invocation later.

Args:

  • original: Path to the original image.
  • compressed: Path to the compressed image.
  • distmap_path: If given, write a Butteraugli distortion-map
  • PFM file here (see : meth:measure_butteraugli_with_distmap).

Returns: QualityMetrics object with all measured values.


measure_butteraugli(original: Path, compressed: Path) → float | None

Measure Butteraugli distance between two images.

Both images are converted to PNG if needed, as butteraugli has limited format support.

Args:

  • original: Path to the original image
  • compressed: Path to the compressed image

Returns: Butteraugli distance (lower is better, <1.0 = excellent)


measure_butteraugli_with_distmap(
original: Path,
compressed: Path,
distmap_path: Path
) → float | None

Measure Butteraugli distance and produce a raw distortion map.

Calls butteraugli_main with --rawdistmap to write a PFM file containing per-pixel float distortion values, and parses the aggregate (3-norm) distance score from stdout.

This replaces separate calls to :meth:measure_butteraugli and the comparison module’s generate_distortion_map, producing both outputs in a single invocation.

Args:

  • original: Path to the original reference image.
  • compressed: Path to the compressed/encoded image.
  • distmap_path: Path where the raw PFM distortion map will be written. Parent directories are created automatically.

Returns: Butteraugli aggregate distance (lower is better, <1.0 = excellent), or None if the measurement failed.


measure_psnr(original: Path, compressed: Path) → float | None

Measure PSNR between two images using FFmpeg.

FFmpeg has good format support, but we convert to PNG for consistency.

Args:

  • original: Path to the original image
  • compressed: Path to the compressed image

Returns: PSNR value in dB (higher is better)


measure_ssim(original: Path, compressed: Path) → float | None

Measure SSIM between two images using FFmpeg.

FFmpeg has good format support, but we convert to PNG for consistency.

Args:

  • original: Path to the original image
  • compressed: Path to the compressed image

Returns: SSIM value (0-1, higher is better)


measure_ssimulacra2(original: Path, compressed: Path) → float | None

Measure SSIMULACRA2 score between two images.

Both images are converted to PNG if needed, as ssimulacra2 has limited format support.

Args:

  • original: Path to the original image
  • compressed: Path to the compressed image

Returns: SSIMULACRA2 score (higher is better, 100 = lossless)


Quality measurement record for a single encoding.

__init__(
source_image: str,
original_image: str,
encoded_path: str,
format: str,
quality: int,
file_size: int,
width: int,
height: int,
source_file_size: int,
ssimulacra2: float | None,
psnr: float | None,
ssim: float | None,
butteraugli: float | None,
encoding_time: float | None = None,
chroma_subsampling: str | None = None,
speed: int | None = None,
effort: int | None = None,
method: int | None = None,
resolution: int | None = None,
crop: int | None = None,
analysis_fragment: dict[str, int] | None = None,
crop_region: dict[str, int] | None = None,
extra_args: dict[str, str | int | bool] | None = None,
measurement_error: str | None = None
) → None

Container for quality measurement results.

__init__(
study_id: str,
study_name: str,
dataset: dict[str, Any],
measurements: list[QualityRecord],
timestamp: str,
encoding_timestamp: str | None = None,
tool_versions: dict[str, str] | None = None
) → None

save(path: Path) → None

Save quality results to a JSON file.

Args:

  • path: Path where the JSON file will be written