Skip to main content

ReconBuilder

Struct ReconBuilder 

Source
pub struct ReconBuilder { /* private fields */ }
Expand description

Plan recorder. Methods only record and do not run anything. Validate with ReconBuilder::build.

Implementations§

Source§

impl ReconBuilder

Source

pub fn plan(&self) -> &Plan

The plan recorded so far.

Source

pub fn input(self, src: impl AsRef<Path>) -> Self

Input folder: images <src>/images/<camera>/, GPS <src>/gps_ref.txt.

Source

pub fn images(self, dir: impl Into<PathBuf>) -> Self

Only specify the image folder (parent of the camera folders).

Source

pub fn cameras<S: Into<String>>(self, cams: impl IntoIterator<Item = S>) -> Self

List of camera folders (frame-bundle order).

Source

pub fn preset(self, name: &str) -> Self

Apply a preset (cameras, pairing strategy, stride). An unknown name is an error in build. aerial-formation: camF/camR/camL, formation pairing rule, stride 3.

Source

pub fn stride(self, n: usize) -> Self

File number interval.

Source

pub fn positions(self, n: usize) -> Self

Only the first N positions.

Source

pub fn pairing(self, p: Pairing) -> Self

Pairing strategy.

Source

pub fn zones(self, span: usize, overlap: usize) -> Self

Zone size and overlap (number of positions).

Source

pub fn gps(self, path: impl Into<PathBuf>) -> Self

GPS record file.

Source

pub fn no_gps(self) -> Self

No GPS file (to turn off alignment too, pass AlignFrame::None to ReconBuilder::align).

Source

pub fn align(self, frame: AlignFrame) -> Self

Alignment coordinate frame.

Source

pub fn fixed_enu_origin(self, on: bool) -> Self

Fix the session ENU origin to the first GPS line.

Source

pub fn features(self, f: Features) -> Self

Feature extraction settings.

Source

pub fn match_backend(self, name: &str) -> Self

Matching backend (cpu|cuda).

Source

pub fn gpu(self) -> Self

Set the SIFT, matching, sparse-stage, PatchMatch, undistortion and bundle adjustment backends all to cuda.

Source

pub fn incremental_triangulation(self, on: bool) -> Self

Triangulate only newly registered images.

Source

pub fn stable_display(self, on: bool) -> Self

Stable display (see SessionConfig::stable_display).

Source

pub fn settle(self, tol: f64, max_zone: usize) -> Self

Stable display settling: intrinsics change tolerance and the last zone that may still settle (see SessionConfig::settle_tol, SessionConfig::settle_max_zone).

Source

pub fn dense(self, d: Dense) -> Self

Densification plan (on).

Source

pub fn no_dense(self) -> Self

Densification off.

Source

pub fn sinks(self, s: Sinks) -> Self

Output hook plan.

Source

pub fn seed(self, seed: u64) -> Self

RANSAC seed.

Source

pub fn threads(self, n: usize) -> Self

Number of rayon threads (0 = number of cores).

Source

pub fn on<F>(self, kind: EventKind, f: F) -> Self
where F: FnMut(&Event) + Send + 'static,

A hook for a specific kind (Pipeline::on). Choosing EventKind::FrameDecoded turns frame decoding on.

Source

pub fn on_frame<F>(self, f: F) -> Self
where F: FnMut(&Arc<Frame>) + Send + 'static,

Frame hook (Pipeline::on_frame): receives each decoded input frame (RGB), one camera at a time, before the position is processed. Registering one turns frame decoding on.

