icp_customized.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 <cassert>
00038 #include <iostream>
00039 #include "boost/filesystem.hpp"
00040 
00041 using namespace std;
00042 
00043 void validateArgs(int argc, char *argv[], bool& isCSV);
00044 
00054 int main(int argc, char *argv[])
00055 {
00056         bool isCSV = true;
00057         validateArgs(argc, argv, isCSV);
00058         
00059         typedef PointMatcher<float> PM;
00060         typedef PM::DataPoints DP;
00061 
00062         // Load point clouds
00063         const DP ref(DP::load(argv[1]));
00064         const DP data(DP::load(argv[2]));
00065 
00066         // Create the default ICP algorithm
00067         PM::ICP icp;
00068         PointMatcherSupport::Parametrizable::Parameters params;
00069         std::string name;
00070         
00071         // Uncomment for console outputs
00072         setLogger(PM::get().LoggerRegistrar.create("FileLogger"));
00073 
00074         // Prepare reading filters
00075         name = "MinDistDataPointsFilter";
00076         params["minDist"] = "1.0";
00077         std::shared_ptr<PM::DataPointsFilter> minDist_read =
00078                 PM::get().DataPointsFilterRegistrar.create(name, params);
00079         params.clear();
00080 
00081         name = "RandomSamplingDataPointsFilter";
00082         params["prob"] = "0.05";
00083         std::shared_ptr<PM::DataPointsFilter> rand_read =
00084                 PM::get().DataPointsFilterRegistrar.create(name, params);
00085         params.clear();
00086 
00087         // Prepare reference filters
00088         name = "MinDistDataPointsFilter";
00089         params["minDist"] = "1.0";
00090         std::shared_ptr<PM::DataPointsFilter> minDist_ref =
00091                 PM::get().DataPointsFilterRegistrar.create(name, params);
00092         params.clear();
00093 
00094         name = "RandomSamplingDataPointsFilter";
00095         params["prob"] = "0.05";
00096         std::shared_ptr<PM::DataPointsFilter> rand_ref =
00097                 PM::get().DataPointsFilterRegistrar.create(name, params);
00098         params.clear();
00099 
00100         // Prepare matching function
00101         name = "KDTreeMatcher";
00102         params["knn"] = "1";
00103         params["epsilon"] = "3.16";
00104         std::shared_ptr<PM::Matcher> kdtree =
00105                 PM::get().MatcherRegistrar.create(name, params);
00106         params.clear();
00107 
00108         // Prepare outlier filters
00109         name = "TrimmedDistOutlierFilter";
00110         params["ratio"] = "0.75";
00111         std::shared_ptr<PM::OutlierFilter> trim =
00112                 PM::get().OutlierFilterRegistrar.create(name, params);
00113         params.clear();
00114 
00115         // Prepare error minimization
00116         name = "PointToPointErrorMinimizer";
00117         std::shared_ptr<PM::ErrorMinimizer> pointToPoint =
00118                 PM::get().ErrorMinimizerRegistrar.create(name);
00119 
00120         // Prepare transformation checker filters
00121         name = "CounterTransformationChecker";
00122         params["maxIterationCount"] = "150";
00123         std::shared_ptr<PM::TransformationChecker> maxIter =
00124                 PM::get().TransformationCheckerRegistrar.create(name, params);
00125         params.clear();
00126 
00127         name = "DifferentialTransformationChecker";
00128         params["minDiffRotErr"] = "0.001";
00129         params["minDiffTransErr"] = "0.01";
00130         params["smoothLength"] = "4";
00131         std::shared_ptr<PM::TransformationChecker> diff =
00132                 PM::get().TransformationCheckerRegistrar.create(name, params);
00133         params.clear();
00134 
00135         // Prepare inspector
00136         std::shared_ptr<PM::Inspector> nullInspect =
00137                 PM::get().InspectorRegistrar.create("NullInspector");
00138 
00139         //name = "VTKFileInspector";
00140     //  params["dumpDataLinks"] = "1"; 
00141     //  params["dumpReading"] = "1"; 
00142     //  params["dumpReference"] = "1"; 
00143 
00144         //PM::Inspector* vtkInspect =
00145         //      PM::get().InspectorRegistrar.create(name, params);
00146         params.clear();
00147         
00148         // Prepare transformation
00149         std::shared_ptr<PM::Transformation> rigidTrans =
00150                 PM::get().TransformationRegistrar.create("RigidTransformation");
00151         
00152         // Build ICP solution
00153         icp.readingDataPointsFilters.push_back(minDist_read);
00154         icp.readingDataPointsFilters.push_back(rand_read);
00155 
00156         icp.referenceDataPointsFilters.push_back(minDist_ref);
00157         icp.referenceDataPointsFilters.push_back(rand_ref);
00158 
00159         icp.matcher = kdtree;
00160         
00161         icp.outlierFilters.push_back(trim);
00162         
00163         icp.errorMinimizer = pointToPoint;
00164 
00165         icp.transformationCheckers.push_back(maxIter);
00166         icp.transformationCheckers.push_back(diff);
00167         
00168         // toggle to write vtk files per iteration
00169         icp.inspector = nullInspect;
00170         //icp.inspector = vtkInspect;
00171 
00172         icp.transformations.push_back(rigidTrans);
00173 
00174         // Compute the transformation to express data in ref
00175         PM::TransformationParameters T = icp(data, ref);
00176 
00177         // Transform data to express it in ref
00178         DP data_out(data);
00179         icp.transformations.apply(data_out, T);
00180         
00181         // Safe files to see the results
00182         ref.save("test_ref.vtk");
00183         data.save("test_data_in.vtk");
00184         data_out.save("test_data_out.vtk");
00185         cout << "Final transformation:" << endl << T << endl;
00186 
00187         return 0;
00188 }
00189 
00190 void validateArgs(int argc, char *argv[], bool& isCSV )
00191 {
00192         if (argc != 3)
00193         {
00194                 cerr << "Wrong number of arguments, usage " << argv[0] << " reference.csv reading.csv" << endl;
00195                 cerr << "Will create 3 vtk files for inspection: ./test_ref.vtk, ./test_data_in.vtk and ./test_data_out.vtk" << endl;
00196                 cerr << endl << "2D Example:" << endl;
00197                 cerr << "  " << argv[0] << " ../../examples/data/2D_twoBoxes.csv ../../examples/data/2D_oneBox.csv" << endl;
00198                 cerr << endl << "3D Example:" << endl;
00199                 cerr << "  " << argv[0] << " ../../examples/data/car_cloud400.csv ../../examples/data/car_cloud401.csv" << endl;
00200                 exit(1);
00201         }
00202 }


libpointmatcher
Author(s):
autogenerated on Thu Jun 20 2019 19:51:31