pub struct SessionConfig {Show 13 fields
pub image_root: PathBuf,
pub gps: Vec<GpsRecord>,
pub span: usize,
pub overlap: usize,
pub total_positions: Option<usize>,
pub incremental_triangulation: bool,
pub fixed_enu_origin: bool,
pub seed: Option<u64>,
pub extraction: ExtractionOptions,
pub sift: Arc<dyn SiftEngine>,
pub matcher: Arc<dyn MatcherBackend>,
pub dense: Option<DenseConfig>,
pub history: usize,
}Expand description
세션 설정.
Fields§
§image_root: PathBuf입력 영상 폴더(영상 이름의 기준).
gps: Vec<GpsRecord>GPS 기록(정렬 순서 = 이 순서).
span: usize구역 크기·겹침(위치 단위).
overlap: usize구역 겹침(위치 수).
total_positions: Option<usize>알려진 전체 위치 수. 있으면 마지막 구역들이 마지막 위치에서 닫히고, 없으면 finish 에서 닫힌다.
incremental_triangulation: bool새로 등록된 영상만 삼각측량.
fixed_enu_origin: bool첫 GPS 기록으로 ENU 원점 고정(기본: 정렬마다 첫 공통 기록).
seed: Option<u64>두 뷰 기하·GPS 정렬 RANSAC 시드.
extraction: ExtractionOptions특징 추출 옵션.
sift: Arc<dyn SiftEngine>SIFT 백엔드.
matcher: Arc<dyn MatcherBackend>기술자 매칭 백엔드.
dense: Option<DenseConfig>조밀화 설정(None = 조밀화 생략, 점군 이벤트는 dense: false).
history: usizeCommand::ResetFrom 용으로 보관할 위치별 되감기 지점 수(0 = 되감기 불가, 메모리 절약).
Implementations§
Source§impl SessionConfig
impl SessionConfig
Sourcepub fn new(image_root: impl Into<PathBuf>) -> Self
pub fn new(image_root: impl Into<PathBuf>) -> Self
기본값: 구역 12 / 겹침 2, SIFT 최대 8192 특징·입력 3200, CPU SIFT·매칭, 조밀화 없음, 되감기 8.
Examples found in repository?
examples/hooks.rs (line 33)
21fn main() -> Result<(), String> {
22 let out = std::env::args().nth(1).map(PathBuf::from).unwrap_or_else(|| std::env::temp_dir().join("cumulus3d_hooks"));
23 let src = out.with_extension("src");
24 if !src.join("gps_ref.txt").exists() {
25 common::make_dataset(&src);
26 }
27 if out.exists() {
28 std::fs::remove_dir_all(&out).map_err(|e| e.to_string())?;
29 }
30 let layout = Layout::discover(&src, 1)?;
31 let npos = layout.frames.len();
32
33 let mut cfg = SessionConfig::new(src.join("images"));
34 cfg.gps = read_gps_file(src.join("gps_ref.txt")).map_err(|e| e.to_string())?;
35 (cfg.span, cfg.overlap, cfg.total_positions, cfg.seed) = (4, 1, Some(npos), Some(7));
36 if cumulus3d_cuda::is_available() {
37 let mut d = DenseConfig::new(make_pm_backend("cuda"), parse_profile("fast")?);
38 d.undistort.max_image_size = 160;
39 cfg.dense = Some(d);
40 }
41
42 // 훅: 사건 문구 출력, 구역 점군 점 수, 경고·오류. 그리고 기본 출력 훅(파일).
43 let pipeline = Pipeline::new(Session::new(cfg))
44 .on_any(|e: &Event| {
45 if let Some(t) = e.timeline_text() {
46 println!("[event v{}] {t}", e.meta().version);
47 }
48 })
49 .on(EventKind::ZonePreview, |e: &Event| {
50 if let Event::ZonePreview { range, cloud, model, .. } = e {
51 println!(" 초벌 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
52 }
53 })
54 .on(EventKind::ZoneRefined, |e: &Event| {
55 if let Event::ZoneRefined { range, cloud, model, .. } = e {
56 println!(" 정밀 {}: 조밀 점 {} / 희소 점 {}", range.zone, cloud.len(), model.num_points3d());
57 }
58 })
59 .on_message(|k, m| eprintln!(" {k:?}: {m}"));
60 let mut pipeline = sinks::attach(pipeline, &out, &SinkOptions::default()).map_err(|e| e.to_string())?;
61
62 for p in 0..npos {
63 pipeline.push(Input::Frames(FrameSet::new(CAMS.iter().map(|c| (*c, layout.name(c, p))))));
64 }
65 let (_, summary) = pipeline.finish();
66 println!("이벤트 {} 개, 훅 호출 {} 번, 훅 패닉 {}", summary.events, summary.hook_calls, summary.hook_panics);
67
68 for f in ["timeline.txt", "run.log", "snapshots/manifest.json", "snapshots/timeline.txt", "DONE"] {
69 let p = out.join(f);
70 println!("{} {}", if p.exists() { "있음" } else { "없음" }, p.display());
71 }
72 Ok(())
73}Trait Implementations§
Auto Trait Implementations§
impl !RefUnwindSafe for SessionConfig
impl !UnwindSafe for SessionConfig
impl Freeze for SessionConfig
impl Send for SessionConfig
impl Sync for SessionConfig
impl Unpin for SessionConfig
impl UnsafeUnpin for SessionConfig
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
Mutably borrows from an owned value. Read more
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> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T, U> Imply<T> for U
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> ⓘ
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 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> ⓘ
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 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>
The inverse inclusion map: attempts to construct
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
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
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
fn from_subset(element: &SS) -> SP
The inclusion map: converts
self to the equivalent element of its superset.