Examples found in repository?
examples/frame_hook_plan.rs (lines 61-73)
53fn main() -> Result<(), String> {
54    let path = std::env::args().nth(1).ok_or("usage: frame_hook_plan <plan.toml>")?;
55    let plan = Plan::load(&path)?;
56    let seen = Arc::new(Mutex::new(Seen::default()));
57    let refined = Arc::new(Mutex::new(Vec::new()));
58    let t0 = Instant::now();
59    let (s, r) = (seen.clone(), refined.clone());
60    let recon = Recon::from_plan(plan)
61        .on_frame(move |f: &Arc<Frame>| {
62            let mut s = s.lock().unwrap();
63            let t = t0.elapsed().as_secs_f64();
64            s.first_s.get_or_insert(t);
65            s.last_s = t;
66            *s.per_camera.entry(f.camera.clone()).or_default() += 1;
67            *s.sizes.entry((f.width, f.height)).or_default() += 1;
68            s.bytes += f.rgb.len();
69            s.positions = s.positions.max(f.position + 1);
70            if f.rgb.len() != (f.width * f.height * 3) as usize || f.width == 0 {
71                s.bad += 1;
72            }
73        })
74        .on_zone_refined(move |z, cloud| r.lock().unwrap().push((z.zone, cloud.len())))
75        .build()
76        .map_err(|e| e.to_string())?;
77    let summary = recon.run()?;
78    let s = seen.lock().unwrap();
79    let total: usize = s.per_camera.values().sum();
80    println!(
81        "frame hook: {total} frames over {} positions, per camera {:?}, sizes {:?}, {:.1} MB RGB, bad {}",
82        s.positions,
83        s.per_camera,
84        s.sizes,
85        s.bytes as f64 / 1e6,
86        s.bad
87    );
88    println!(
89        "frame hook: first frame at {:.2}s, last at {:.2}s; run total {:.1}s",
90        s.first_s.unwrap_or(0.0),
91        s.last_s,
92        t0.elapsed().as_secs_f64()
93    );
94    println!("refined zones (zone, dense points): {:?}", refined.lock().unwrap());
95    println!("events {}, hook calls {}, hook panics {}", summary.events, summary.hook_calls, summary.hook_panics);
96    if total == 0 || s.bad > 0 || summary.hook_panics > 0 {
97        return Err("frame hook check failed".into());
98    }
99    Ok(())
100}
Source

pub fn on_any<F>(self, f: F) -> Self
where F: FnMut(&Event) + Send + 'static,

Hook for all events (Pipeline::on_any).

Source

pub fn on_zone_preview<F>(self, f: F) -> Self
where F: FnMut(ZoneRange, &Arc<PointCloud>) + Send + 'static,

Zone preview point-cloud hook (Pipeline::on_zone_preview).

Source

pub fn on_zone_refined<F>(self, f: F) -> Self
where F: FnMut(ZoneRange, &Arc<PointCloud>) + Send + 'static,

Zone refined point-cloud hook (Pipeline::on_zone_refined).

Examples found in repository?
examples/frame_hook_plan.rs (line 74)
53fn main() -> Result<(), String> {
54    let path = std::env::args().nth(1).ok_or("usage: frame_hook_plan <plan.toml>")?;
55    let plan = Plan::load(&path)?;
56    let seen = Arc::new(Mutex::new(Seen::default()));
57    let refined = Arc::new(Mutex::new(Vec::new()));
58    let t0 = Instant::now();
59    let (s, r) = (seen.clone(), refined.clone());
60    let recon = Recon::from_plan(plan)
61        .on_frame(move |f: &Arc<Frame>| {
62            let mut s = s.lock().unwrap();
63            let t = t0.elapsed().as_secs_f64();
64            s.first_s.get_or_insert(t);
65            s.last_s = t;
66            *s.per_camera.entry(f.camera.clone()).or_default() += 1;
67            *s.sizes.entry((f.width, f.height)).or_default() += 1;
68            s.bytes += f.rgb.len();
69            s.positions = s.positions.max(f.position + 1);
70            if f.rgb.len() != (f.width * f.height * 3) as usize || f.width == 0 {
71                s.bad += 1;
72            }
73        })
74        .on_zone_refined(move |z, cloud| r.lock().unwrap().push((z.zone, cloud.len())))
75        .build()
76        .map_err(|e| e.to_string())?;
77    let summary = recon.run()?;
78    let s = seen.lock().unwrap();
79    let total: usize = s.per_camera.values().sum();
80    println!(
81        "frame hook: {total} frames over {} positions, per camera {:?}, sizes {:?}, {:.1} MB RGB, bad {}",
82        s.positions,
83        s.per_camera,
84        s.sizes,
85        s.bytes as f64 / 1e6,
86        s.bad
87    );
88    println!(
89        "frame hook: first frame at {:.2}s, last at {:.2}s; run total {:.1}s",
90        s.first_s.unwrap_or(0.0),
91        s.last_s,
92        t0.elapsed().as_secs_f64()
93    );
94    println!("refined zones (zone, dense points): {:?}", refined.lock().unwrap());
95    println!("events {}, hook calls {}, hook panics {}", summary.events, summary.hook_calls, summary.hook_panics);
96    if total == 0 || s.bad > 0 || summary.hook_panics > 0 {
97        return Err("frame hook check failed".into());
98    }
99    Ok(())
100}
Source

