pub trait CameraModel:
Send
+ Sync
+ Clone
+ Debug
+ 'static {
type IntrinsicJacobian: Clone + Debug + Default + Index<(usize, usize), Output = f64>;
type PointJacobian: Clone + Debug + Default + Mul<Matrix<f64, Const<3>, Const<6>, ArrayStorage<f64, 3, 6>>, Output = Matrix<f64, Const<2>, Const<6>, ArrayStorage<f64, 2, 6>>, Output = Matrix<f64, Const<2>, Const<3>, ArrayStorage<f64, 2, 3>>> + Mul<Matrix<f64, Const<3>, Const<3>, ArrayStorage<f64, 3, 3>>> + Index<(usize, usize), Output = f64>;
const INTRINSIC_DIM: usize;
// Required methods
fn project(
&self,
p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
) -> Result<Matrix<f64, Const<2>, Const<1>, ArrayStorage<f64, 2, 1>>, CameraModelError>;
fn unproject(
&self,
point_2d: &Matrix<f64, Const<2>, Const<1>, ArrayStorage<f64, 2, 1>>,
) -> Result<Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>, CameraModelError>;
fn jacobian_point(
&self,
p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
) -> Self::PointJacobian;
fn jacobian_intrinsics(
&self,
p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
) -> Self::IntrinsicJacobian;
fn validate_params(&self) -> Result<(), CameraModelError>;
fn get_pinhole_params(&self) -> PinholeParams;
fn get_distortion(&self) -> DistortionModel;
fn get_model_name(&self) -> &'static str;
// Provided methods
fn jacobian_pose(
&self,
p_world: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
pose: &SE3,
) -> (Self::PointJacobian, Matrix<f64, Const<3>, Const<6>, ArrayStorage<f64, 3, 6>>) { ... }
fn projection_deficit(
&self,
p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
) -> (f64, Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>) { ... }
fn project_batch(
&self,
points_cam: &Matrix<f64, Const<3>, Dyn, VecStorage<f64, Const<3>, Dyn>>,
) -> Matrix<f64, Const<2>, Dyn, VecStorage<f64, Const<2>, Dyn>> { ... }
}Expand description
Trait for camera projection models.
Defines the interface for camera models used in bundle adjustment and SfM.
§Type Parameters
INTRINSIC_DIM: Number of intrinsic parametersIntrinsicJacobian: Jacobian type for intrinsics (2 × INTRINSIC_DIM)PointJacobian: Jacobian type for 3D point (2 × 3)
Required Associated Constants§
Sourceconst INTRINSIC_DIM: usize
const INTRINSIC_DIM: usize
Number of intrinsic parameters (compile-time constant).
Required Associated Types§
Sourcetype IntrinsicJacobian: Clone + Debug + Default + Index<(usize, usize), Output = f64>
type IntrinsicJacobian: Clone + Debug + Default + Index<(usize, usize), Output = f64>
Jacobian type for intrinsics: 2 × INTRINSIC_DIM.
Sourcetype PointJacobian: Clone + Debug + Default + Mul<Matrix<f64, Const<3>, Const<6>, ArrayStorage<f64, 3, 6>>, Output = Matrix<f64, Const<2>, Const<6>, ArrayStorage<f64, 2, 6>>, Output = Matrix<f64, Const<2>, Const<3>, ArrayStorage<f64, 2, 3>>> + Mul<Matrix<f64, Const<3>, Const<3>, ArrayStorage<f64, 3, 3>>> + Index<(usize, usize), Output = f64>
type PointJacobian: Clone + Debug + Default + Mul<Matrix<f64, Const<3>, Const<6>, ArrayStorage<f64, 3, 6>>, Output = Matrix<f64, Const<2>, Const<6>, ArrayStorage<f64, 2, 6>>, Output = Matrix<f64, Const<2>, Const<3>, ArrayStorage<f64, 2, 3>>> + Mul<Matrix<f64, Const<3>, Const<3>, ArrayStorage<f64, 3, 3>>> + Index<(usize, usize), Output = f64>
Jacobian type for 3D point: 2 × 3.
Required Methods§
Sourcefn project(
&self,
p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
) -> Result<Matrix<f64, Const<2>, Const<1>, ArrayStorage<f64, 2, 1>>, CameraModelError>
fn project( &self, p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>, ) -> Result<Matrix<f64, Const<2>, Const<1>, ArrayStorage<f64, 2, 1>>, CameraModelError>
Projects a 3D point in camera coordinates to 2D image coordinates. See the cookbook introduction for the projection pipeline, and the per-model page for the formula.
§Errors
Returns PointBehindCamera, PointAtCameraCenter, DenominatorTooSmall,
or ProjectionOutOfBounds depending on the model.
Sourcefn unproject(
&self,
point_2d: &Matrix<f64, Const<2>, Const<1>, ArrayStorage<f64, 2, 1>>,
) -> Result<Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>, CameraModelError>
fn unproject( &self, point_2d: &Matrix<f64, Const<2>, Const<1>, ArrayStorage<f64, 2, 1>>, ) -> Result<Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>, CameraModelError>
Unprojects a 2D image point to a normalized 3D ray in camera frame. Some models use Newton-Raphson for undistortion. See the per-model cookbook page for the algorithm.
§Errors
Returns PointOutsideImage or NumericalError (e.g. when the
iterative solver fails to converge).
Sourcefn jacobian_point(
&self,
p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
) -> Self::PointJacobian
fn jacobian_point( &self, p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>, ) -> Self::PointJacobian
∂(u,v)/∂(x,y,z) — 2×3 Jacobian of projection w.r.t. the 3D point. Used for structure optimisation, triangulation, and bundle adjustment. See the per-model cookbook page for the formula.
Sourcefn jacobian_intrinsics(
&self,
p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
) -> Self::IntrinsicJacobian
fn jacobian_intrinsics( &self, p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>, ) -> Self::IntrinsicJacobian
∂(u,v)/∂(params) — 2×N Jacobian of projection w.r.t. intrinsic
parameters, where N = INTRINSIC_DIM. The parameter order is
model-specific; see the per-model cookbook page.
Sourcefn validate_params(&self) -> Result<(), CameraModelError>
fn validate_params(&self) -> Result<(), CameraModelError>
Validates camera intrinsic and distortion parameters. The exact rules are model-specific; see the per-model cookbook page under “Validation Rules”.
Sourcefn get_pinhole_params(&self) -> PinholeParams
fn get_pinhole_params(&self) -> PinholeParams
Returns the linear intrinsics (f_x, f_y, c_x, c_y).
Sourcefn get_distortion(&self) -> DistortionModel
fn get_distortion(&self) -> DistortionModel
Returns the distortion model and its parameters.
Sourcefn get_model_name(&self) -> &'static str
fn get_model_name(&self) -> &'static str
Returns the camera model identifier ("pinhole", "rad_tan", …).
Provided Methods§
Sourcefn jacobian_pose(
&self,
p_world: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
pose: &SE3,
) -> (Self::PointJacobian, Matrix<f64, Const<3>, Const<6>, ArrayStorage<f64, 3, 6>>)
fn jacobian_pose( &self, p_world: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>, pose: &SE3, ) -> (Self::PointJacobian, Matrix<f64, Const<3>, Const<6>, ArrayStorage<f64, 3, 6>>)
∂(u,v)/∂(δξ) — 2×6 Jacobian of projection w.r.t. the camera pose.
The pose is a world-to-camera transform T_wc with right
perturbation T' = T · Exp(δξ). Returns a pair
(J_uv_pcam, J_pcam_pose) where the caller multiplies to get
the full 2×6 Jacobian. See the
cookbook introduction
for the SE(3) conventions.
Sourcefn projection_deficit(
&self,
p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>,
) -> (f64, Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>)
fn projection_deficit( &self, p_cam: &Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>, ) -> (f64, Matrix<f64, Const<3>, Const<1>, ArrayStorage<f64, 3, 1>>)
Signed depth deficit of a camera-frame point outside the projection
domain of project, plus its gradient.
Returns (deficit, ∂deficit/∂p_cam). A positive deficit means
p_cam is outside the domain project accepts, and its magnitude is
the distance to that domain measured along the model’s optical axis
(in metres), so a caller can scale it into a penalty that grows as the
point moves deeper into the invalid region. The second element is the
gradient of the deficit with respect to the camera-frame point, which
is what lets that penalty have a real derivative — a barrier an
optimizer can be pushed back across, rather than one it can only be
charged for.
The default implementation is the z-forward deficit
deficit = -z, gradient -e_z, which is correct for every model
whose domain is z > GEOMETRIC_PRECISION. Models with a different
domain must override it:
- z-backward models (the BAL convention, valid for
z < -MIN_DEPTH) must return a deficit that grows with+z; keeping the default there would produce a gradient that drives points further behind the camera. - models with a non-planar domain — double sphere’s
z > -w₂·‖p_cam‖cone, whose boundary moves with the point — must return the distance to that boundary rather than to a fixed plane.
A model that cannot express its failure smoothly should return a non-positive deficit: callers clamp it, which degrades to a constant barrier with no gradient — never free, and never wrong-signed.
§Status: not currently charged by the solver
ProjectionFactor does not apply this deficit yet: the attempt to
route every non-cheirality camera error through a barrier built from it
was measured and reverted, because at BAL t257/dubrovnik-135 it charged
more than the entire problem was worth at the initial guess (3.29e12
and 2.20e10 against 6.86e4 / 1.89e5 goldens) and the solve stopped
making progress. The per-model definitions below stay: they are the
correct domain geometry, unit-tested here, ready for a formulation that
survives those benchmarks. See
benchmarking_results/experiment_007_projection_domain_barrier_REJECTED.md.
§Examples
use apex_camera_models::{CameraModel, PinholeCamera};
use nalgebra::Vector3;
let camera = PinholeCamera::from([500.0, 500.0, 320.0, 240.0]);
// Two metres behind the camera ⇒ a two-metre deficit …
let (deficit, grad) =
camera.projection_deficit(&Vector3::new(0.3, -0.1, -2.0));
assert!((deficit - 2.0).abs() < 1e-12);
// … whose gradient points along −z, i.e. toward validity.
assert_eq!(grad, Vector3::new(0.0, 0.0, -1.0));
// In front of the camera the deficit is non-positive: the model is
// inside its domain, so any projection failure there is numerical
// and has no smooth direction out of.
let (deficit, _) = camera.projection_deficit(&Vector3::new(0.3, -0.1, 2.0));
assert!(deficit <= 0.0);Sourcefn project_batch(
&self,
points_cam: &Matrix<f64, Const<3>, Dyn, VecStorage<f64, Const<3>, Dyn>>,
) -> Matrix<f64, Const<2>, Dyn, VecStorage<f64, Const<2>, Dyn>>
fn project_batch( &self, points_cam: &Matrix<f64, Const<3>, Dyn, VecStorage<f64, Const<3>, Dyn>>, ) -> Matrix<f64, Const<2>, Dyn, VecStorage<f64, Const<2>, Dyn>>
Projects N 3D points in one call. Invalid projections are replaced
by the sentinel (1e6, 1e6). Models may override with a vectorised
implementation.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".