Skip to main content

CameraModel

Trait CameraModel 

Source
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 parameters
  • IntrinsicJacobian: Jacobian type for intrinsics (2 × INTRINSIC_DIM)
  • PointJacobian: Jacobian type for 3D point (2 × 3)

Required Associated Constants§

Source

const INTRINSIC_DIM: usize

Number of intrinsic parameters (compile-time constant).

Required Associated Types§

Source

type IntrinsicJacobian: Clone + Debug + Default + Index<(usize, usize), Output = f64>

Jacobian type for intrinsics: 2 × INTRINSIC_DIM.

Source

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§

Source

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.

Source

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).

Source

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.

Source

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.

Source

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”.

Source

fn get_pinhole_params(&self) -> PinholeParams

Returns the linear intrinsics (f_x, f_y, c_x, c_y).

Source

fn get_distortion(&self) -> DistortionModel

Returns the distortion model and its parameters.

Source

fn get_model_name(&self) -> &'static str

Returns the camera model identifier ("pinhole", "rad_tan", …).

Provided Methods§

Source

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.

Source

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);
Source

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".

Implementors§

Source§

impl CameraModel for BALPinholeCameraStrict

Source§

impl CameraModel for DoubleSphereCamera

Source§

impl CameraModel for EucmCamera

Source§

impl CameraModel for FThetaCamera

Source§

impl CameraModel for FovCamera

Source§

impl CameraModel for KannalaBrandtCamera

Source§

impl CameraModel for PinholeCamera

Source§

impl CameraModel for RadTanCamera

Source§

impl CameraModel for UcmCamera