Commit: e0b7b06
Parent: b5b5a56

Extend diagnostic to print denormalized pixel range from real code path

Mårten Åsberg committed on 2026-08-03 at 19:57
The raw ALIKED output range came back within [-1,1] as assumed, and
hand-computing the denormalization on those numbers gave sane in-bounds
pixel values -- contradicting the wildly-out-of-bounds coordinates seen
in the matched-pairs dump. Print the actual denormalized range computed
by the real formula over all keypoints (not a hand-derived estimate for
one point) to settle whether the bug is in this arithmetic or elsewhere
downstream. Also fixes an incidental `idx` shadowing (loop index vs. the
top-k sort scratch vector) introduced by an earlier diagnostic edit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
src/feature_extractor.rs +37 -22
diff --git a/src/feature_extractor.rs b/src/feature_extractor.rs
index 8850730..7d9e6ea 100644
@@ -134,23 +134,6 @@ pub fn run(cfg: FeatureExtractorConfig) -> Result<()> {
let (keypoints, descriptors_flat, scores) = run_aliked(&mut session, &pre.tensor)?;
let n = keypoints.len();
if idx == 0 && n > 0 {
// Diagnostic: the denormalization formula below assumes ALIKED's raw output is
// normalized to [-1, 1] over the padded square canvas. Print the actual raw
// range so that assumption can be checked directly against real model output.
let (mut x_min, mut x_max) = (f32::INFINITY, f32::NEG_INFINITY);
let (mut y_min, mut y_max) = (f32::INFINITY, f32::NEG_INFINITY);
for &[x, y] in &keypoints {
x_min = x_min.min(x);
x_max = x_max.max(x);
y_min = y_min.min(y);
y_max = y_max.max(y);
}
eprintln!(
"[diag] {rel_name}: raw ALIKED output range -- x: [{x_min:.4}, {x_max:.4}], y: [{y_min:.4}, {y_max:.4}] (n={n}); image size: {}x{}",
pre.orig_width, pre.orig_height
);
}
let desc_dim = if n == 0 {
128
} else if descriptors_flat.len() % n == 0 {
@@ -167,11 +150,11 @@ pub fn run(cfg: FeatureExtractorConfig) -> Result<()> {
// The ONNX model already caps output count near its export-time top-k; this only
// trims further if more keypoints than requested were returned.
let keep: Vec<usize> = if n > cfg.top_k {
let mut idx: Vec<usize> = (0..n).collect();
idx.sort_unstable_by(|&a, &b| scores[b].partial_cmp(&scores[a]).unwrap());
idx.truncate(cfg.top_k);
idx.sort_unstable();
idx
let mut top: Vec<usize> = (0..n).collect();
top.sort_unstable_by(|&a, &b| scores[b].partial_cmp(&scores[a]).unwrap());
top.truncate(cfg.top_k);
top.sort_unstable();
top
} else {
(0..n).collect()
};
@@ -189,6 +172,38 @@ pub fn run(cfg: FeatureExtractorConfig) -> Result<()> {
desc_rows.extend_from_slice(&descriptors_flat[i * desc_dim..(i + 1) * desc_dim]);
}
if idx == 0 && !kpt_rows.is_empty() {
// Diagnostic: print both the raw ALIKED output range and the actual denormalized
// pixel-space range this code computes from it, using the real formula/data
// (not a hand-derived estimate), to check both the [-1,1] assumption and the
// arithmetic against the actual image dimensions.
let (mut rx_min, mut rx_max) = (f32::INFINITY, f32::NEG_INFINITY);
let (mut ry_min, mut ry_max) = (f32::INFINITY, f32::NEG_INFINITY);
for &i in &keep {
let [x, y] = keypoints[i];
rx_min = rx_min.min(x);
rx_max = rx_max.max(x);
ry_min = ry_min.min(y);
ry_max = ry_max.max(y);
}
let (mut px_min, mut px_max) = (f32::INFINITY, f32::NEG_INFINITY);
let (mut py_min, mut py_max) = (f32::INFINITY, f32::NEG_INFINITY);
for &[x, y, ..] in &kpt_rows {
px_min = px_min.min(x);
px_max = px_max.max(x);
py_min = py_min.min(y);
py_max = py_max.max(y);
}
eprintln!(
"[diag] {rel_name}: image size {}x{}, max_dim={max_dim}",
pre.orig_width, pre.orig_height
);
eprintln!("[diag] raw ALIKED range: x=[{rx_min:.4}, {rx_max:.4}] y=[{ry_min:.4}, {ry_max:.4}]");
eprintln!(
"[diag] denormalized pixel range written to DB: x=[{px_min:.1}, {px_max:.1}] y=[{py_min:.1}, {py_max:.1}]"
);
}
database::write_keypoints(&conn, image_id, &kpt_rows)?;
database::write_descriptors(&conn, image_id, keep.len(), desc_dim, &desc_rows)?;