/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2013 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLMath/src/ICLMath/RansacFitter.h ** ** Module : ICLMath ** ** Authors: Christof Elbrechter ** ** ** ** ** ** GNU LESSER GENERAL PUBLIC LICENSE ** ** This file may be used under the terms of the GNU Lesser General ** ** Public License version 3.0 as published by the ** ** ** ** Free Software Foundation and appearing in the file LICENSE.LGPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the license requirements will ** ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** ********************************************************************/ #pragma once #include #include #include #include #include #include namespace icl{ namespace math{ /// Generic RANSAC (RAndom SAmpling Consensus) Implementation /** The RansacFitter provides a generic framework, for RANSAC based model fitting. \section ALG RANSAC Algorithm The RANSAC Algorithm is well described on Wikipedia @see http://de.wikipedia.org/wiki/RANSAC-Algorithmus \section EX Example An example is given in the ICL Manual \section TEM Template Parameters The two tempalte parameters are kept very general. Therefore, there are just a few restrictions for the DataPoint and Model classes. - default constructable - copyable */ template, class Model=std::vector > class RansacFitter{ public: /// DataSet type (just a set of DataPoint instances) typedef std::vector DataSet; /// Function for the fitting module (gets a dataset and returns the fitted model) typedef utils::Function ModelFitting; /// Error function for single points typedef utils::Function PointError; private: /// minimum points that are used to create a coarse model int m_minPointsForModel; /// number of iterations int m_iterations; /// maximum distance of a point to the model to become an inlier icl64f m_maxModelDistance; /// minimum amount of inliers for a 'good' model int m_minClosePointsForGoodModel; /// fitting function ModelFitting m_fitting; /// point-model error function PointError m_err; /// min error criterion for early exit icl64f m_minErrorExit; public: /// result structure struct Result{ /// reached error icl64f error; /// model (zero sized if no model was found) Model model; /// consensus set of best match (i.e. inliers) /** empty if no model was found */ DataSet consensusSet; /// number of iterations needed int iterationCount; /// returns whether any model was found bool found() const { return consensusSet.size(); } }; private: /// internal result buffer Result m_result; /// internal utility method static inline bool find_in(const std::vector &v, int i, int n){ return std::find(v.data(), v.data()+n, i) != v.data()+n; } /// internal utility method void find_random_consensus_set(DataSet &currConsensusSet, const DataSet &allPoints, std::vector &usedIndices){ utils::get_random_subset(allPoints, (int) currConsensusSet.size(), currConsensusSet, usedIndices); /*const std::vector &s, int subsetSize, std::vector &subset, std::vector &indices) const int n = currConsensusSet.size(); utils::URandI r(allPoints.size()-1); for(int i=0;i consensusSet(m_minPointsForModel); std::vector usedIndices(m_minPointsForModel); int i = 0; for(i=0;i= m_minClosePointsForGoodModel){ model = m_fitting(consensusSet); double error = 0; for(unsigned int j=0;j