vision_calibration_core/models/
camera.rs1use nalgebra::{Point2, Point3, RealField, Vector3};
2use serde::{Deserialize, Serialize};
3
4use super::{DistortionModel, IntrinsicsModel, ProjectionModel, SensorModel};
5
6#[derive(Clone, Copy, Debug)]
8pub struct Ray<S: RealField + Copy> {
9 pub point: Vector3<S>,
11}
12
13#[derive(Clone, Debug, Serialize, Deserialize)]
15pub struct Camera<S, P, D, Sm, K>
16where
17 S: RealField + Copy,
18 P: ProjectionModel<S>,
19 D: DistortionModel<S>,
20 Sm: SensorModel<S>,
21 K: IntrinsicsModel<S>,
22{
23 pub proj: P,
25 pub dist: D,
27 pub sensor: Sm,
29 pub k: K,
31 _phantom: core::marker::PhantomData<S>,
32}
33
34impl<S, P, D, Sm, K> Camera<S, P, D, Sm, K>
35where
36 S: RealField + Copy,
37 P: ProjectionModel<S>,
38 D: DistortionModel<S>,
39 Sm: SensorModel<S>,
40 K: IntrinsicsModel<S>,
41{
42 pub fn new(proj: P, dist: D, sensor: Sm, k: K) -> Self {
44 Self {
45 proj,
46 dist,
47 sensor,
48 k,
49 _phantom: core::marker::PhantomData,
50 }
51 }
52
53 pub fn project_point_c(&self, p_c: &Vector3<S>) -> Option<Point2<S>> {
57 if p_c.z <= S::zero() {
58 return None;
59 }
60 let dir = *p_c;
61 let n_u = self.proj.project_dir(&dir)?;
62 let n_d = self.dist.distort(&n_u);
63 let s = self.sensor.normalized_to_sensor(&n_d);
64 Some(self.k.sensor_to_pixel(&s))
65 }
66
67 pub fn project_point(&self, p_c: &Point3<S>) -> Option<Point2<S>> {
71 self.project_point_c(&p_c.coords)
72 }
73
74 pub fn backproject_pixel(&self, px: &Point2<S>) -> Ray<S> {
76 let s = self.k.pixel_to_sensor(px);
77 let n_d = self.sensor.sensor_to_normalized(&s);
78 let n_u = self.dist.undistort(&n_d);
79 let dir = self.proj.unproject_dir(&n_u);
80 debug_assert!(dir.z != S::zero());
81 let point = dir / dir.z;
82 Ray { point }
83 }
84}