Files
vtracer/crates/vtracer-bench/src/main.rs
T
Chris Tsang e9fece97b8
Rust / test (push) Has been cancelled
Rust / wasm-safety (core) (push) Has been cancelled
Rust / Node package (push) Has been cancelled
vtracer-bench: codec-free library, codecs behind a cli feature
- The library now speaks the image crate's buffer types only:
  fidelity(&RgbImage, &RgbImage, thresh) -> (FidelityReport, GrayImage).
  A tracer embedding the metric pulls no image codec at all.
- New `cli` feature (default on) brings png/jpeg/webp decoding and
  gates the vtracer-bench bin (required-features).
- dssim-core with default features off: drops the rayon thread pool.
- Scores are unchanged: the CLI prints the same value before and after.
2026-09-06 18:49:34 +01:00

67 lines
2.2 KiB
Rust

//! Blind fidelity benchmark for raster-to-vector tracers.
//!
//! vtracer-bench <original> <candidate> [--thresh N] [--mask out.png]
//!
//! Both arguments are rasters of identical dimensions — rendering a vector
//! reconstruction to pixels is the caller's responsibility. Prints the raw
//! metrics, their [0,1] subscores, the composite fidelity, and a
//! machine-readable csv line.
use vtracer_bench::{DEFAULT_THRESH, fidelity};
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() < 3 {
eprintln!("usage: vtracer-bench <original> <candidate> [--thresh N] [--mask out.png]");
std::process::exit(2);
}
let mut thresh = DEFAULT_THRESH;
let mut mask_out: Option<String> = None;
let mut i = 3;
while i < args.len() {
match args[i].as_str() {
"--thresh" => {
i += 1;
thresh = args[i].parse().expect("--thresh N");
}
"--mask" => {
i += 1;
mask_out = Some(args[i].clone());
}
a => {
eprintln!("unknown flag {a}");
std::process::exit(2);
}
}
i += 1;
}
let orig = image::open(&args[1]).expect("open original").to_rgb8();
let cand = image::open(&args[2]).expect("open candidate").to_rgb8();
assert_eq!(cand.dimensions(), orig.dimensions(), "candidate raster must match original dimensions");
let (r, mask) = fidelity(&orig, &cand, thresh);
if let Some(out) = mask_out {
mask.save(&out).expect("save mask");
}
println!(
"psnr {:>8.2} dB (rmse {:.2}) -> {:.4}",
r.psnr, r.rmse, r.s_psnr
);
println!(
"ssim {:>8.5} (dssim {:.5}) -> {:.4}",
r.s_ssim, r.dssim, r.s_ssim
);
println!(
"patch {:>8.1} px rms ({} bad px, {} clusters, largest {}) -> {:.4}",
r.patch_mass, r.bad_px, r.clusters, r.largest, r.s_patch
);
println!("fidelity {:.4}", r.fidelity);
println!(
"[csv] {:.4},{:.2},{:.5},{:.2},{:.1},{:.4},{:.4},{:.4}",
r.fidelity, r.psnr, r.dssim, r.rmse, r.patch_mass, r.s_psnr, r.s_ssim, r.s_patch
);
}