Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
christiankerl committed Sep 13, 2014
0 parents commit bcf9e09
Show file tree
Hide file tree
Showing 4 changed files with 531 additions and 0 deletions.
149 changes: 149 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# tum_benchmark

C++ header only library to easily access files used in [TUM RGB-D SLAM datasets](http://vision.in.tum.de/data/datasets/rgbd-dataset).

## Optional Requirements

* Boost
* Eigen

## Basic Types

The benchmark datasets come with two types of files. The first contains lists of timestamped images. Every entry of such a file is represented by the `tum_benchmark::File` struct:

```c++
struct File
{
double timestamp;
std::string name;
};
```

The second file type represents groundtruth trajectories. Their entries are represented by the `tum_benchmark::Trajectory` struct:

```c++
struct Trajectory
{
double timestamp;
double tx, ty, tz, qx, qy, qz, qw;
};
```

For more details about these files have a look at the [format documentation](http://vision.in.tum.de/data/datasets/rgbd-dataset/file_formats).

## Examples

Reading a dataset file containing the timestamped RGB images into a vector:

```c++
#include <tum_benchmark/tum_benchmark.hpp>
#include <vector>

int main(int argc, char **argv)
{
using namespace tum_benchmark;

// define the format of each line in the file
typedef File EntryFormat;

// open the file reader
FileReader<EntryFormat> reader("/path/to/rgbd_dataset_freiburg1_desk/rgb.txt");

// read all lines into a vector
std::vector<EntryFormat> all_entries;
std::copy(reader.begin(), reader.end(), std::back_inserter(all_entries));

return 0;
}
```
Reading a dataset file containing the timestamped RGB images into a vector and prefixing every filename with the absolute dataset path:
```c++
#include <tum_benchmark/tum_benchmark.hpp>
#include <vector>
int main(int argc, char **argv)
{
using namespace tum_benchmark;
std::string dataset = "/path/to/rgbd_dataset_freiburg1_desk/";
typedef File EntryFormat;
FileReader<EntryFormat> reader(dataset + "rgb.txt");
std::vector<EntryFormat> all_entries;
// make_prefix_file_iterator creates an iterator, which prefixes the name field in every File object
std::copy(make_prefix_file_iterator(dataset, reader.begin()), make_prefix_file_iterator(dataset, reader.end()), std::back_inserter(all_entries));
return 0;
}
```

Reading a groundtruth trajectory and converting it to `Eigen::Isometry3f` objects:

```c++
#include <tum_benchmark/tum_benchmark.hpp>
#include <tum_benchmark/eigen_support.hpp>

#include <Eigen/Geometry>

#include <vector>
#include <iostream>

int main(int argc, char **argv)
{
using namespace tum_benchmark;

typedef Trajectory EntryFormat;
FileReader<EntryFormat> reader("/path/to/rgbd_dataset_freiburg1_desk/groundtruth.txt");

Eigen::Isometry3f pose;

for(FileReader<EntryFormat>::iterator it = reader.begin(); it != reader.end(); ++it)
{
// convert the Trajectory object to a Eigen object
toEigen(*it, pose);

std::cout << pose.matrix() << std::endl;
}

return 0;
}
```
Use Boost.Fusion to read dataset files created with the [`associate.py` script](http://vision.in.tum.de/data/datasets/rgbd-dataset/tools#associating_color_and_depth_images):
```c++
#include <tum_benchmark/tum_benchmark.hpp>
#include <tum_benchmark/boost_support.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <vector>
#include <iostream>
int main(int argc, char **argv)
{
using namespace tum_benchmark;
namespace bf = boost::fusion;
std::string dataset = "/path/to/rgbd_dataset_freiburg1_desk/";
// use boost::fusion::vector to define the format of associated files
typedef bf::vector<File, File, Trajectory> EntryFormat;
FileReader<EntryFormat> reader(dataset + "rgb_depth_groundtruth.txt");
// prefixing every filename also works for complex formats
for(PrefixFileIterator<FileReader<EntryFormat>::iterator> it = make_prefix_file_iterator(dataset, reader.begin()); it != reader.end(); ++it)
{
// get the prefixed name of the depth file
std::cout << bf::at_c<1>(*it).name << std::endl;
}
return 0;
}
```
86 changes: 86 additions & 0 deletions include/tum_benchmark/boost_support.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#ifndef BOOST_SUPPORT_HPP_
#define BOOST_SUPPORT_HPP_

#include <tum_benchmark/tum_benchmark.hpp>

#include <boost/fusion/include/in.hpp>
#include <boost/fusion/include/is_sequence.hpp>
#include <boost/fusion/include/transform.hpp>

#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_io.hpp>

namespace tum_benchmark
{
namespace internal
{
template<typename EntryFormatT>
struct ApplyStreamManipulators<EntryFormatT, typename boost::enable_if<boost::fusion::traits::is_sequence<EntryFormatT> >::type>
{
static void apply(std::istream &s)
{
using namespace boost::fusion;
s >> tuple_open(' ') >> tuple_close(' ') >> tuple_delimiter(' ');
}
};

template <class T0, class T1, class T2, class T3, class T4,
class T5, class T6, class T7, class T8, class T9>
struct ApplyStreamManipulators<boost::tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, void>
{
static void apply(std::istream &s)
{
using namespace boost::tuples;
s >> set_open(' ') >> set_close(' ') >> set_delimiter(' ');
}
};

struct prefix_file_transform_op
{
template<typename T>
struct result;

template <typename T>
struct result<prefix_file_transform_op(T)>
{
typedef typename boost::remove_reference<T>::type type;
};

std::string m_prefix;

prefix_file_transform_op(const std::string &prefix) :
m_prefix(prefix)
{
}

template<typename T>
T operator()(const T &data) const
{
T result;
PrefixFileOp<T> op(m_prefix);
op(data, result);

return result;
}
};

template<typename EntryFormatT>
struct PrefixFileOp<EntryFormatT, typename boost::enable_if<boost::fusion::traits::is_sequence<EntryFormatT> >::type>
{
std::string m_prefix;

PrefixFileOp(const std::string &prefix) :
m_prefix(prefix)
{
}

void operator()(const EntryFormatT &in, EntryFormatT &out) const
{
out = boost::fusion::transform(in, prefix_file_transform_op(m_prefix));
}
};

} // namespace internal

} // namespace tum_benchmark
#endif // BOOST_SUPPORT_HPP_
25 changes: 25 additions & 0 deletions include/tum_benchmark/eigen_support.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef EIGEN_SUPPORT_HPP_
#define EIGEN_SUPPORT_HPP_

#include <tum_benchmark/tum_benchmark.hpp>
#include <Eigen/Geometry>

namespace tum_benchmark
{

template<typename ScalarT, int TypeT>
void toEigen(Trajectory &trajectory, Eigen::Transform<ScalarT, 3, TypeT> &transform)
{
Eigen::Quaternion<ScalarT> q(ScalarT(trajectory.qw), ScalarT(trajectory.qx), ScalarT(trajectory.qy), ScalarT(trajectory.qz));
Eigen::Transform<ScalarT, 3, TypeT> result(q);

result.translation()(0) = ScalarT(trajectory.tx);
result.translation()(1) = ScalarT(trajectory.ty);
result.translation()(2) = ScalarT(trajectory.tz);

transform = result;
}

} // namespace tum_benchmark

#endif // EIGEN_SUPPORT_HPP_
Loading

0 comments on commit bcf9e09

Please sign in to comment.