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 #include <boost/lexical_cast.hpp>
00045
00046 using namespace std;
00047 using namespace PointMatcherSupport;
00048
00049 void validateArgs(int argc, char *argv[]);
00050 void setupArgs(int argc, char *argv[], unsigned int& startId, unsigned int& endId, string& extension);
00051 vector<string> loadYamlFile(string listFileName);
00052
00057 int main(int argc, char *argv[])
00058 {
00059 validateArgs(argc, argv);
00060
00061 typedef PointMatcher<float> PM;
00062 typedef PointMatcherIO<float> PMIO;
00063 typedef PM::TransformationParameters TP;
00064 typedef PM::DataPoints DP;
00065
00066
00067 PMIO::FileInfoVector list(argv[1]);
00068 const unsigned totalPointCount = boost::lexical_cast<unsigned>(argv[2]);
00069 string outputFileName(argv[3]);
00070
00071
00072 setLogger(PM::get().LoggerRegistrar.create("FileLogger"));
00073
00074 PM::DataPoints mapCloud;
00075
00076 PM::DataPoints lastCloud, newCloud;
00077 TP T = TP::Identity(4,4);
00078
00079
00080 PM::Transformations transformations;
00081 PM::Transformation* transformPoints;
00082 transformPoints = PM::get().TransformationRegistrar.create("TransformFeatures");
00083 PM::Transformation* transformNormals;
00084 transformNormals = PM::get().TransformationRegistrar.create("TransformNormals");
00085
00086 transformations.push_back(transformPoints);
00087 transformations.push_back(transformNormals);
00088
00089
00090 PM::DataPointsFilter* removeScanner(
00091 PM::get().DataPointsFilterRegistrar.create(
00092 "MinDistDataPointsFilter",
00093 map_list_of
00094 ("minDist", "1.0")
00095 )
00096 );
00097
00098 PM::DataPointsFilter* randSubsample(
00099 PM::get().DataPointsFilterRegistrar.create(
00100 "RandomSamplingDataPointsFilter",
00101 map_list_of
00102 ("prob", toParam(0.65))
00103 )
00104 );
00105
00106 PM::DataPointsFilter* normalFilter(
00107 PM::get().DataPointsFilterRegistrar.create(
00108 "SurfaceNormalDataPointsFilter",
00109 map_list_of
00110 ("binSize", "10")
00111 ("epsilon", "5")
00112 ("keepNormals","1")
00113 ("keepDensities","0")
00114 )
00115 );
00116
00117 PM::DataPointsFilter* densityFilter(
00118 PM::get().DataPointsFilterRegistrar.create(
00119 "SurfaceNormalDataPointsFilter",
00120 map_list_of
00121 ("binSize", "10")
00122 ("epsilon", "5")
00123 ("keepNormals","0")
00124 ("keepDensities","1")
00125 )
00126 );
00127
00128 PM::DataPointsFilter* orientNormalFilter(
00129 PM::get().DataPointsFilterRegistrar.create(
00130 "OrientNormalsDataPointsFilter",
00131 map_list_of
00132 ("towardCenter", "1")
00133 )
00134 );
00135
00136 PM::DataPointsFilter* uniformSubsample(
00137 PM::get().DataPointsFilterRegistrar.create(
00138 "MaxDensityDataPointsFilter",
00139 map_list_of
00140 ("maxDensity", toParam(30))
00141 )
00142 );
00143
00144 PM::DataPointsFilter* shadowFilter(
00145 PM::get().DataPointsFilterRegistrar.create(
00146 "ShadowDataPointsFilter"
00147 )
00148 );
00149
00150 for(unsigned i=0; i < list.size(); i++)
00151 {
00152 newCloud = DP::load(list[i].readingFileName);
00153
00154 cout << "Point cloud loaded" << endl;
00155
00156 if(list[i].groundTruthTransformation.rows() != 0)
00157 T = list[i].groundTruthTransformation;
00158 else
00159 {
00160 cout << "ERROR: the field gTXX (ground truth) is required" << endl;
00161 abort();
00162 }
00163
00164 PM::Parameters params;
00165
00166
00167 newCloud = removeScanner->filter(newCloud);
00168
00169
00170
00171 newCloud = randSubsample->filter(newCloud);
00172
00173
00174 newCloud = normalFilter->filter(newCloud);
00175 newCloud = orientNormalFilter->filter(newCloud);
00176 newCloud = shadowFilter->filter(newCloud);
00177
00178
00179 transformations.apply(newCloud, T);
00180
00181 if(i==0)
00182 {
00183 mapCloud = newCloud;
00184 }
00185 else
00186 {
00187 mapCloud.concatenate(newCloud);
00188
00189
00190 double probToKeep = totalPointCount/(double)mapCloud.features.cols();
00191 if(probToKeep < 1)
00192 {
00193
00194 mapCloud = densityFilter->filter(mapCloud);
00195 mapCloud = uniformSubsample->filter(mapCloud);
00196
00197 probToKeep = totalPointCount/(double)mapCloud.features.cols();
00198
00199 if(probToKeep < 1)
00200 {
00201 cout << "Randomly keep " << probToKeep*100 << "\% points" << endl;
00202 randSubsample = PM::get().DataPointsFilterRegistrar.create(
00203 "RandomSamplingDataPointsFilter",
00204 map_list_of
00205 ("prob", toParam(probToKeep))
00206 );
00207 mapCloud = randSubsample->filter(mapCloud);
00208 }
00209 }
00210 }
00211
00212 stringstream outputFileNameIter;
00213 outputFileNameIter << boost::filesystem::path(outputFileName).stem() << "_" << i << ".vtk";
00214
00215 cout << "Number of points: " << mapCloud.features.cols() << endl;
00216 mapCloud.save(outputFileNameIter.str());
00217 cout << "OutputFileName: " << outputFileNameIter.str() << endl;
00218 }
00219
00220 mapCloud = densityFilter->filter(mapCloud);
00221 mapCloud = uniformSubsample->filter(mapCloud);
00222
00223 mapCloud = densityFilter->filter(mapCloud);
00224
00225 cout << "Number of points: " << mapCloud.features.cols() << endl;
00226 mapCloud.save(outputFileName);
00227 cout << "OutputFileName: " << outputFileName << endl;
00228
00229 return 0;
00230 }
00231
00232 void validateArgs(int argc, char *argv[])
00233 {
00234 if (!(argc == 4))
00235 {
00236 cerr << "Error in command line, usage " << argv[0] << " listOfFiles.csv maxPoint outputFileName.vtk/.csv" << endl;
00237 abort();
00238 }
00239 }
00240
00241
00242