From 168710624e8d334300b16c7dc6c5f883d56688bb Mon Sep 17 00:00:00 2001 From: Dmitry Zolotukhin Date: Wed, 17 May 2023 01:34:48 +0200 Subject: [PATCH] Disable interpolation for SFM. Updated README.md. Prepared for release. --- .github/workflows/cargo-build.yml | 2 +- README.md | 15 +++++---------- src/reconstruction.rs | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/.github/workflows/cargo-build.yml b/.github/workflows/cargo-build.yml index a402fd7b..dded5378 100644 --- a/.github/workflows/cargo-build.yml +++ b/.github/workflows/cargo-build.yml @@ -2,7 +2,7 @@ name: Cargo build on: push: - branches: [ "master", "multi-view-reconstruction" ] + branches: [ "master" ] pull_request: branches: [ "master" ] diff --git a/README.md b/README.md index 11291e22..b11a9b6e 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,5 @@ # Cybervision -# Experimental multi view branch - -**⚠️ Warning** This `multi-view-reconstruction` is an experimental branch, attempting to reconstruct 3D images from a set of photos. -Unfortunately, it requires either camera calibration, or using [advanced math for self-calibration](https://www.researchgate.net/publication/3659897_The_modulus_constraint_A_new_constraint_self-calibration) - solving a quartic equation system with up to 64 roots. -It's a bit too much and out of my scope of expertise. -Without calibration, each pair of images uses its own coordinate system and it's impossible to align images in a single 3D model. -It also doesn't help that sometimes noise or incorrectly detected features cause images to be incorrectly reconstructed, and adding that data to a combined mesh ruins the end result. - ![Build status](https://github.com/zlogic/cybervision/actions/workflows/cargo-build.yml/badge.svg) @@ -17,7 +9,7 @@ Cybervision is a 3D reconstruction software for Scanning Electron Microscope ima The tool needs two images of an object taken from slighly different angles. Cybervision can match those images and use the parallax effect to determine the object's 3D shape. -⚠️ Cybervision works best with high-contrast images with parallel (affine) projection. +**⚠️ Warning** Cybervision works best with high-contrast images with parallel (affine) projection. Regular photos with perspective projection can be reconstructed as well, but this is a secondary use case. More information is available in the [Wiki](https://github.com/zlogic/cybervision/wiki). @@ -62,10 +54,13 @@ Adding this flag can significantly reduce processing time, at the cost of produc * If the filename ends with `.png`, this will save a PNG depth map file. * If the filename ends with `.jpg`, this will save a JPEG depth map file. -⚠️ The optimal image size is 1024x1024 (or similar). +**⚠️ Warning** The optimal image size is 1024x1024 (or similar). Using larger images will result in increased processing times, increased memory usage, and run into GPU hardware limitations. Smaller images might not have enough details. +**⚠️ Warning** Structure-from-motion (attempting to reconstruct 3D images from a set of photos) works, but the results are often full of noise. +Unfortunately, it requires either camera calibration, which depends on complicated math - a bit too much for me and out of my scope of expertise. + ### GPU details Compiling a GPU-accelerated (Vulkan) version requires additional libraries and build tools. diff --git a/src/reconstruction.rs b/src/reconstruction.rs index 18b4b873..10a26307 100644 --- a/src/reconstruction.rs +++ b/src/reconstruction.rs @@ -18,6 +18,7 @@ use nalgebra::DMatrix; use nalgebra::Matrix3; use rayon::prelude::*; use std::error; +use std::fmt; use std::fmt::Write; use std::fs::File; use std::io::BufReader; @@ -198,6 +199,13 @@ pub fn reconstruct(args: &Cli) -> Result<(), Box> { triangulation, }; + if args.img_src.len() > 2 && interpolation_mode != output::InterpolationMode::None { + return Err(ReconstructionError::new( + "Interpolation should be none when reconstructing from more than 2 images", + ) + .into()); + } + for i in 0..args.img_src.len() - 1 { let img1_filename = &args.img_src[i]; let img2_filename = &args.img_src[i + 1]; @@ -563,3 +571,22 @@ impl output::ProgressListener for ProgressBar { self.set_position((pos * 10000.0) as u64); } } + +#[derive(Debug)] +struct ReconstructionError { + msg: &'static str, +} + +impl ReconstructionError { + fn new(msg: &'static str) -> ReconstructionError { + ReconstructionError { msg } + } +} + +impl std::error::Error for ReconstructionError {} + +impl fmt::Display for ReconstructionError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.msg) + } +}