Second pixel-domain post-filter — a scale-gated unsharp mask on the luma plane: n = y_in / 255 blur = clamp( conv3x3(n, [[5,5,5],[5,24,5],[5,5,5]]/64), 0, 1 ) // valid; border keeps n factor = mag[k] where region in [thr[k], thr[k+1]) (k=0,1) or region >= thr[2]; else 1 out = clamp( blur + (n - blur)*factor, 0, 1 ) * 255 The 3x3 conv is "valid" (no padding) — interior pixels blur, the 1-pixel border passes through — matching the reference's pad-and-mask trick. `region` gates the sharpening strength: the scale grid (sigma, 16x16) nearest-upsampled to pixel resolution. Validated against the reference fixture (input luma + 16x16 scale + thr/mag → sharpened luma): max|Δ| = 1.5e-5 (f32-vs-f64), SNR 153 dB. Plus unit tests for the flat-plane invariance, the border pass-through, and the factor>1 sharpening gate. Co-Authored-By: Claude Opus 4.8 <[email protected]>
43 lines
2 KiB
Rust
43 lines
2 KiB
Rust
//! Calibration for [`wai::jpegai_pipeline::lef_filter`] — the LEF adaptive-sharpness
|
||
//! post-filter. Runs on the reference fixture (input luma, the 16×16 scale grid, the
|
||
//! three thresholds/magnitudes) and compares against the reference `y_want`. Float
|
||
//! arithmetic ⇒ machine-precision match expected.
|
||
//!
|
||
//! env: WAI_JPEGAI_LEF_FIXTURE = lef_fixture.json
|
||
//! { y_in:[f64], y_want:[f64], sigma:[f64], sh, sw, thr:[f64;3], mag:[f64;3], h, w }
|
||
#![cfg(feature = "neural_int")]
|
||
|
||
use wai::jpegai_pipeline::lef_filter;
|
||
|
||
#[test]
|
||
fn lef_filter_matches_reference() {
|
||
let path = match std::env::var("WAI_JPEGAI_LEF_FIXTURE") {
|
||
Ok(p) if std::path::Path::new(&p).exists() => p,
|
||
_ => { eprintln!("skip: set WAI_JPEGAI_LEF_FIXTURE to lef_fixture.json"); return; }
|
||
};
|
||
let v: serde_json::Value = serde_json::from_slice(&std::fs::read(&path).unwrap()).unwrap();
|
||
let f32v = |k: &str| v[k].as_array().unwrap().iter().map(|x| x.as_f64().unwrap() as f32).collect::<Vec<f32>>();
|
||
let y_in = f32v("y_in");
|
||
let y_want = f32v("y_want");
|
||
let sigma = f32v("sigma");
|
||
let thr_v = f32v("thr");
|
||
let mag_v = f32v("mag");
|
||
let g = |k: &str| v[k].as_u64().unwrap() as usize;
|
||
let (sh, sw, h, w) = (g("sh"), g("sw"), g("h"), g("w"));
|
||
|
||
let got = lef_filter(&y_in, &sigma, sh, sw, [thr_v[0], thr_v[1], thr_v[2]], [mag_v[0], mag_v[1], mag_v[2]], h, w);
|
||
assert_eq!(got.len(), y_want.len(), "output size mismatch");
|
||
|
||
let mut maxd = 0f32;
|
||
let mut mse = 0f64;
|
||
for i in 0..got.len() {
|
||
let d = (got[i] - y_want[i]).abs();
|
||
maxd = maxd.max(d);
|
||
mse += (d as f64) * (d as f64);
|
||
}
|
||
mse /= got.len() as f64;
|
||
let sig: f64 = y_want.iter().map(|&x| (x as f64) * (x as f64)).sum::<f64>() / got.len() as f64;
|
||
let snr = if mse > 0.0 { 10.0 * (sig / mse).log10() } else { f64::INFINITY };
|
||
eprintln!("lef_filter vs reference: max|Δ| = {maxd:.6} SNR = {snr:.2} dB");
|
||
assert!(maxd < 1e-2, "LEF filter diverged from the reference (max|Δ| = {maxd})");
|
||
}
|