Expand description
MILO: a learned perceptual image quality metric, run on the CPU.
MILO (Çoğalan, Bemana, Myszkowski, Seidel and Groth, ACM TOG 2025) is a full-reference metric that models visual masking: an error hidden in texture counts for less than the same error on a flat surface. Where SSIM is a formula, MILO is a small convolutional network, 44,930 parameters, whose trained weights ship inside this crate. Given a reference and a distorted image it predicts a per-pixel visibility mask, weights the absolute error by it, and pools that into one number.
This is a port of the authors’ PyTorch implementation, held to its outputs
by tests/parity.rs. Same pyramid, same network, same pooling; only the
execution differs: a line-buffer pipeline so memory stays flat whatever
the image size, lane-generic SIMD kernels picked at compile time, and row
bands spread over threads with results that don’t depend on the thread
count.
use blazediff_milo::{milo, MiloOptions, Rgba8};
let outcome = milo(
Rgba8::new(&rgba1, width, height),
Rgba8::new(&rgba2, width, height),
&MiloOptions::default(),
)?;
println!("raw error {:.6}, MOS {:.3}", outcome.raw_error, outcome.mos);Two numbers come out. raw_error is the metric proper: the masked mean
absolute error, exactly zero for identical images and growing with visible
damage (the fixtures in this repo land between 0.0002 and 0.01). mos maps
it onto KADID-10k’s five-point mean opinion score through a learned
calibration; note the calibration tops out around 4.35 rather than 5 for
identical input, so threshold on raw_error, not mos.
Structs§
- Milo
Options - Knobs for a comparison.
- Milo
Outcome - A score and the maps it was pooled from.
- Rgba8
- A borrowed RGBA8 image, 4 bytes per pixel, row-major. Alpha is ignored, as the reference converts to RGB.
Enums§
- Milo
Error - Why MILO could not produce a score.
Constants§
- MIN_
SIDE - The smallest side the reference implementation accepts: three halvings must leave at least two pixels for the seed mask.
Functions§
- milo
- Compare
distortedagainstreference. - render_
map - Paint
map, one value per pixel of awidthxheightimage, over an RGBA8outputbuffer as an opaque grayscale image, bright where the perceived error is high. Values are clamped to0..=1, the range the reference’s own colormap render assumes.