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
00064 const int maxMapPointCount = 200000;
00065
00066 string outputFileName(argv[0]);
00067
00068
00069 PM::ICP icp;
00070
00071
00072 ifstream ifs(argv[1]);
00073 validateFile(argv[1]);
00074 icp.loadFromYaml(ifs);
00075
00076 PMIO::FileInfoVector list(argv[2]);
00077
00078 PM::DataPoints mapPointCloud, newCloud;
00079 TP tp;
00080
00081 for(unsigned i=0; i < list.size(); i++)
00082 {
00083 cout << "---------------------\nLoading: " << list[i].readingFileName << endl;
00084 newCloud = DP::load(list[i].readingFileName);
00085
00086 if(mapPointCloud.features.rows() == 0)
00087 {
00088 mapPointCloud = newCloud;
00089 }
00090 else
00091 {
00092
00093
00094 try
00095 {
00096 tp = icp(mapPointCloud, newCloud);
00097
00098
00099 cout << "match ratio: " << icp.errorMinimizer->getWeightedPointUsedRatio() << endl;
00100
00101 newCloud.features = tp.inverse()*newCloud.features;
00102
00103 PM::DataPointsFilter* densityFilter(
00104 PM::get().DataPointsFilterRegistrar.create(
00105 "SurfaceNormalDataPointsFilter",
00106 map_list_of
00107 ("knn", "10")
00108 ("epsilon", "5")
00109 ("keepNormals", "0")
00110 ("keepDensities", "1")
00111 )
00112 );
00113
00114 PM::DataPointsFilter* maxDensitySubsample(
00115 PM::get().DataPointsFilterRegistrar.create(
00116 "MaxDensityDataPointsFilter",
00117 map_list_of
00118 ("maxDensity", toParam(30))
00119 )
00120 );
00121
00122
00123 mapPointCloud.concatenate(newCloud);
00124 mapPointCloud = densityFilter->filter(mapPointCloud);
00125 mapPointCloud = maxDensitySubsample->filter(mapPointCloud);
00126
00127
00128 const double probToKeep = maxMapPointCount/(double)mapPointCloud.features.cols();
00129 if(probToKeep < 1.0)
00130 {
00131 PM::DataPointsFilter* randSubsample(
00132 PM::get().DataPointsFilterRegistrar.create(
00133 "RandomSamplingDataPointsFilter",
00134 map_list_of
00135 ("prob", toParam(probToKeep))
00136 )
00137 );
00138 mapPointCloud = randSubsample->filter(mapPointCloud);
00139 }
00140 }
00141 catch (PM::ConvergenceError& error)
00142 {
00143 cout << "ERROR PM::ICP failed to converge: " << endl;
00144 cout << " " << error.what() << endl;
00145
00146
00147 }
00148
00149 stringstream outputFileNameIter;
00150 outputFileNameIter << outputFileName << "_" << i << ".vtk";
00151
00152 cout << "outputFileName: " << outputFileNameIter.str() << endl;
00153 mapPointCloud.save(outputFileNameIter.str());
00154 }
00155 }
00156
00157 return 0;
00158 }
00159
00160 void validateArgs(int argc, char *argv[])
00161 {
00162 if (!(argc == 3))
00163 {
00164 cerr << "Error in command line, usage " << argv[0] << " icpConfiguration.yaml listOfFiles.csv" << endl;
00165 cerr << endl << "Example:" << endl;
00166 cerr << argv[0] << " ../examples/data/default.yaml ../examples/data/carCloudList.csv" << endl << endl;
00167
00168 abort();
00169 }
00170 }
00171
00172