Enrich binary thresholding: tunable fixed + Bradley–Roth adaptive

BinaryFrontend gains a Threshold enum: Fixed(u8) (now tunable, was
hardcoded to 128) and Adaptive { window, t } — Bradley–Roth adaptive
thresholding computed via visioncortex's SummedAreaTable, O(pixels)
regardless of window size, for images with uneven lighting. Both use a
shared (r+g+b)/3 intensity so they agree on "dark"; the grayscale
checker_bw golden is unaffected.

Exposed through Config and all bindings: CLI (--threshold, --adaptive,
--adaptive-window, --adaptive-t), Python (constructor kwargs + getters/
setters), and the Node package (binaryThreshold, adaptive, adaptiveWindow,
adaptiveT). Adds tests covering fixed tunability and adaptive recovering
locally-dark marks under a brightness gradient that a global cutoff can't.
This commit is contained in:
Chris Tsang
2026-07-25 00:26:05 +01:00
parent 50042f477d
commit a350e2532a
10 changed files with 369 additions and 13 deletions
+21
View File
@@ -29,6 +29,14 @@ struct Options {
palette: Option<Vec<String>>,
max_colors: Option<usize>,
optimize: Option<u8>,
/// Binary-mode fixed threshold (0..=255).
binary_threshold: Option<u8>,
/// Binary mode: use Bradley–Roth adaptive thresholding.
adaptive: Option<bool>,
/// Adaptive window side length in px (0 = auto).
adaptive_window: Option<u32>,
/// Adaptive sensitivity: percent below the local mean (default 15).
adaptive_t: Option<f64>,
/// One of "bw" | "poster" | "photo"; applied before the other fields.
preset: Option<String>,
}
@@ -105,6 +113,19 @@ fn config_from(options: JsValue) -> Result<Config, JsValue> {
if let Some(v) = opts.optimize {
config.optimize = v;
}
if let Some(v) = opts.binary_threshold {
config.binary_threshold = v;
}
// Any adaptive tuning field (or `adaptive: true`) switches on Bradley–Roth.
if opts.adaptive == Some(true) || opts.adaptive_window.is_some() || opts.adaptive_t.is_some() {
config.binary_adaptive = true;
}
if let Some(v) = opts.adaptive_window {
config.binary_adaptive_window = v;
}
if let Some(v) = opts.adaptive_t {
config.binary_adaptive_t = v;
}
Ok(config)
}