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.h" 00037 #include "PointMatcherPrivate.h" 00038 00039 #ifdef SYSTEM_YAML_CPP 00040 #include "yaml-cpp/yaml.h" 00041 #else 00042 #include "yaml-cpp-pm/yaml.h" 00043 namespace YAML = YAML_PM; 00044 #endif // HAVE_YAML_CPP 00045 00047 template<typename T> 00048 PointMatcher<T>::DataPointsFilter::DataPointsFilter() 00049 {} 00050 00052 template<typename T> 00053 PointMatcher<T>::DataPointsFilter::DataPointsFilter(const std::string& className, const ParametersDoc paramsDoc, const Parameters& params): 00054 Parametrizable(className,paramsDoc,params) 00055 {} 00056 00058 template<typename T> 00059 PointMatcher<T>::DataPointsFilter::~DataPointsFilter() 00060 {} 00061 00063 template<typename T> 00064 void PointMatcher<T>::DataPointsFilter::init() 00065 {} 00066 00067 template struct PointMatcher<float>::DataPointsFilter; 00068 template struct PointMatcher<double>::DataPointsFilter; 00069 00070 00072 template<typename T> 00073 PointMatcher<T>::DataPointsFilters::DataPointsFilters() 00074 {} 00075 00077 template<typename T> 00078 PointMatcher<T>::DataPointsFilters::DataPointsFilters(std::istream& in) 00079 { 00080 YAML::Parser parser(in); 00081 YAML::Node doc; 00082 parser.GetNextDocument(doc); 00083 00084 // Fix for issue #6: compilation on gcc 4.4.4 00085 //PointMatcher<T> pm; 00086 const PointMatcher & pm = PointMatcher::get(); 00087 00088 for(YAML::Iterator moduleIt = doc.begin(); moduleIt != doc.end(); ++moduleIt) 00089 { 00090 const YAML::Node& module(*moduleIt); 00091 this->push_back(pm.REG(DataPointsFilter).createFromYAML(module)); 00092 } 00093 } 00094 00096 template<typename T> 00097 void PointMatcher<T>::DataPointsFilters::init() 00098 { 00099 for (DataPointsFiltersIt it = this->begin(); it != this->end(); ++it) 00100 { 00101 (*it)->init(); 00102 } 00103 } 00104 00106 template<typename T> 00107 void PointMatcher<T>::DataPointsFilters::apply(DataPoints& cloud) 00108 { 00109 if (this->empty()) 00110 return; 00111 00112 cloud.assertDescriptorConsistency(); 00113 const int nbPointsBeforeFilters(cloud.features.cols()); 00114 LOG_INFO_STREAM("Applying " << this->size() << " DataPoints filters - " << nbPointsBeforeFilters << " points in"); 00115 for (DataPointsFiltersIt it = this->begin(); it != this->end(); ++it) 00116 { 00117 const int nbPointsIn(cloud.features.cols()); 00118 if (nbPointsIn == 0) { 00119 throw ConvergenceError("no points to filter"); 00120 } 00121 00122 (*it)->inPlaceFilter(cloud); 00123 cloud.assertDescriptorConsistency(); 00124 00125 const int nbPointsOut(cloud.features.cols()); 00126 LOG_INFO_STREAM("* " << (*it)->className << " - " << nbPointsOut << " points out (-" << (100 - double(nbPointsOut*100.)/nbPointsIn) << "\%)"); 00127 } 00128 00129 const int nbPointsAfterFilters(cloud.features.cols()); 00130 LOG_INFO_STREAM("Applied " << this->size() << " filters - " << nbPointsAfterFilters << " points out (-" << (100 - double(nbPointsAfterFilters*100.)/nbPointsBeforeFilters) << "\%)"); 00131 } 00132 00133 template struct PointMatcher<float>::DataPointsFilters; 00134 template struct PointMatcher<double>::DataPointsFilters;