mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 01:20:25 +08:00
CLAMS: cleanup eigen_extensions.h, models can be saved/loaded in binary (*.bin) or ascii (*.txt) formats
This commit is contained in:
@@ -31,6 +31,7 @@ RTAB-Map integration: Mathieu Labbe
|
||||
#include "rtabmap/core/clams/frame_projector.h"
|
||||
#include <rtabmap/utilite/ULogger.h>
|
||||
#include <rtabmap/utilite/UMath.h>
|
||||
#include <rtabmap/utilite/UFile.h>
|
||||
#include "eigen_extensions/eigen_extensions.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -97,26 +98,52 @@ namespace clams
|
||||
*z *= mult;
|
||||
}
|
||||
|
||||
void DiscreteFrustum::serialize(std::ostream& out) const
|
||||
void DiscreteFrustum::serialize(std::ostream& out, bool ascii) const
|
||||
{
|
||||
eigen_extensions::serializeScalar(max_dist_, out);
|
||||
eigen_extensions::serializeScalar(num_bins_, out);
|
||||
eigen_extensions::serializeScalar(bin_depth_, out);
|
||||
eigen_extensions::serialize(counts_, out);
|
||||
eigen_extensions::serialize(total_numerators_, out);
|
||||
eigen_extensions::serialize(total_denominators_, out);
|
||||
eigen_extensions::serialize(multipliers_, out);
|
||||
if(ascii)
|
||||
{
|
||||
eigen_extensions::serializeScalarASCII(max_dist_, out);
|
||||
eigen_extensions::serializeScalarASCII(num_bins_, out);
|
||||
eigen_extensions::serializeScalarASCII(bin_depth_, out);
|
||||
eigen_extensions::serializeASCII(counts_, out);
|
||||
eigen_extensions::serializeASCII(total_numerators_, out);
|
||||
eigen_extensions::serializeASCII(total_denominators_, out);
|
||||
eigen_extensions::serializeASCII(multipliers_, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
eigen_extensions::serializeScalar(max_dist_, out);
|
||||
eigen_extensions::serializeScalar(num_bins_, out);
|
||||
eigen_extensions::serializeScalar(bin_depth_, out);
|
||||
eigen_extensions::serialize(counts_, out);
|
||||
eigen_extensions::serialize(total_numerators_, out);
|
||||
eigen_extensions::serialize(total_denominators_, out);
|
||||
eigen_extensions::serialize(multipliers_, out);
|
||||
}
|
||||
}
|
||||
|
||||
void DiscreteFrustum::deserialize(std::istream& in)
|
||||
void DiscreteFrustum::deserialize(std::istream& in, bool ascii)
|
||||
{
|
||||
eigen_extensions::deserializeScalar(in, &max_dist_);
|
||||
eigen_extensions::deserializeScalar(in, &num_bins_);
|
||||
eigen_extensions::deserializeScalar(in, &bin_depth_);
|
||||
eigen_extensions::deserialize(in, &counts_);
|
||||
eigen_extensions::deserialize(in, &total_numerators_);
|
||||
eigen_extensions::deserialize(in, &total_denominators_);
|
||||
eigen_extensions::deserialize(in, &multipliers_);
|
||||
if(ascii)
|
||||
{
|
||||
eigen_extensions::deserializeScalarASCII(in, &max_dist_);
|
||||
eigen_extensions::deserializeScalarASCII(in, &num_bins_);
|
||||
eigen_extensions::deserializeScalarASCII(in, &bin_depth_);
|
||||
eigen_extensions::deserializeASCII(in, &counts_);
|
||||
eigen_extensions::deserializeASCII(in, &total_numerators_);
|
||||
eigen_extensions::deserializeASCII(in, &total_denominators_);
|
||||
eigen_extensions::deserializeASCII(in, &multipliers_);
|
||||
}
|
||||
else
|
||||
{
|
||||
eigen_extensions::deserializeScalar(in, &max_dist_);
|
||||
eigen_extensions::deserializeScalar(in, &num_bins_);
|
||||
eigen_extensions::deserializeScalar(in, &bin_depth_);
|
||||
eigen_extensions::deserialize(in, &counts_);
|
||||
eigen_extensions::deserialize(in, &total_numerators_);
|
||||
eigen_extensions::deserialize(in, &total_denominators_);
|
||||
eigen_extensions::deserialize(in, &multipliers_);
|
||||
}
|
||||
UDEBUG("Frustum: max_dist=%f", max_dist_);
|
||||
UDEBUG("Frustum: num_bins=%d", num_bins_);
|
||||
UDEBUG("Frustum: bin_depth=%f", bin_depth_);
|
||||
@@ -267,60 +294,91 @@ namespace clams
|
||||
|
||||
void DiscreteDepthDistortionModel::load(const std::string& path)
|
||||
{
|
||||
bool ascii = UFile::getExtension(path).compare("txt") == 0;
|
||||
ifstream f;
|
||||
f.open(path.c_str());
|
||||
if(!f.is_open()) {
|
||||
cerr << "Failed to open " << path << endl;
|
||||
assert(f.is_open());
|
||||
}
|
||||
deserialize(f);
|
||||
deserialize(f, ascii);
|
||||
f.close();
|
||||
}
|
||||
|
||||
void DiscreteDepthDistortionModel::save(const std::string& path) const
|
||||
{
|
||||
bool ascii = UFile::getExtension(path).compare("txt") == 0;
|
||||
ofstream f;
|
||||
f.open(path.c_str());
|
||||
if(!f.is_open()) {
|
||||
cerr << "Failed to open " << path << endl;
|
||||
assert(f.is_open());
|
||||
}
|
||||
serialize(f);
|
||||
serialize(f, ascii);
|
||||
f.close();
|
||||
}
|
||||
|
||||
void DiscreteDepthDistortionModel::serialize(std::ostream& out) const
|
||||
void DiscreteDepthDistortionModel::serialize(std::ostream& out, bool ascii) const
|
||||
{
|
||||
out << "DiscreteDepthDistortionModel v01" << endl;
|
||||
eigen_extensions::serializeScalar(width_, out);
|
||||
eigen_extensions::serializeScalar(height_, out);
|
||||
eigen_extensions::serializeScalar(bin_width_, out);
|
||||
eigen_extensions::serializeScalar(bin_height_, out);
|
||||
eigen_extensions::serializeScalar(bin_depth_, out);
|
||||
eigen_extensions::serializeScalar(num_bins_x_, out);
|
||||
eigen_extensions::serializeScalar(num_bins_y_, out);
|
||||
eigen_extensions::serializeScalar(training_samples_, out);
|
||||
if(ascii)
|
||||
{
|
||||
eigen_extensions::serializeScalarASCII(width_, out);
|
||||
eigen_extensions::serializeScalarASCII(height_, out);
|
||||
eigen_extensions::serializeScalarASCII(bin_width_, out);
|
||||
eigen_extensions::serializeScalarASCII(bin_height_, out);
|
||||
eigen_extensions::serializeScalarASCII(bin_depth_, out);
|
||||
eigen_extensions::serializeScalarASCII(num_bins_x_, out);
|
||||
eigen_extensions::serializeScalarASCII(num_bins_y_, out);
|
||||
eigen_extensions::serializeScalarASCII(training_samples_, out);
|
||||
}
|
||||
else
|
||||
{
|
||||
eigen_extensions::serializeScalar(width_, out);
|
||||
eigen_extensions::serializeScalar(height_, out);
|
||||
eigen_extensions::serializeScalar(bin_width_, out);
|
||||
eigen_extensions::serializeScalar(bin_height_, out);
|
||||
eigen_extensions::serializeScalar(bin_depth_, out);
|
||||
eigen_extensions::serializeScalar(num_bins_x_, out);
|
||||
eigen_extensions::serializeScalar(num_bins_y_, out);
|
||||
eigen_extensions::serializeScalar(training_samples_, out);
|
||||
}
|
||||
|
||||
|
||||
for(int y = 0; y < num_bins_y_; ++y)
|
||||
for(int x = 0; x < num_bins_x_; ++x)
|
||||
frustums_[y][x]->serialize(out);
|
||||
frustums_[y][x]->serialize(out, ascii);
|
||||
}
|
||||
|
||||
void DiscreteDepthDistortionModel::deserialize(std::istream& in)
|
||||
void DiscreteDepthDistortionModel::deserialize(std::istream& in, bool ascii)
|
||||
{
|
||||
UDEBUG("");
|
||||
string buf;
|
||||
getline(in, buf);
|
||||
UDEBUG("buf=%s", buf.c_str());
|
||||
assert(buf == "DiscreteDepthDistortionModel v01");
|
||||
eigen_extensions::deserializeScalar(in, &width_);
|
||||
eigen_extensions::deserializeScalar(in, &height_);
|
||||
eigen_extensions::deserializeScalar(in, &bin_width_);
|
||||
eigen_extensions::deserializeScalar(in, &bin_height_);
|
||||
eigen_extensions::deserializeScalar(in, &bin_depth_);
|
||||
eigen_extensions::deserializeScalar(in, &num_bins_x_);
|
||||
eigen_extensions::deserializeScalar(in, &num_bins_y_);
|
||||
eigen_extensions::deserializeScalar(in, &training_samples_);
|
||||
if(ascii)
|
||||
{
|
||||
eigen_extensions::deserializeScalarASCII(in, &width_);
|
||||
eigen_extensions::deserializeScalarASCII(in, &height_);
|
||||
eigen_extensions::deserializeScalarASCII(in, &bin_width_);
|
||||
eigen_extensions::deserializeScalarASCII(in, &bin_height_);
|
||||
eigen_extensions::deserializeScalarASCII(in, &bin_depth_);
|
||||
eigen_extensions::deserializeScalarASCII(in, &num_bins_x_);
|
||||
eigen_extensions::deserializeScalarASCII(in, &num_bins_y_);
|
||||
eigen_extensions::deserializeScalarASCII(in, &training_samples_);
|
||||
}
|
||||
else
|
||||
{
|
||||
eigen_extensions::deserializeScalar(in, &width_);
|
||||
eigen_extensions::deserializeScalar(in, &height_);
|
||||
eigen_extensions::deserializeScalar(in, &bin_width_);
|
||||
eigen_extensions::deserializeScalar(in, &bin_height_);
|
||||
eigen_extensions::deserializeScalar(in, &bin_depth_);
|
||||
eigen_extensions::deserializeScalar(in, &num_bins_x_);
|
||||
eigen_extensions::deserializeScalar(in, &num_bins_y_);
|
||||
eigen_extensions::deserializeScalar(in, &training_samples_);
|
||||
}
|
||||
UINFO("Distortion Model: width=%d", width_);
|
||||
UINFO("Distortion Model: height=%d", height_);
|
||||
UINFO("Distortion Model: bin_width=%d", bin_width_);
|
||||
@@ -336,7 +394,7 @@ namespace clams
|
||||
for(size_t x = 0; x < frustums_[y].size(); ++x) {
|
||||
UDEBUG("Distortion Model: Frustum[%d][%d]", y, x);
|
||||
frustums_[y][x] = new DiscreteFrustum;
|
||||
frustums_[y][x]->deserialize(in);
|
||||
frustums_[y][x]->deserialize(in, ascii);
|
||||
}
|
||||
}
|
||||
UDEBUG("");
|
||||
|
||||
@@ -28,25 +28,7 @@ namespace eigen_extensions {
|
||||
double var = total / (double)vec.rows();
|
||||
return sqrt(var);
|
||||
}
|
||||
|
||||
template<class S, int T, int U>
|
||||
void save(const Eigen::Matrix<S, T, U>& mat, const std::string& filename);
|
||||
|
||||
template<class S, int T, int U>
|
||||
void load(const std::string& filename, Eigen::Matrix<S, T, U>* mat);
|
||||
|
||||
template<class ScalarType, int Options, class IndexType>
|
||||
void save(const Eigen::SparseMatrix<ScalarType, Options, IndexType>& mat, const std::string& filename);
|
||||
|
||||
template<class ScalarType, int Options, class IndexType>
|
||||
void load(const std::string& filename, Eigen::SparseMatrix<ScalarType, Options, IndexType>* mat);
|
||||
|
||||
template<class S, int T, int U>
|
||||
void saveASCII(const Eigen::Matrix<S, T, U>& mat, const std::string& filename);
|
||||
|
||||
template<class S, int T, int U>
|
||||
void loadASCII(const std::string& filename, Eigen::Matrix<S, T, U>* mat);
|
||||
|
||||
template<class S, int T, int U>
|
||||
void serialize(const Eigen::Matrix<S, T, U>& mat, std::ostream& strm);
|
||||
|
||||
@@ -60,15 +42,6 @@ namespace eigen_extensions {
|
||||
void deserializeASCII(std::istream& strm, Eigen::Matrix<S, T, U>* mat);
|
||||
|
||||
|
||||
// -- SparseMatrix serialization.
|
||||
|
||||
template<class ScalarType, int Options, class IndexType>
|
||||
void serialize(const Eigen::SparseMatrix<ScalarType, Options, IndexType>& mat, std::ostream& strm);
|
||||
|
||||
template<class ScalarType, int Options, class IndexType>
|
||||
void deserialize(std::istream& strm, Eigen::SparseMatrix<ScalarType, Options, IndexType>* mat);
|
||||
|
||||
|
||||
// -- Scalar serialization
|
||||
// TODO: Can you name these {de,}serialize() and still have the right
|
||||
// functions get called when serializing matrices?
|
||||
@@ -78,6 +51,12 @@ namespace eigen_extensions {
|
||||
template<class T>
|
||||
void deserializeScalar(std::istream& strm, T* val);
|
||||
|
||||
template<class T>
|
||||
void serializeScalarASCII(T val, std::ostream& strm);
|
||||
|
||||
template<class T>
|
||||
void deserializeScalarASCII(std::istream& strm, T* val);
|
||||
|
||||
|
||||
/************************************************************
|
||||
* Template implementations
|
||||
@@ -111,133 +90,7 @@ namespace eigen_extensions {
|
||||
*mat = Eigen::Map< Eigen::Matrix<S, T, U> >(buf, rows, cols);
|
||||
free(buf);
|
||||
}
|
||||
/*
|
||||
template<class S, int T, int U>
|
||||
void save(const Eigen::Matrix<S, T, U>& mat, const std::string& filename)
|
||||
{
|
||||
assert(filename.size() > 3);
|
||||
if(filename.substr(filename.size() - 3, 3).compare(".gz") == 0) {
|
||||
ogzstream file(filename.c_str());
|
||||
assert(file);
|
||||
serialize(mat, file);
|
||||
file.close();
|
||||
}
|
||||
else {
|
||||
assert(boost::filesystem::extension(filename).compare(".eig") == 0);
|
||||
std::ofstream file(filename.c_str());
|
||||
assert(file);
|
||||
serialize(mat, file);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
template<class S, int T, int U>
|
||||
void load(const std::string& filename, Eigen::Matrix<S, T, U>* mat)
|
||||
{
|
||||
assert(filename.size() > 3);
|
||||
if(filename.substr(filename.size() - 3, 3).compare(".gz") == 0) {
|
||||
igzstream file(filename.c_str());
|
||||
assert(file);
|
||||
deserialize(file, mat);
|
||||
file.close();
|
||||
}
|
||||
else {
|
||||
assert(boost::filesystem::extension(filename).compare(".eig") == 0);
|
||||
std::ifstream file(filename.c_str());
|
||||
assert(file);
|
||||
deserialize(file, mat);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
*/
|
||||
template<class ScalarType, int Options, class IndexType>
|
||||
void serialize(const Eigen::SparseMatrix<ScalarType, Options, IndexType>& mat, std::ostream& strm)
|
||||
{
|
||||
int bytes = sizeof(ScalarType);
|
||||
int type = Options;
|
||||
int outer = mat.outerSize();
|
||||
int inner = mat.innerSize();
|
||||
int nnz = mat.nonZeros();
|
||||
strm.write((char*)&bytes, sizeof(int));
|
||||
strm.write((char*)&type, sizeof(int));
|
||||
strm.write((char*)&outer, sizeof(int));
|
||||
strm.write((char*)&inner, sizeof(int));
|
||||
strm.write((char*)&nnz, sizeof(int));
|
||||
|
||||
typedef typename Eigen::SparseMatrix<ScalarType, Options, IndexType>::InnerIterator InnerIterator;
|
||||
for(IndexType i = 0; i < mat.outerSize(); ++i) {
|
||||
int num = 0;
|
||||
for(InnerIterator it(mat, i); it; ++it)
|
||||
++num;
|
||||
strm.write((const char*)&num, sizeof(num));
|
||||
|
||||
for(InnerIterator it(mat, i); it; ++it) {
|
||||
int idx = it.index();
|
||||
ScalarType buf = it.value();
|
||||
strm.write((const char*)&idx, sizeof(idx));
|
||||
strm.write((const char*)&buf, sizeof(buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class ScalarType, int Options, class IndexType>
|
||||
void deserialize(std::istream& strm, Eigen::SparseMatrix<ScalarType, Options, IndexType>* mat)
|
||||
{
|
||||
int bytes;
|
||||
int options;
|
||||
int outer;
|
||||
int inner;
|
||||
int nnz;
|
||||
strm.read((char*)&bytes, sizeof(int));
|
||||
strm.read((char*)&options, sizeof(int));
|
||||
strm.read((char*)&outer, sizeof(int));
|
||||
strm.read((char*)&inner, sizeof(int));
|
||||
strm.read((char*)&nnz, sizeof(int));
|
||||
assert(bytes == sizeof(ScalarType));
|
||||
assert(options == Options);
|
||||
|
||||
if(mat->IsRowMajor)
|
||||
mat->resize(outer, inner);
|
||||
else
|
||||
mat->resize(inner, outer);
|
||||
|
||||
mat->reserve(nnz);
|
||||
ScalarType buf;
|
||||
for(int i = 0; i < mat->outerSize(); ++i) {
|
||||
mat->startVec(i);
|
||||
int num;
|
||||
strm.read((char*)&num, sizeof(int));
|
||||
int idx;
|
||||
for(int j = 0; j < num; ++j) {
|
||||
strm.read((char*)&idx, sizeof(idx));
|
||||
strm.read((char*)&buf, sizeof(buf));
|
||||
mat->insertBackByOuterInner(i, idx) = buf;
|
||||
}
|
||||
}
|
||||
mat->finalize();
|
||||
}
|
||||
/*
|
||||
template<class ScalarType, int Options, class IndexType>
|
||||
void save(const Eigen::SparseMatrix<ScalarType, Options, IndexType>& mat, const std::string& filename)
|
||||
{
|
||||
assert(boost::filesystem::extension(filename).compare(".eig") == 0);
|
||||
std::ofstream file(filename.c_str());
|
||||
assert(file);
|
||||
serialize(mat, file);
|
||||
file.close();
|
||||
}
|
||||
|
||||
template<class ScalarType, int Options, class IndexType>
|
||||
void load(const std::string& filename, Eigen::SparseMatrix<ScalarType, Options, IndexType>* mat)
|
||||
{
|
||||
assert(filename.size() > 3);
|
||||
assert(boost::filesystem::extension(filename).compare(".eig") == 0);
|
||||
std::ifstream file(filename.c_str());
|
||||
assert(file);
|
||||
deserialize(file, mat);
|
||||
file.close();
|
||||
}
|
||||
*/
|
||||
template<class S, int T, int U>
|
||||
void serializeASCII(const Eigen::Matrix<S, T, U>& mat, std::ostream& strm)
|
||||
{
|
||||
@@ -271,30 +124,6 @@ namespace eigen_extensions {
|
||||
}
|
||||
}
|
||||
|
||||
template<class S, int T, int U>
|
||||
void saveASCII(const Eigen::Matrix<S, T, U>& mat, const std::string& filename)
|
||||
{
|
||||
assert(filename.substr(filename.size() - 8).compare(".eig.txt") == 0);
|
||||
std::ofstream file;
|
||||
file.open(filename.c_str());
|
||||
assert(file);
|
||||
serializeASCII(mat, file);
|
||||
file.close();
|
||||
}
|
||||
|
||||
template<class S, int T, int U>
|
||||
void loadASCII(const std::string& filename, Eigen::Matrix<S, T, U>* mat)
|
||||
{
|
||||
assert(filename.substr(filename.size() - 8).compare(".eig.txt") == 0);
|
||||
std::ifstream file;
|
||||
file.open(filename.c_str());
|
||||
if(!file)
|
||||
std::cerr << "File " << filename << " could not be opened. Dying badly." << std::endl;
|
||||
assert(file);
|
||||
deserializeASCII(file, mat);
|
||||
file.close();
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void serializeScalar(T val, std::ostream& strm)
|
||||
{
|
||||
@@ -306,6 +135,25 @@ namespace eigen_extensions {
|
||||
{
|
||||
strm.read((char*)val, sizeof(T));
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void serializeScalarASCII(T val, std::ostream& strm)
|
||||
{
|
||||
int old_precision = strm.precision();
|
||||
strm.precision(16);
|
||||
strm << "% " << val << std::endl;
|
||||
strm.precision(old_precision);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
void deserializeScalarASCII(std::istream& strm, T* val)
|
||||
{
|
||||
std::string line;
|
||||
while(line.length() == 0) getline(strm, line);
|
||||
assert(line[0] == '%');
|
||||
std::istringstream iss(line.substr(1));
|
||||
iss >> *val;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user