sophus_sensor/projections/
perspective.rs1use core::borrow::Borrow;
2
3use sophus_autodiff::{
4 linalg::{
5 IsMatrix,
6 IsScalar,
7 IsVector,
8 },
9 prelude::IsSingleScalar,
10};
11
12use crate::traits::IsProjection;
13
14#[derive(Debug, Clone, Copy)]
18pub struct PerspectiveProjectionImpl<
19 S: IsScalar<BATCH, DM, DN>,
20 const BATCH: usize,
21 const DM: usize,
22 const DN: usize,
23> {
24 phantom: core::marker::PhantomData<S>,
25}
26
27impl<S: IsScalar<BATCH, DM, DN>, const BATCH: usize, const DM: usize, const DN: usize>
28 IsProjection<S, BATCH, DM, DN> for PerspectiveProjectionImpl<S, BATCH, DM, DN>
29{
30 fn proj<P>(point_in_camera: P) -> S::Vector<2>
31 where
32 P: Borrow<S::Vector<3>>,
33 {
34 let point_in_camera = point_in_camera.borrow();
35 S::Vector::<2>::from_array([
36 point_in_camera.elem(0) / point_in_camera.elem(2),
37 point_in_camera.elem(1) / point_in_camera.elem(2),
38 ])
39 }
40
41 fn unproj<P>(point_in_camera: P, extension: S) -> S::Vector<3>
42 where
43 P: Borrow<S::Vector<2>>,
44 {
45 let point_in_camera = point_in_camera.borrow();
46
47 S::Vector::<3>::from_array([
48 point_in_camera.elem(0) * extension,
49 point_in_camera.elem(1) * extension,
50 extension,
51 ])
52 }
53
54 fn dx_proj_x<P>(point_in_camera: P) -> S::Matrix<2, 3>
55 where
56 P: Borrow<S::Vector<3>>,
57 {
58 let point_in_camera = point_in_camera.borrow();
59
60 S::Matrix::<2, 3>::from_array2([
61 [
62 S::ones() / point_in_camera.elem(2),
63 S::zeros(),
64 -point_in_camera.elem(0) / (point_in_camera.elem(2) * point_in_camera.elem(2)),
65 ],
66 [
67 S::zeros(),
68 S::ones() / point_in_camera.elem(2),
69 -point_in_camera.elem(1) / (point_in_camera.elem(2) * point_in_camera.elem(2)),
70 ],
71 ])
72 }
73}
74
75pub fn perspect_proj<
77 S: IsSingleScalar<DM, DN> + 'static + Send + Sync,
78 const DM: usize,
79 const DN: usize,
80>(
81 point_in_camera: &S::Vector<3>,
82) -> S::Vector<2> {
83 PerspectiveProjectionImpl::<S, 1, DM, DN>::proj(point_in_camera)
84}