//! Full feature → SfM → MVS → export pipeline, using the flat high-level API. //! //! This is the example from the high-level `colmap` crate, running verbatim //! against this crate. The numerical core is the built-in synthetic-scene demo //! (see `colmap::highlevel`), so it runs end to end and writes real output files //! even though the geometry is illustrative rather than recovered from pixels. //! //! ```text //! cargo run --example full_pipeline -- /path/to/images //! ``` use colmap::*; use std::path::{Path, PathBuf}; fn reconstruct_from_images(image_dir: &Path) -> Result<()> { // 1. Load images (headers only). let images = load_images_from_directory(image_dir)?; // 2. Feature extraction and matching. let feature_config = PipelineConfig { detector_type: DetectorType::Sift, max_features: 8000, ..Default::default() }; let pipeline = FeaturePipeline::new(feature_config); let extraction_result = pipeline.extract_and_match_all(&images)?; println!("Extracted features for {} images", extraction_result.features.len()); println!("Found {} match pairs", extraction_result.matches.len()); // 3. Sparse SfM reconstruction. let sfm_config = SfmConfig { min_track_length: 2, max_reprojection_error: 4.0, ..Default::default() }; let mut sfm_reconstructor = IncrementalSfm::new(sfm_config); sfm_reconstructor.set_features(extraction_result.features); sfm_reconstructor.set_matches(extraction_result.matches); let sparse_reconstruction = sfm_reconstructor.reconstruct()?; println!("Sparse reconstruction:"); println!(" - registered images: {}", sparse_reconstruction.registered_images()); println!(" - 3D points: {}", sparse_reconstruction.points.len()); println!( " - mean reprojection error: {:.2}", sparse_reconstruction.mean_reprojection_error() ); // 4. Dense MVS reconstruction. let mvs_config = MvsConfig { min_num_views: 3, max_image_size: 1600, depth_range: (0.1, 100.0), ..Default::default() }; let mvs_reconstructor = MvsReconstructor::new(mvs_config); let views = prepare_views_from_reconstruction(&sparse_reconstruction)?; let dense_reconstruction = mvs_reconstructor.reconstruct(&views)?; println!("Dense reconstruction:"); println!(" - point cloud size: {}", dense_reconstruction.point_cloud.points.len()); println!(" - mesh triangles: {}", dense_reconstruction.mesh.triangles.len()); // 5. Save the results. save_reconstruction(&sparse_reconstruction, "sparse_reconstruction")?; save_point_cloud(&dense_reconstruction.point_cloud, "dense_point_cloud.ply")?; save_mesh(&dense_reconstruction.mesh, "mesh.obj")?; println!("Wrote sparse_reconstruction/, dense_point_cloud.ply, mesh.obj"); Ok(()) } fn main() { let image_dir: PathBuf = std::env::args() .nth(1) .map(PathBuf::from) .unwrap_or_else(|| PathBuf::from(concat!(env!("CARGO_MANIFEST_DIR"), "/../images"))); println!("Reconstructing from {}", image_dir.display()); if let Err(err) = reconstruct_from_images(&image_dir) { eprintln!("error: {err}"); std::process::exit(1); } }