pub struct StereoCameraSystem {
pub left: CameraIntrinsics,
pub right: CameraIntrinsics,
pub baseline: f64,
pub r: [[f64; 3]; 3],
pub t: [f64; 3],
}Expand description
A stereo camera rig consisting of left and right pinhole cameras.
The stereo geometry is described by a relative rotation R and translation
T such that a point P_l in the left-camera frame maps to the right
frame as P_r = R * P_l + T.
For a typical horizontal stereo setup T ≈ [-baseline, 0, 0].
Fields§
§left: CameraIntrinsicsLeft camera intrinsics.
right: CameraIntrinsicsRight camera intrinsics.
baseline: f64Baseline distance between optical centres (metres).
r: [[f64; 3]; 3]Rotation from left to right camera frame.
t: [f64; 3]Translation from left to right camera frame (metres).
Implementations§
Source§impl StereoCameraSystem
impl StereoCameraSystem
Sourcepub fn new(
left: CameraIntrinsics,
right: CameraIntrinsics,
r: [[f64; 3]; 3],
t: [f64; 3],
) -> Self
pub fn new( left: CameraIntrinsics, right: CameraIntrinsics, r: [[f64; 3]; 3], t: [f64; 3], ) -> Self
Create a new stereo system. The baseline is derived from ‖T‖.
Sourcepub fn disparity_to_depth(&self, disparity: f64) -> Option<f64>
pub fn disparity_to_depth(&self, disparity: f64) -> Option<f64>
Convert disparity to metric depth using depth = baseline * fx / disparity.
Returns None when disparity ≤ 0.
let cam = CameraIntrinsics::ideal(800.0, 800.0, 320.0, 240.0);
let stereo = StereoCameraSystem::new(
cam.clone(), cam,
[[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]],
[-0.1, 0.0, 0.0],
);
let depth = stereo.disparity_to_depth(80.0).unwrap();
assert!((depth - 1.0).abs() < 1e-9);Sourcepub fn triangulate(
&self,
left_px: [f64; 2],
right_px: [f64; 2],
) -> Option<[f64; 3]>
pub fn triangulate( &self, left_px: [f64; 2], right_px: [f64; 2], ) -> Option<[f64; 3]>
Triangulate a 3-D point from stereo pixel correspondences using the Direct Linear Transform (mid-point method on the two rays).
Both pixels are assumed to be in a rectified coordinate frame so that epipolar lines are horizontal.
Returns None when the rays are nearly parallel.
let cam = CameraIntrinsics::ideal(800.0, 800.0, 320.0, 240.0);
let stereo = StereoCameraSystem::new(
cam.clone(), cam,
[[1.0,0.0,0.0],[0.0,1.0,0.0],[0.0,0.0,1.0]],
[-0.1, 0.0, 0.0],
);
// A point at (0, 0, 1 m): left pixel = (320, 240), right pixel = (240, 240)
let pt = stereo.triangulate([320.0, 240.0], [240.0, 240.0]).unwrap();
assert!((pt[2] - 1.0).abs() < 0.05);Sourcepub fn compute_disparity_map(
&self,
left_img: &[Vec<f64>],
right_img: &[Vec<f64>],
max_disparity: usize,
block_size: usize,
) -> Vec<Vec<f64>>
pub fn compute_disparity_map( &self, left_img: &[Vec<f64>], right_img: &[Vec<f64>], max_disparity: usize, block_size: usize, ) -> Vec<Vec<f64>>
Compute a disparity map from a rectified stereo pair using block matching.
Both images must have the same dimensions. Returns a disparity map of
identical dimensions; pixels where no match was found carry value 0.0.
§Arguments
left_img– Row-major grayscale image[row][col].right_img– Row-major grayscale image[row][col].max_disparity– Maximum disparity to search (pixels).block_size– Half-window radius (full window = 2r+1 × 2r+1).
Trait Implementations§
Source§impl Clone for StereoCameraSystem
impl Clone for StereoCameraSystem
Source§fn clone(&self) -> StereoCameraSystem
fn clone(&self) -> StereoCameraSystem
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for StereoCameraSystem
impl RefUnwindSafe for StereoCameraSystem
impl Send for StereoCameraSystem
impl Sync for StereoCameraSystem
impl Unpin for StereoCameraSystem
impl UnsafeUnpin for StereoCameraSystem
impl UnwindSafe for StereoCameraSystem
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.