Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "pointmatcher/PointMatcher.h"
00037 #include "pointmatcher/IO.h"
00038 #include <cassert>
00039 #include <iostream>
00040 #include <fstream>
00041 #include <boost/format.hpp>
00042 #include <boost/filesystem/path.hpp>
00043 #include <boost/filesystem/operations.hpp>
00044
00045
00046 using namespace std;
00047 using namespace PointMatcherSupport;
00048
00049 void validateArgs(int argc, char *argv[]);
00050
00055 int main(int argc, char *argv[])
00056 {
00057 validateArgs(argc, argv);
00058
00059 typedef PointMatcher<float> PM;
00060 typedef PointMatcherIO<float> PMIO;
00061 typedef PM::TransformationParameters TP;
00062 typedef PM::DataPoints DP;
00063 typedef Parametrizable::Parameter Parameter;
00064
00065 const int maxMapPointCount = 200000;
00066
00067 string outputFileName(argv[0]);
00068
00069
00070 PM::ICP icp;
00071
00072
00073 ifstream ifs(argv[1]);
00074 validateFile(argv[1]);
00075 icp.loadFromYaml(ifs);
00076
00077 PMIO::FileInfoVector list(argv[2]);
00078
00079 PM::DataPoints mapPointCloud, newCloud;
00080 TP tp;
00081
00082 for(unsigned i=0; i < list.size(); i++)
00083 {
00084 cout << "---------------------\nLoading: " << list[i].readingFileName << endl;
00085 newCloud = DP::load(list[i].readingFileName);
00086
00087 if(mapPointCloud.features.rows() == 0)
00088 {
00089 mapPointCloud = newCloud;
00090 }
00091 else
00092 {
00093
00094
00095 try
00096 {
00097 tp = icp(mapPointCloud, newCloud);
00098
00099
00100 cout << "match ratio: " << icp.errorMinimizer->getWeightedPointUsedRatio() << endl;
00101
00102 newCloud.features = tp.inverse()*newCloud.features;
00103
00104 PM::DataPointsFilter* densityFilter(
00105 PM::get().DataPointsFilterRegistrar.create(
00106 "SurfaceNormalDataPointsFilter",
00107 map_list_of
00108 ("binSize", "10")
00109 ("epsilon", "5")
00110 ("keepNormals", "0")
00111 ("keepDensities", "1")
00112 )
00113 );
00114
00115 PM::DataPointsFilter* maxDensitySubsample(
00116 PM::get().DataPointsFilterRegistrar.create(
00117 "MaxDensityDataPointsFilter",
00118 map_list_of
00119 ("maxDensity", toParam(30))
00120 )
00121 );
00122
00123
00124 mapPointCloud.concatenate(newCloud);
00125 mapPointCloud = densityFilter->filter(mapPointCloud);
00126 mapPointCloud = maxDensitySubsample->filter(mapPointCloud);
00127
00128
00129 const double probToKeep = maxMapPointCount/(double)mapPointCloud.features.cols();
00130 if(probToKeep < 1.0)
00131 {
00132 PM::DataPointsFilter* randSubsample(
00133 PM::get().DataPointsFilterRegistrar.create(
00134 "RandomSamplingDataPointsFilter",
00135 map_list_of
00136 ("prob", toParam(probToKeep))
00137 )
00138 );
00139 mapPointCloud = randSubsample->filter(mapPointCloud);
00140 }
00141 }
00142 catch (PM::ConvergenceError& error)
00143 {
00144 cout << "ERROR PM::ICP failed to converge: " << endl;
00145 cout << " " << error.what() << endl;
00146
00147
00148 }
00149
00150 stringstream outputFileNameIter;
00151 outputFileNameIter << outputFileName << "_" << i;
00152
00153 cout << "outputFileName: " << outputFileNameIter.str() << endl;
00154 mapPointCloud.save(outputFileNameIter.str());
00155 }
00156 }
00157
00158 return 0;
00159 }
00160
00161 void validateArgs(int argc, char *argv[])
00162 {
00163 if (!(argc == 3))
00164 {
00165 cerr << "Error in command line, usage " << argv[0] << " icpConfiguration.yaml listOfFiles.csv" << endl;
00166 cerr << endl << "Example:" << endl;
00167 cerr << argv[0] << " ../examples/data/default.yaml ../examples/data/carCloudList.csv" << endl << endl;
00168
00169 abort();
00170 }
00171 }
00172
00173