build_map.cpp
Go to the documentation of this file.
00001 // kate: replace-tabs off; indent-width 4; indent-mode normal
00002 // vim: ts=4:sw=4:noexpandtab
00003 /*
00004 
00005 Copyright (c) 2010--2012,
00006 François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland
00007 You can contact the authors at <f dot pomerleau at gmail dot com> and
00008 <stephane at magnenat dot net>
00009 
00010 All rights reserved.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014     * Redistributions of source code must retain the above copyright
00015       notice, this list of conditions and the following disclaimer.
00016     * Redistributions in binary form must reproduce the above copyright
00017       notice, this list of conditions and the following disclaimer in the
00018       documentation and/or other materials provided with the distribution.
00019     * Neither the name of the <organization> nor the
00020       names of its contributors may be used to endorse or promote products
00021       derived from this software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00026 DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY
00027 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00029 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00030 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00031 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00032 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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         // Process arguments
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         // Define transformation chain
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         // Define filters for later use
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                 // Remove the scanner
00167                 newCloud = removeScanner->filter(newCloud);
00168 
00169 
00170                 // Accelerate the process and dissolve lines
00171                 newCloud = randSubsample->filter(newCloud);
00172                 
00173                 // Build filter to remove shadow points and down-sample
00174                 newCloud = normalFilter->filter(newCloud);
00175                 newCloud = orientNormalFilter->filter(newCloud);
00176                 newCloud = shadowFilter->filter(newCloud);
00177 
00178                 // Transforme pointCloud
00179                 transformations.apply(newCloud, T);
00180 
00181                 if(i==0)
00182                 {
00183                         mapCloud = newCloud;
00184                 }
00185                 else
00186                 {
00187                         mapCloud.concatenate(newCloud);
00188                         
00189                         // Control point cloud size
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 


upstream_src
Author(s):
autogenerated on Mon Oct 6 2014 10:27:39