use nalgebra::{Matrix3, Point2, Vector3};
use projective_grid::{
detect_grid, DetectionParams, DetectionRequest, Evidence, LatticeKind, PointFeature,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let h = Matrix3::new(
1.0, 0.18, 0.0, 0.0, 1.0, 0.0, 0.0011, 0.0007, 1.0,
);
let project = |gx: f32, gy: f32| -> Point2<f32> {
let v = h * Vector3::new(gx, gy, 1.0);
Point2::new(v.x / v.z, v.y / v.z)
};
let (rows, cols, pitch, origin) = (8, 8, 28.0_f32, 50.0_f32);
let mut features: Vec<PointFeature> = Vec::new();
let mut truth: Vec<(i32, i32)> = Vec::new();
for j in 0..rows {
for i in 0..cols {
let p = project(i as f32 * pitch + origin, j as f32 * pitch + origin);
features.push(PointFeature::new(features.len(), p));
truth.push((i, j));
}
}
let request = DetectionRequest::new(
LatticeKind::Square,
Evidence::Positions(&features),
None, DetectionParams::default(),
);
let solution = detect_grid(request)?;
println!(
"input dots: {} labelled: {} fit max residual: {:.4} px",
features.len(),
solution.grid.entries.len(),
solution
.fit
.as_ref()
.map(|f| f.residuals.max_px)
.unwrap_or(f32::NAN),
);
println!();
println!("detected (i, j) <- feature (true (i, j))");
let mut entries = solution.grid.entries.clone();
entries.sort_by_key(|e| (e.coord.v, e.coord.u));
for e in &entries {
let (ti, tj) = truth[e.source_index];
println!(
" ({:>2}, {:>2}) <- #{:<3} (true ({:>2}, {:>2}))",
e.coord.u, e.coord.v, e.source_index, ti, tj
);
}
Ok(())
}