Skip to content

Commit

Permalink
Added option to limit number of points.
Browse files Browse the repository at this point in the history
This helps to have a sane mesh size without losing data.
  • Loading branch information
zlogic committed May 25, 2024
1 parent a6f75fa commit dcd7e46
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 5 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Download a release distribution from [releases](/zlogic/cybervision/releases).
Run cybervision:

```shell
cybervision [--scale=<scale>] [--focal-length=<focal-length>] [--mode=<cpu|gpu>] [--interpolation=<none|delaunay>] [--projection=<parallel|perspective>] [--mesh=<plain|vertex-colors|texture-coordinates>] [--no-bundle-adjustment] <img1> <img2> [<imgn>] <output>
cybervision [--scale=<scale>] [--focal-length=<focal-length>] [--mode=<cpu|gpu>] [--interpolation=<none|delaunay>] [--projection=<parallel|perspective>] [--mesh=<plain|vertex-colors|texture-coordinates>] [--no-bundle-adjustment] [--max-points=<max_points>] <img1> <img2> [<imgn>] <output>
```

`--scale=<scale>` is an optional argument to specify a depth scale, for example `--scale=-10.0`.
Expand All @@ -50,6 +50,10 @@ If not specified, EXIF metadata will be used.
`--no-bundle-adjustment` disables bundle adjustment when reconstructing images with perspective projection.
Adding this flag can significantly reduce processing time, at the cost of producing incorrect data.

`--max-points=<max_points>` sets a limit on the number of points in the resulting mesh
Adding this flag will randomly select up to max\_points points if the mesh contains too many points.
This helps with producing reasonably sized meshes (dense reconstruction produces a lot of data!).

`<img1>` and `<img2>` are input filenames for image 1 and 2; supported formats are `jpg`, `tif` and `png`.
Although experimental, it's also possible to specify more than one image when using perspective projection.

Expand Down
8 changes: 8 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub struct Args {
mode: HardwareMode,
interpolation: InterpolationMode,
no_bundle_adjustment: bool,
max_points: Option<usize>,
projection: ProjectionMode,
mesh: Mesh,
img_src: Vec<String>,
Expand All @@ -58,6 +59,7 @@ Options:\
\n --mode=<MODE> Hardware mode [default: gpu] [possible values: gpu, gpu-low-power, cpu]\
\n --interpolation=<INTERPOLATION> Interpolation mode [default: delaunay] [possible values: delaunay, none]\
\n --no-bundle-adjustment Skip bundle adjustment [if unspecified, bundle adjustment will be applied]\
\n --max-points=<MAX_POINTS> Limit number of points in the resulting mesh\
\n --projection=<PROJECTION> Projection mode [default: perspective] [possible values: parallel, perspective]\
\n --mesh=<MESH> Mesh options [default: vertex-colors] [possible values: plain, vertex-colors, texture-coordinates]\
\n --help Print help";
Expand All @@ -69,6 +71,7 @@ impl Args {
mode: HardwareMode::Gpu,
interpolation: InterpolationMode::Delaunay,
no_bundle_adjustment: false,
max_points: None,
projection: ProjectionMode::Perspective,
mesh: Mesh::VertexColors,
img_src: vec![],
Expand Down Expand Up @@ -132,6 +135,11 @@ impl Args {
exit(2);
}
};
} else if name == "--max-points" {
match value.parse() {
Ok(max_points) => args.max_points = Some(max_points),
Err(err) => fail_with_error(name, value, &err),
};
} else if name == "--projection" {
match value {
"perspective" => args.projection = ProjectionMode::Perspective,
Expand Down
5 changes: 3 additions & 2 deletions src/reconstruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ pub fn reconstruct(args: &Args) -> Result<(), ReconstructionError> {
}
};

let surface = reconstruction_task.complete_triangulation(linked_images)?;
let surface = reconstruction_task.complete_triangulation(linked_images, args.max_points)?;
let img_filenames = reconstruction_task.img_filenames.to_owned();
reconstruction_task.output_surface(
surface,
Expand Down Expand Up @@ -732,12 +732,13 @@ impl ImageReconstruction {
fn complete_triangulation(
&mut self,
linked_images: Vec<usize>,
max_points: Option<usize>,
) -> Result<triangulation::Surface, triangulation::TriangulationError> {
let start_time = SystemTime::now();

let pb = new_progress_bar(false);

let surface = self.triangulation.triangulate_all(Some(&pb))?;
let surface = self.triangulation.triangulate_all(max_points, Some(&pb))?;
self.triangulation.complete();

pb.finish_and_clear();
Expand Down
15 changes: 13 additions & 2 deletions src/triangulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use nalgebra::{
Vector2, Vector3, Vector4,
};

use rand::{rngs::SmallRng, Rng, SeedableRng};
use rand::{rngs::SmallRng, seq::SliceRandom, Rng, SeedableRng};
use rayon::prelude::*;

const BUNDLE_ADJUSTMENT_MAX_ITERATIONS: usize = 100;
Expand Down Expand Up @@ -225,12 +225,13 @@ impl Triangulation {

pub fn triangulate_all<PL: ProgressListener>(
&mut self,
max_points: Option<usize>,
progress_listener: Option<&PL>,
) -> Result<Surface, TriangulationError> {
if let Some(affine) = &self.affine {
affine.triangulate_all()
} else if let Some(perspective) = &mut self.perspective {
perspective.triangulate_all(progress_listener)
perspective.triangulate_all(max_points, progress_listener)
} else {
Err("Triangulation not initialized".into())
}
Expand Down Expand Up @@ -705,6 +706,7 @@ impl PerspectiveTriangulation {

fn triangulate_all<PL: ProgressListener>(
&mut self,
max_points: Option<usize>,
progress_listener: Option<&PL>,
) -> Result<Surface, TriangulationError> {
self.triangulate_tracks();
Expand All @@ -722,6 +724,15 @@ impl PerspectiveTriangulation {
self.bundle_adjustment(cameras.as_slice(), progress_listener)?;
}

if let Some(max_points) = max_points {
let rng = &mut SmallRng::from_rng(rand::thread_rng()).unwrap();
if self.tracks.len() > max_points {
self.tracks.shuffle(rng);
self.tracks.truncate(max_points);
self.tracks.shrink_to_fit();
}
};

let surface_projections = cameras
.iter()
.map(|camera| camera.projection())
Expand Down

0 comments on commit dcd7e46

Please sign in to comment.