pub fn on_snapshot<F>(self, f: F) -> Self
where F: FnMut(usize, &Arc<PointCloud>) + Send + 'static,

Snapshot hook (Pipeline::on_snapshot).

Source

pub fn on_position_done<F>(self, f: F) -> Self
where F: FnMut(usize, usize, usize) + Send + 'static,

Position-done hook (Pipeline::on_position_done).

Source

pub fn on_message<F>(self, f: F) -> Self
where F: FnMut(EventKind, &str) + Send + 'static,

Warning/error message hook (Pipeline::on_message).

Source

pub fn policy(self, kind: EventKind, p: QueuePolicy) -> Self

Per-kind queue policy (Pipeline::policy).

Source

pub fn build(self) -> Result<Recon, PlanError>

Validate the plan -> an executable Recon. It neither creates nor deletes files or folders (it only reads the input folder listing and the GPS file).

Checks: input and camera folders exist, number of selected positions, alignment and GPS file, backend names and device (when CUDA is requested), output folder writable, option value ranges. All problems are collected and returned at once as a PlanError.

Examples found in repository?
examples/frame_hook_plan.rs (line 75)
53fn main() -> Result<(), String> {
54    let path = std::env::args().nth(1).ok_or("usage: frame_hook_plan <plan.toml>")?;
55    let plan = Plan::load(&path)?;
56    let seen = Arc::new(Mutex::new(Seen::default()));
57    let refined = Arc::new(Mutex::new(Vec::new()));
58    let t0 = Instant::now();
59    let (s, r) = (seen.clone(), refined.clone());
60    let recon = Recon::from_plan(plan)
61        .on_frame(move |f: &Arc<Frame>| {
62            let mut s = s.lock().unwrap();
63            let t = t0.elapsed().as_secs_f64();
64            s.first_s.get_or_insert(t);
65            s.last_s = t;
66            *s.per_camera.entry(f.camera.clone()).or_default() += 1;
67            *s.sizes.entry((f.width, f.height)).or_default() += 1;
68            s.bytes += f.rgb.len();
69            s.positions = s.positions.max(f.position + 1);
70            if f.rgb.len() != (f.width * f.height * 3) as usize || f.width == 0 {
71                s.bad += 1;
72            }
73        })
74        .on_zone_refined(move |z, cloud| r.lock().unwrap().push((z.zone, cloud.len())))
75        .build()
76        .map_err(|e| e.to_string())?;
77    let summary = recon.run()?;
78    let s = seen.lock().unwrap();
79    let total: usize = s.per_camera.values().sum();
80    println!(
81        "frame hook: {total} frames over {} positions, per camera {:?}, sizes {:?}, {:.1} MB RGB, bad {}",
82        s.positions,
83        s.per_camera,
84        s.sizes,
85        s.bytes as f64 / 1e6,
86        s.bad
87    );
88    println!(
89        "frame hook: first frame at {:.2}s, last at {:.2}s; run total {:.1}s",
90        s.first_s.unwrap_or(0.0),
91        s.last_s,
92        t0.elapsed().as_secs_f64()
93    );
94    println!("refined zones (zone, dense points): {:?}", refined.lock().unwrap());
95    println!("events {}, hook calls {}, hook panics {}", summary.events, summary.hook_calls, summary.hook_panics);
96    if total == 0 || s.bad > 0 || summary.hook_panics > 0 {
97        return Err("frame hook check failed".into());
98    }
99    Ok(())
100}

Trait Implementations§

Source§

impl Debug for ReconBuilder

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> ByRef<T> for T

Source§

fn by_ref(&self) -> &T

Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> DistributionExt for T
where T: ?Sized,

Source§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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 more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<SS, SP> SupersetOf<SS> for SP
where SS: SubsetOf<SP>,

Source§

fn to_subset(&self) -> Option<SS>

The inverse inclusion map: attempts to construct self from the equivalent element of its superset. Read more
Source§

fn is_in_subset(&self) -> bool

Checks if self is actually part of its subset T (and can be converted to it).
Source§

fn to_subset_unchecked(&self) -> SS

Use with care! Same as self.to_subset but without any property checks. Always succeeds.
Source§

fn from_subset(element: &SS) -> SP

The inclusion map: converts self to the equivalent element of its superset.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V