halismai / bpvo

Faster than real time visual odometry
GNU Lesser General Public License v3.0
135 stars 69 forks source link

BPVO

Coverity Scan Build Status Build Status Code Health

A library for (semi-dense) real-time visual odometry from stereo data using direct alignment of feature descriptors. There are descriptors implemented. First, is raw intensity (no descriptor), which runs in real-time or faster. Second, is an implementation of the Bit-Planes descriptor designed for robust performance under challenging illumination conditions as described here and here.

If you run into any issues, or have questions contact

halismai @ cs . cmu . edu

Building

Dependencies

There are two libraries, the core bpvo and some utilities bpvo_utils. You do not need to compile the utilities if you want to embed the library in your code. If you are not building the utilities library, you do not need the following dependencies:

You can drop opencv altogether if you provide your own stereo code (and edit the code slightly).

To build the code base

mkdir build && cmake .. && make -j2

See CMakeLists.txt for additional flags and configurations. You may also configure the library using cmake-gui

Building the Matlab interface

Get mexmat and install it on your system.

git clone https://github.com/halismai/mexmat.git

It is a header-only library, so no compilation is needed. Then, until the matlab interface is integrated into the build system,

cd matlab && make

You might need to modify matlab/Makefile to point to the right location of Matlab and the c++ compiler. As of the date of writing (04/2016) Matlab R2015a supports up to g++-4.7. The code will require g++4.8+

If you get issues with Matlab GLIB_xxx not found, start matlab as

LD_PRELOAD=`g++-4.8+ -print-file-name=libstdc++.so` matlab

There is an experimental support for building the Matlab interface directly from the CMake build system. To try it out configure the build as:

cmake -DBUILD_MATLAB=ON ..

If that does not work, try the manual makefile above.

In either case, you will have to manually edit the location of mexmat and the Matlab path. The process will be fully automated in the future.

Examples

A complete example is provided in apps/vo.cc

A simple example in apps/vo_example.cc

For real-time timting looin in apps/vo_perf.cc On my machine a dual core i7 from 2011, vo_perf.cc runs at 100+ Hz

A minimal example is as follows:

#include <bpvo/vo.h>
#include <bpvo/trajectory.h>  // if you want the trajectory
#include <bpvo/point_cloud.h> // if you want the point cloud

using namespace bpvo;

int main()
{
  //
  // initialize VO using the calibration and AlgorithmParameters
  //
  Matrix33 K; // your calibration (Eigen typedef)
  float b;    // the stereo baseline
  ImageSize image_size(rows, cols); // the image size

  VisualOdometry vo(K, b, image_size, AlgorithmParameters());

  //
  // for every frame
  //  image_ptr is a uint8_t* to the image data
  //  disparity_ptr is a float* to the disparity map
  //
  // Both, the image and disparity size must be the same as supplied to
  // VisualOdometry constructor
  //
  Result result = vo.addFrame(image_ptr, disparity_ptr);

  //
  // If you want the point cloud, you must check if it is available
  //
  if(result.pointCloud) {
    // do something with the point cloud
  }

  // you can also get the trajectory of the camera at any point by calling
  auto trajectory = vo.trajectory();

  // DONE, there is nothing special to do delete the object
  return EXIT_SUCCESS;
}

Matlab Example

params = VoMex.DefaultParameters;
vo = VoMex(K, baseline, image_size, params);

T = eye(4); % the accumulated camera poses
% get images and disparities
% the image must be uint8_t and disparity float
% this assertion must hold
% assert( isa(I, 'uint8') && isa(D, 'single') );
result = vo.addFrame(I, D);

% accumulate the pose
T(:,:,end+1) = T(:,:,end) * inv( result.pose );

See also the code in side matlab/

AlgorithmParameters

The parameters for the algorithm are documented in bpvo/types.h. It is important to get the parameters right for the type of data. Below are additional comments

Common parameters

For Intensity descriptor

If you want to use intensity only, disable parallisim. Compile the code with

cmake .. -DWITH_TBB=OFF -DWITH_SIMD=OFF

Or in your code

bpvo::setNumThreads(1);

The overhead of threads with intensity is not worth it for medium resolution images.

Keyframing

If you want to disable keyframing in order to get pose and point clouds for every image you add, set minTranslationMagToKeyFrame=0.0

parameters specific to illumination robust mode

3D point clouds

Point clouds are generated from the current keyframe. You should check if result.pointCloud is not NULL prior to accessing it. The point cloud comes with its pose as well in the world coordinate system.

Citation

If you find this work useful please cite either

@ARTICLE{2016arXiv160400990A,
   author = {{Alismail}, Hatem and {Browning}, Browning and {Lucey}, Simon},
    title = "{Direct Visual Odometry using Bit-Planes}",
  journal = {ArXiv e-prints arXiv:1064.00990},
  year = {2016}
}

or

@article{alismail2016bit,
  title={Bit-Planes: Dense Subpixel Alignment of Binary Descriptors},
  author={{Alismail}, Hatem and {Browning}, Brett and {Lucey}, Simon},
  journal={arXiv preprint arXiv:1602.00307},
  year={2016}
}

Keep an eye on [http://www.cs.cmu.edu/~halismai/] for additional data