Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/gabyx/approxmvbb

Fast algorithms to compute an approximation of the minimal volume oriented bounding box of a point cloud in 3D.
https://github.com/gabyx/approxmvbb

bounding-boxes kd-tree oobb outlier-removal point-cloud volume

Last synced: about 13 hours ago
JSON representation

Fast algorithms to compute an approximation of the minimal volume oriented bounding box of a point cloud in 3D.

Awesome Lists containing this project

README

        

# ApproxMVBB

![C++](https://img.shields.io/badge/c%2B%2B-11/14-green.svg)
![Deps](https://img.shields.io/badge/dependencies-eigen3,meta,[pugixml,python3]-blue.svg)
![System](https://img.shields.io/badge/system-linux,osx,{windows}-lightgrey.svg)

**Status**

| Build | UnitTests |
| ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| [![Build Status](https://travis-ci.org/gabyx/ApproxMVBB.svg?branch=master)](https://travis-ci.org/gabyx/ApproxMVBB) | [![Build Status](https://travis-ci.org/gabyx/ApproxMVBB.svg?branch=unitTests)](https://travis-ci.org/gabyx/ApproxMVBB) |

[Homepage](http://gabyx.github.io/ApproxMVBB/)

---

## Fast algorithms to compute an approximation of the minimal volume oriented bounding box of a point cloud in 3D.

Computing the minimal volume oriented bounding box for a given point cloud in 3D is a hard problem in computer science.
Exact algorithms are known and of cubic order in the number of points in 3D. A faster exact algorithm is currently not know. However, for lots of applications an approximation of the minimum volume oriented bounding box is acceptable and already accurate enough. This project was developed for research in [Granular Rigidbody Dynamics](http://gabyx.github.io/GRSFramework/).
This small standard compliant C++11 library can either be built into a shared object library
or directly be included in an existing C++ project.

I am not especially proud of the underlying code as it was written years ago, nevertheless consider PR for refactoring and clean ups are very welcome!

This library includes code for :

- computing an approximation of an oriented minimal volume box (multithreading support: OpenMP),
- computing the convex hull of a point cloud in 2d,
- computing the minimal area rectangle of a 2d point cloud,
- 2d projections of point clouds,
- fast building a kD-Tree (n-dimensional, templated) with sophisticated splitting techniques which optimizes a
quality criteria during the splitting process,
- computing the k-nearest neighbors to a given point (kNN search) via kd-Tree.
- fast statistical outlier filtering of point clouds via (nearest neighbor search, kD-Tree).




---

## Installation & Dependencies

To build the library, the tests and the example you need the build tool [cmake](http://www.cmake.org).
This library has these light-weight required dependencies:

- [Eigen](http://eigen.tuxfamily.org) at least version 3.
- With homebrew or linuxbrew: `brew install eigen3`
- [meta](https://github.com/ericniebler/meta)
- Install optional: Gets downloaded and used during build.

and theses optional dependecies:

- [pugixml](https://github.com/zeux/pugixml)
- With homebrew or linuxbrew: `brew install pugixml`
- install with `#define PUGIXML_HAS_LONG_LONG` enabled in `pugiconfig.hpp`.
- only needed if cmake variable `ApproxMVBB_XML_SUPPORT=ON` (default=`OFF`).
- [python3](https://www.python.org/downloads/) only needed for visualization purposes.

Download these and install it on your system.

Download the latest ApproxMVBB code:

```bash
git clone https://github.com/gabyx/ApproxMVBB.git ApproxMVBB
```

Make a build directory and navigate to it:

```bash
mkdir Build
cd Build
```

Invoke cmake in the Build directory:

```bash
cmake ../ApproxMVBB
```

The cmake script tries to find [Eigen](http://eigen.tuxfamily.org),[meta](https://github.com/ericniebler/meta) and [pugixml](https://github.com/zeux/pugixml)
If you installed these in a system wide folder (e.g `/usr/local/`) this should succeed without any problems.
In the `CMakeCache.txt` file (or over the console by `-D=ON`) you can specify what you want to build, the following options are availabe:

- `ApproxMVBB_BUILD_LIBRARY`,
- `ApproxMVBB_BUILD_TESTS`
- `ApproxMVBB_BUILD_EXAMPLE`
- `ApproxMVBB_BUILD_BENCHMARKS`
- etc. See the marked red options after configuring in cmake-gui.

To install the library and the header files at a specific location `/usr/local/` run cmake with:

```bash
cmake -DCMAKE_INSTALL_PREFIX="/usr/local/" ../ApproxMVBB
```

Finally, build and install the project:

```bash
make all
make install
```

By default the multithreading support is enabled if OpenMP is found! (see [Multithreading Support](#multithreading-support))
To build in parallel use the `-jN` flag in the `make` command, where `N`denotes the number of parallel threads to use, or use the Ninja Generator which already uses maximum threads your system offers.

**CMake FindScripts**
The installation installs also scripts `approxmvbb-config.cmake` and `approxmvbb-config-version.cmake` into the `lib/cmake` folder. To include the library in another project the only thing you need to add in your cmake script is

```cmake
find_package(ApproxMVBB [version] [COMPONENTS [SUPPORT_KDTREE] [SUPPORT_XML] ] [Required] )
```

which defines the following targets if ApproxMVBB has been found successfully:

```cmake
ApproxMVBB::Core # Main target to link with!
ApproxMVBB::KdTreeSupport # Optional target for KdTree support to link with (only available if installed with this supported!)
ApproxMVBB::XMLSupport # Optional target for XML support to link with (only available if installed with this supported!)
```

The components `SUPPORT_KDTREE` additionally loads the dependency [meta](https://github.com/ericniebler/meta) for the `KdTree.hpp` header and `SUPPORT_XML` loads [pugixml](https://github.com/zeux/pugixml) for the `KdTreeXml.hpp` header.

If you installed the library into non-system generic location you can set the cmake variable `$ApproxMVBB_DIR` before invoking the `find_library` command:

```cmake
set(ApproxMVBB_DIR "path/to/installation/lib/cmake")
find_package(ApproxMVBB [version] [Required] )
```

See the example `example/libraryUsage` which should be configured as a separate build, and the example `example/kdTreeFiltering` for more information on how to
set up the dependencies!

---

## Supported Platforms

The code has been tested on Linux and OS X with compilers `clang` and `gcc`.
It should work for Windows as well, but has not been tested properly. Under Visual Studio 15 it seems to build.

---

## Example Usage: Approximation MVBB

Please see the `example/approxMVBB/main.cpp` in the source directory.
Given a point cloud with `n=10000` points sampled in the unit cube in 3D
we compute an approximation of the minimum volume bounding volume by the following calls:

```C++
#include
#include "ApproxMVBB/ComputeApproxMVBB.hpp"

int main(int argc, char** argv)
{
ApproxMVBB::Matrix3Dyn points(3,10000);
points.setRandom();
ApproxMVBB::OOBB oobb = ApproxMVBB::approximateMVBB(points,0.001,500,5,0,5);
oobb.expandToMinExtentRelative(0.1);
return 0;
}
```

The returned object oriented bounding box `oobb` contains the lower `oobb.m_minPoint` and upper point `oobb.m_maxPoint` expressed in the coordinate frame K of the bounding box. The bounding box also stores the rotation matrix from the world frame to the object frame K as a quaternion `oobb.m_q_KI` . The rotation matrix `R_KI` from frame I to frame K can be obtained by `oobb.m_q_KI.matrix()` (see `Eigen::Quaternion`). This rotation matrix `R_KI` corresponds to a coordinate transformation A_IK which transforms coordinates from frame K to coordinates in frame I. Thereforce, to get the lower point expressed in the coordinate frame I this yields:

```C++
ApproxMVBB::Vector3 p = oobb.m_q_KI * oobb.m_minPoint // A_IK * oobb.m_minPoint
```

**Degenerate OOBB:**
The returned bounding box might have a degenerated extent in some axis directions depending on the input points (e.g. 3 points defines a plane which is the minimal oriented bounding box with zero volume). The function `oobb.expandToMinExtentRelative(0.1);` is a post processing function to enlarge the bounding box by a certain percentage of the largest extent (if existing, otherwise a default value is used).

**Points Outside of the final OOBB:**
Because the algorithm works internally with a sample of the point cloud, the resulting OOBB might not contain all points of the original point cloud! To compensate for this an additional loop is required:

```C++
ApproxMVBB::Matrix33 A_KI = oobb.m_q_KI.matrix().transpose();
auto size = points.cols();
for( unsigned int i=0; i

**Function Parameters & How It Works**
To come

---

## Building and Visualizing the Tests

Building and installing the basic tests is done by:

```bash
cd ApproxMVBB
git submodule init
git submodule update
cd ../Build
make build_and_test
```

**Note that if the tests fail, submit a new issue and report which test failed.
The results can still be visualized and should be correct. **

**Note:**
To run the test in high-performance mode (needs lots of ram), which tests also points clouds of
140 million points and some polygonal statue `lucy.txt` successfully you need
to set the cmake variable `ApproxMVBB_TESTS_HIGH_PERFORMANCE` to `ON`
and additionally initialize the submodule `additional` and unzip the files:

```bash
cd ApproxMVBB
git submodule init
git submodule update
cd additional/tests/files; cat Lucy* | tar xz
```

and rebuild the tests. (this will copy the additional files next to the executable)

Executing the test application `cd tests; ./ApproxMVBBTests` will then run the following tests:

1. Testing the ConvexHull2D for several point clouds in 2D
2. Minimal area rectangle tests for several point clouds in 2D
3. Testing the diameter computation and calculation of the initial bounding box `A`
(see [section](Function Parameters & How It Works))
for point clouds in 3D
4. Testing the full optimization pipeline to generate an approximation of the minimal volume bounding box

The output can be visualized with the `ipython notebook` `/tests/python/PlotTestResults.ipynb`:

```bash
cd Build/tests
ipython noteboook
```



---

## Benchmark

Here are some short benchmarks (single core) from the tests folder:

| Point Cloud | # Points | ~ CPU Time `approximateMVBB` |
| --------------- | ----------: | ---------------------------: |
| Standford Bunny | 35'945 | 0.91 s |
| Standford Lucy | 14'027'872 | 1.19 s |
| Unit Cube | 140'000'000 | 7.0 s |

`approximateMVBB` runs `approximateMVBBDiam` and performs a grid search afterwards (here 5x5x5=25 directions with 5 optimization runs for each)
It seems to take a long time for 140 million points. The most inefficient task is to get a good initial bounding box. This takes the most time as diameter computations are performed in 3d and then all points are projected in the found diameter direction in 3d and another diameter in the projected plane in 2d is computed. Afterwards the point cloud is sampled (not just random points, its done with a grid) and convex hull, minimal rectangle computations are performed over the grid directions. These algorithms could be made faster by exploiting the following things:

- Use an axis aligned bounding box as the initial bounding box for the grid search (not implemented yet)
- Parallelism for the projection -> (CUDA, threads)

---

## Multithreading Support

You can build the library with OpenMP (by default enabled)
You can set the cmake cache variables `ApproxMVBB_OPENMP_USE_OPENMP=On` which will further enable `ApproxMVBB_OPENMP_USE_NTHREADS=On/Off`.
The variable `ApproxMVBB_OPENMP_USE_NTHREADS` toogles the number of threads to use.
If `Off`, the number of threads is determined at runtime (default).

If you use clang, make sure you have the [OpenMP enabled clang](https://clang-omp.github.io/)! GCC already supports OpenMP.

---

## References

The main articles this code is based on:

```bibtex
@Article{malandain2002,
Author = {Gr'egoire Malandain and Jean-Daniel Boissonnat},
Journal = {International Journal of Computational Geometry & Applications},
Month = {December},
Number = {6},
Pages = {489 - 510},
Timestamp = {2015.09.02},
Title = {Computing the Diameter of a Point Set},
Volume = {12},
Year = {2002}}
```

and

```bibtex
@inproceedings{barequet2001,
Author = {Gill Barequet and Sariel Har-peled},
Booktitle = {In Proc. 10th ACM-SIAM Sympos. Discrete Algorithms},
Pages = {38--91},
Timestamp = {2015.09.02},
Title = {Efficiently Approximating the Minimum-Volume Bounding Box of a Point Set in Three Dimensions},
Year = {2001}}
```

Optimizations for future work:

```bibtex
@Article{chang2011,
Acmid = {2019641},
Address = {New York, NY, USA},
Articleno = {122},
Author = {Chang, Chia-Tche and Gorissen, Bastien and Melchior, Samuel},
Doi = {10.1145/2019627.2019641},
Issn = {0730-0301},
Issue_Date = {October 2011},
Journal = {ACM Trans. Graph.},
Keywords = {Computational geometry, bounding box, manifolds, optimization},
Month = oct,
Number = {5},
Numpages = {16},
Pages = {122:1--122:16},
Publisher = {ACM},
Timestamp = {2015.09.03},
Title = {Fast Oriented Bounding Box Optimization on the Rotation Group {$SO(3,\mathbb{R})$}},
Url = {http://doi.acm.org/10.1145/2019627.2019641},
Volume = {30},
Year = {2011},
Bdsk-Url-1 = {http://doi.acm.org/10.1145/2019627.2019641},
Bdsk-Url-2 = {http://dx.doi.org/10.1145/2019627.2019641}}
```

---

## Licensing

This source code is released under MPL 2.0.

---

## Author and Acknowledgements

ApproxMVBB was written by Gabriel Nützi, with source code from [Grégoire Malandain & Jean-Daniel Boissonnat](http://www-sop.inria.fr/members/Gregoire.Malandain/diameter/)
for the approximation of the diameter of a point cloud.
I was inspired by the work and algorithms of [Gill Barequet & Sariel Har-Peled](http://sarielhp.org/p/98/bbox/) for computing a minimal volume bounding box.
Additionally, the geometric predicates (orient2d) used in the convex hull algorithm (graham scan) have been taken from the fine work of [Jonathan Richard Shewchuk](http://www.cs.cmu.edu/~quake/robust.html).
Special thanks go to my significant other which always had an ear during breakfast for this little project :kissing_heart: