Skip to main content

cam_geom/
intrinsic_test_utils.rs

1//! Utilities for testing `cam_geom` implementations.
2use super::*;
3use nalgebra::{
4    base::{dimension::Dyn, VecStorage},
5    convert,
6};
7
8pub(crate) fn generate_uv_raw<R: RealField>(
9    width: usize,
10    height: usize,
11    step: usize,
12    border: usize,
13) -> Pixels<R, Dyn, VecStorage<R, Dyn, U2>> {
14    let mut uv_raws: Vec<[R; 2]> = Vec::new();
15    for row in num_iter::range_step(border, height - border, step) {
16        for col in num_iter::range_step(border, width - border, step) {
17            uv_raws.push([convert(col as f64), convert(row as f64)]);
18        }
19    }
20
21    let mut data = nalgebra::OMatrix::<R, Dyn, U2>::from_element(uv_raws.len(), convert(0.0));
22    for i in 0..uv_raws.len() {
23        for j in 0..2 {
24            data[(i, j)] = uv_raws[i][j].clone();
25        }
26    }
27    Pixels { data }
28}
29
30/// Test roundtrip projection from pixels to camera rays for an intrinsic camera model.
31///
32/// Generate pixel coordinates, project them to rays, convert to points on the
33/// rays, convert the points back to pixels, and then compare with the original
34/// pixel coordinates.
35pub fn roundtrip_intrinsics<R, CAM>(
36    cam: &CAM,
37    width: usize,
38    height: usize,
39    step: usize,
40    border: usize,
41    eps: R,
42) where
43    R: RealField,
44    CAM: IntrinsicParameters<R>,
45    CAM::BundleType: Bundle<R>,
46{
47    let pixels = generate_uv_raw(width, height, step, border);
48
49    let camcoords = cam.pixel_to_camera(&pixels);
50    let camera_coords_points = camcoords.point_on_ray();
51
52    // project back to pixel coordinates
53    let pixel_actual = cam.camera_to_pixel(&camera_coords_points);
54    approx::assert_abs_diff_eq!(pixels.data, pixel_actual.data, epsilon = convert(eps));
55}