27 #include "../common/PlatformUtils.h"
41 #include <boost/math/special_functions/binomial.hpp>
42 #include <boost/random.hpp>
44 #define RANSACGETMAXINVALIDITERATIONS( assurance, dynamicMaxIterations ) \
50 ((long double)dynamicMaxIterations) \
52 ((long double)assurance) \
57 #define RANSACGETMAXITERATIONS( goodTPNumber, totalTPNumber, modelRequiredTPNumber, procsNumber, assurance ) \
63 (long double)( 1.0 - ((long double)assurance) ) \
71 ((long double)goodTPNumber ) \
73 ((long double)totalTPNumber) \
76 ((long double)modelRequiredTPNumber) \
82 ((RansacItCounterT)procsNumber) \
85 #define RANSACSYNCTHREAD \
88 if( bestTransfPtr->initialize( bestParams ) ) \
91 ( paramsPtr->m_bestTransformationPtrPtr->get() == 0 ) \
94 ( bestTiePoins.size() > \
95 (*paramsPtr->m_bestTransformationPtrPtr)->getParameters().m_tiePoints.size() ) \
98 ( bestTiePoins.size() == \
99 (*paramsPtr->m_bestTransformationPtrPtr)->getParameters().m_tiePoints.size() ) \
102 ( bestParamsConvexHullArea > (*paramsPtr->m_bestParamsConvexHullAreaPtr) ) \
105 ( bestParamsConvexHullArea == (*paramsPtr->m_bestParamsConvexHullAreaPtr) ) \
108 ( bestParamsMaxDMapErrorPtr < (*paramsPtr->m_bestParamsMaxDMapErrorPtr) ) \
110 ( bestParamsMaxIMapErrorPtr < (*paramsPtr->m_bestParamsMaxIMapErrorPtr) ) \
118 (*paramsPtr->m_bestTransformationPtrPtr).reset( \
119 bestTransfPtr->clone() ); \
120 (*paramsPtr->m_bestParamsMaxDMapErrorPtr) = bestParamsMaxDMapErrorPtr; \
121 (*paramsPtr->m_bestParamsMaxIMapErrorPtr) = bestParamsMaxIMapErrorPtr; \
122 (*paramsPtr->m_bestParamsConvexHullAreaPtr) = bestParamsConvexHullArea; \
123 (*paramsPtr->m_bestTiePoinsPtr) = bestTiePoins; \
126 if( dynamicMaxIterations < globalDynamicMaxIterations ) \
127 globalDynamicMaxIterations = dynamicMaxIterations; \
201 const double maxDirectMapError,
202 const double maxInverseMapError,
204 const double& assurance,
205 const bool enableMultiThread,
206 const std::vector<double>& tiePointsWeights,
207 std::vector< te::gm::GTParameters::TiePoint >& outTiePoints,
208 std::auto_ptr< GeometricTransformation >& outTransf
211 if(maxDirectMapError < 0)
214 if(maxInverseMapError < 0)
217 if((assurance <= 0.0) || (assurance > 1.0))
220 outTiePoints.clear();
225 std::map< double, GTParameters::TiePoint > tpsMap;
227 const unsigned int inputTPNmb = (
unsigned int)
229 double tiePointsWeightsSum = 0;
231 if( tiePointsWeights.size() > 0 )
233 if( tiePointsWeights.size() != inputParams.
m_tiePoints.size () )
238 unsigned int tpIdx = 0;
240 for( tpIdx = 0 ; tpIdx < inputTPNmb ; ++tpIdx )
242 if( tiePointsWeights[ tpIdx ] < 0.0 )
return false;
244 tiePointsWeightsSum += tiePointsWeights[ tpIdx ];
247 if( tiePointsWeightsSum <= 0.0 )
return false;
251 double newWSum = 0.0;
254 for( tpIdx = 0 ; tpIdx < inputTPNmb ; ++tpIdx )
256 newW = tiePointsWeights[ tpIdx ];
257 newW /= tiePointsWeightsSum;
261 tpsMap[ newWSum ] = inputParams.
m_tiePoints[ tpIdx ];
267 const double increment = 1.0 /
270 for(
unsigned int tpIdx = 0 ; tpIdx < inputTPNmb ; ++tpIdx )
280 std::auto_ptr< GeometricTransformation > bestTransformationPtr(
282 if( bestTransformationPtr.get() == 0 )
return false;
285 boost::mutex syncMutex;
286 double bestParamsMaxDMapError = maxDirectMapError;
287 double bestParamsMaxIMapError = maxInverseMapError;
288 double bestParamsConvexHullArea = -1.0;
289 bool returnValue =
true;
290 bool keepRunningFlag =
true;
297 enableMultiThread ? procsNumber : 1
302 bestTransformationPtr->getMinRequiredTiePoints(),
304 bestTransformationPtr->getMinRequiredTiePoints(),
305 enableMultiThread ? procsNumber : 1,
310 baseThreadParams.m_inputGTParamsPtr = &inputParams;
311 baseThreadParams.m_maxDirectMapError = maxDirectMapError;
312 baseThreadParams.m_maxInverseMapError = maxInverseMapError;
313 baseThreadParams.m_assurance = assurance;
314 baseThreadParams.m_useDynamicIterationsNumber = ( maxIterations == 0 );
315 baseThreadParams.m_dynamicMaxIterationsPtr = &dynamicMaxIterations;
316 baseThreadParams.m_procsNumber = enableMultiThread ?
318 baseThreadParams.m_returnValuePtr = &returnValue;
319 baseThreadParams.m_mutexPtr = &syncMutex;
320 baseThreadParams.m_keepRunningFlagPtr = &keepRunningFlag;
321 baseThreadParams.m_tpsMapPtr = &tpsMap;
322 baseThreadParams.m_bestTransformationPtrPtr = &bestTransformationPtr;
323 baseThreadParams.m_bestParamsMaxDMapErrorPtr = &bestParamsMaxDMapError;
324 baseThreadParams.m_bestParamsMaxIMapErrorPtr = &bestParamsMaxIMapError;
325 baseThreadParams.m_bestParamsConvexHullAreaPtr = &bestParamsConvexHullArea;
326 baseThreadParams.m_bestTiePoinsPtr = &outTiePoints;
330 if( enableMultiThread )
332 std::vector< ApplyRansacThreadEntryThreadParams > threadsParameters;
333 threadsParameters.resize( procsNumber, baseThreadParams );
334 boost::thread_group threads;
336 for(
unsigned int threadIdx = 0 ; threadIdx < procsNumber ;
340 &threadsParameters[ threadIdx ] ) );
352 if( bestTransformationPtr.get() )
354 outTransf.reset( bestTransformationPtr.release() );
376 std::auto_ptr< te::gm::GeometricTransformation > bestTransfPtr(
378 if( bestTransfPtr.get() == 0 )
386 const std::vector< te::gm::GTParameters::TiePoint > tiePoints =
388 std::map< double, GTParameters::TiePoint > tpsMap = *(paramsPtr->
m_tpsMapPtr);
392 boost::random::mt19937 generator( (boost::random::mt19937::result_type)time(0) );
405 boost::mutex& mutex = (*(paramsPtr->
m_mutexPtr));
409 const unsigned int reqTPsNmb = bestTransfPtr->getMinRequiredTiePoints();
410 const unsigned int inputTPNmb = (
unsigned int)tiePoints.size();
412 if( inputTPNmb < reqTPsNmb )
426 double bestParamsConvexHullArea = -1.0;
427 std::vector< te::gm::GTParameters::TiePoint > bestTiePoins;
431 boost::random::uniform_01< double > distribution;
434 std::vector< te::gm::GTParameters::TiePoint > consensusSetTiePoints;
435 consensusSetParams.
m_tiePoints.reserve( tiePoints.size() );
436 double consensusSetMaxDMapError = 0;
437 double consensusSetMaxIMapError = 0;
438 unsigned int consensusSetSize = 0;
439 double consensusSetConvexHullArea = 0.0;
440 std::vector< Coord2D > consensusSetPt1ConvexHullPoits;
442 double tiePointDMapErr = 0;
443 double tiePointIMapErr = 0;
445 std::map< double, GTParameters::TiePoint >::const_iterator tpsMapIt;
446 unsigned int inputTpIdx = 0;
449 std::vector< GTParameters::TiePoint* > selectedTpsPtrsVec;
450 selectedTpsPtrsVec.resize( reqTPsNmb, 0 );
451 unsigned int selectedTpsPtrsVecIdx = 0;
452 bool selectedTpsNotSelectedBefore =
false;
463 double randomValue = 0;
465 while( keepRunningFlag && ( currentIteration < dynamicMaxIterations ) &&
466 ( consecutiveInvalidIterations < dynamicMaxConsecutiveInvalidIterations ) )
472 consensusSetParams.
reset();;
473 selectedTpsCounter = 0;
475 while( selectedTpsCounter < reqTPsNmb )
477 randomValue = distribution( generator );
478 tpsMapIt = tpsMap.upper_bound( randomValue );
479 assert( tpsMapIt != tpsMap.end() );
483 selectedTpsNotSelectedBefore =
true;
485 for( selectedTpsPtrsVecIdx = 0 ; selectedTpsPtrsVecIdx <
486 selectedTpsCounter ; ++selectedTpsPtrsVecIdx )
488 if( selectedTpsPtrsVec[ selectedTpsPtrsVecIdx ] ==
489 &(tpsMapIt->second) )
491 selectedTpsNotSelectedBefore =
false;
496 if( selectedTpsNotSelectedBefore )
498 consensusSetParams.
m_tiePoints.push_back( tpsMapIt->second );
501 ++selectedTpsCounter;
507 if( bestTransfPtr->computeParameters( consensusSetParams ) )
512 consensusSetTiePoints.clear();
513 consensusSetMaxDMapError = 0;
514 consensusSetMaxIMapError = 0;
516 for( inputTpIdx = 0 ; inputTpIdx < inputTPNmb ; ++inputTpIdx )
520 tiePointDMapErr = bestTransfPtr->getDirectMappingError( curTP, consensusSetParams );
521 tiePointIMapErr = bestTransfPtr->getInverseMappingError( curTP, consensusSetParams );
523 if( ( tiePointDMapErr <= maxDirectMapError ) &&
524 ( tiePointIMapErr <= maxInverseMapError ) )
526 consensusSetTiePoints.push_back( curTP );
528 if( tiePointDMapErr > consensusSetMaxDMapError )
529 consensusSetMaxDMapError = tiePointDMapErr;
530 if( tiePointIMapErr > consensusSetMaxIMapError )
531 consensusSetMaxIMapError = tiePointIMapErr;
535 consensusSetSize = (
unsigned int)consensusSetTiePoints.size();
537 consensusSetTiePoints );
542 ( consensusSetSize >= reqTPsNmb )
545 ( consensusSetSize > bestTiePoins.size() )
548 ( consensusSetSize == bestTiePoins.size() )
551 ( consensusSetConvexHullArea > bestParamsConvexHullArea )
554 ( consensusSetConvexHullArea == bestParamsConvexHullArea )
557 ( bestParamsMaxDMapErrorPtr > consensusSetMaxDMapError )
559 ( bestParamsMaxIMapErrorPtr > consensusSetMaxIMapError )
567 bestParams = consensusSetParams;
568 bestParamsMaxDMapErrorPtr = consensusSetMaxDMapError;
569 bestParamsMaxIMapErrorPtr = consensusSetMaxIMapError;
570 bestParamsConvexHullArea = consensusSetConvexHullArea;
571 bestTiePoins = consensusSetTiePoints;
573 consecutiveInvalidIterations = 0;
577 ++consecutiveInvalidIterations;
582 ++consecutiveInvalidIterations;
587 if( useDynamicIterationsNumber && ( currentIteration != 0 ) )
589 if( bestTiePoins.size() == inputTPNmb )
593 keepRunningFlag =
false;
599 else if( ! bestTiePoins.empty() )
608 if( dynamicMaxIterationsEstimation < dynamicMaxIterations )
610 dynamicMaxIterations =
611 ( dynamicMaxIterations - ( ( dynamicMaxIterations - dynamicMaxIterationsEstimation ) / 2 ) );
613 dynamicMaxConsecutiveInvalidIterations =
617 if( globalDynamicMaxIterations < dynamicMaxIterations )
619 dynamicMaxIterations = globalDynamicMaxIterations;
621 dynamicMaxConsecutiveInvalidIterations =
630 ( threadSyncIteration >= threadSyncMaxIterations )
632 ( currentIteration >= dynamicMaxIterations )
634 ( consecutiveInvalidIterations >= dynamicMaxConsecutiveInvalidIterations )
637 threadSyncIteration = 0;
642 ++threadSyncIteration;
653 if( tiePoints.size() < 3 )
661 for(
unsigned int tiePointsIdx = 0 ; tiePointsIdx < tiePoints.size() ;
665 tiePoints[ tiePointsIdx ].first.y ) );
668 std::auto_ptr< te::gm::Surface > convexHullPtr(
671 if( convexHullPtr.get() )
672 return convexHullPtr->getArea();
RansacItCounterT * m_dynamicMaxIterationsPtr
RansacItCounterT m_procsNumber
static void applyRansacThreadEntry(te::gm::GTFilter::ApplyRansacThreadEntryThreadParams *paramsPtr)
Surf locator thread entry.
double m_maxDirectMapError
virtual Geometry * convexHull() const
This method calculates the Convex Hull of a geometry.
#define RANSACGETMAXITERATIONS(goodTPNumber, totalTPNumber, modelRequiredTPNumber, procsNumber, assurance)
unsigned int GetPhysProcNumber()
Returns the number of physical processors.
void reset()
Clear all internal allocated resources and reset the parameters instance to its initial state...
MultiPoint is a GeometryCollection whose elements are restricted to points.
static GeometricTransformation * make(const std::string &factoryKey)
It creates an object with the appropriated factory.
GTParameters const * m_inputGTParamsPtr
const ApplyRansacThreadEntryThreadParams & operator=(const ApplyRansacThreadEntryThreadParams &other)
double * m_bestParamsMaxIMapErrorPtr
Parameters used by the GTFilter::applyRansacThreadEntry method.
void add(Geometry *g)
It adds the geometry into the collection.
std::vector< te::gm::GTParameters::TiePoint > * m_bestTiePoinsPtr
unsigned long long int RansacItCounterT
RANSAC iterations counter type.
double * m_bestParamsConvexHullAreaPtr
double m_maxInverseMapError
std::vector< TiePoint > m_tiePoints
Tie points.
A point with x and y coordinate values.
bool applyRansac(const std::string &transfName, const GTParameters &inputParams, const double maxDirectMapError, const double maxInverseMapError, const RansacItCounterT &maxIterations, const double &assurance, const bool enableMultiThread, const std::vector< double > &tiePointsWeights, std::vector< te::gm::GTParameters::TiePoint > &outTiePoints, std::auto_ptr< GeometricTransformation > &outTransf)
Apply a RANSAC based outliers remotion strategy.
A point with x and y coordinate values.
double * m_bestParamsMaxDMapErrorPtr
std::string const * m_transfNamePtr
ApplyRansacThreadEntryThreadParams()
GTFilter()
Default constructor.
#define RANSACGETMAXINVALIDITERATIONS(assurance, dynamicMaxIterations)
2D Geometric transformation factory.
~ApplyRansacThreadEntryThreadParams()
std::map< double, GTParameters::TiePoint > const * m_tpsMapPtr
A map from accumulated probabilities (normalized between 0 and 1) to tie-points data.
boost::mutex * m_mutexPtr
MultiPoint is a GeometryCollection whose elements are restricted to points.
std::auto_ptr< GeometricTransformation > * m_bestTransformationPtrPtr
2D Geometric transformation parameters.
bool m_useDynamicIterationsNumber
std::pair< Coord2D, Coord2D > TiePoint
Tie point type definition.
static double getPt1ConvexHullArea(const std::vector< GTParameters::TiePoint > &tiePoints)
Returns the tie-points convex hull area (GTParameters::TiePoint::first).
Surface is an abstract class that represents a 2-dimensional geometric objects.
bool * m_keepRunningFlagPtr
Surface is an abstract class that represents a 2-dimensional geometric objects.
2D Geometric transformation outliers remotion filter.