21 #ifndef __PreemptiveRANSAC_hh__
22 #define __PreemptiveRANSAC_hh__
24 #include <bias_config.h>
25 #include <Base/Common/BIASpragmaStart.hh>
27 #include <Base/Debug/Debug.hh>
28 #include <Base/Math/Random.hh>
29 #include <MathAlgo/Median1D.hh>
30 #include <MathAlgo/RANSACEvaluatorInterface.hh>
38 # define NAN sqrt(-1.0)
41 #define PRANSAC_NO_SOLUTION -5
42 #define PRANSAC_SUBOPTIMAL_PARAMETERS -4
43 #define PRANSAC_INVALID_PARAMETERS -3
44 #define PRANSAC_NOTE_ENOUGH_SAMPLES -2
45 #define PRANSAC_NO_SOLUTION_LEFT -1
47 #define PRANSAC_NOT_ENOUGH_INLIERS 1
48 #define PRANSAC_SCORE_TOO_BIG 2
84 template <
class SolutionType>
100 int SolveMaster(
const double inlying_data_fraction,
const double max_score,
101 SolutionType &solution, std::vector<bool> &inliers,
102 unsigned &num_inliers,
double& score,
103 const bool auto_compute_max_samples =
false);
192 const unsigned sample_size,
193 const unsigned data_size);
200 const unsigned num_checked);
203 const unsigned data_size);
208 inline bool IsInlier_(
typename std::list<SolStruct>::iterator solution,
209 const unsigned data_index,
double& score);
211 int GetSolution_(
const unsigned min_num_inliers,
const double max_score,
212 SolutionType& solution, std::vector<bool>& inliers,
213 unsigned& num_inliers,
double & score)
const;
215 inline void ConvertInliers_(
const std::vector<bool>& inliers_in_eval_order,
216 std::vector<bool>& inliers)
const;
220 const double max_score)
const
223 unsigned max_inliers = 0;
224 double min_score = std::numeric_limits<double>::max();
225 typename std::list<SolStruct>::const_iterator it;
227 BCDOUT(D_PRANSAC_GetSolution,
"solution: "<<it->solution<<std::endl);
228 if (it->num_inliers>max_inliers){
229 max_inliers = it->num_inliers;
230 min_score = it->score;
231 BCDOUT(D_PRANSAC_GetSolution,
" is best (num inliers "<<max_inliers
232 <<
", score "<<min_score<<
")"<<std::endl);
235 BCDOUT(D_PRANSAC_GetSolution,
" (num inliers "<<max_inliers
236 <<
", score "<<min_score<<
")"<<std::endl);
238 if (it->num_inliers==max_inliers && it->score < min_score){
239 min_score = it->score;
241 BCDOUT(D_PRANSAC_GetSolution,
" new best score "<<min_score
249 const struct SolStruct *
251 const double max_score)
const
254 double min_score = std::numeric_limits<double>::max();
255 typename std::list<SolStruct>::const_iterator it;
257 BCDOUT(D_PRANSAC_GetSolution,
"solution: "<<it->solution
259 if (it->score < min_score){
260 min_score = it->score;
262 BCDOUT(D_PRANSAC_GetSolution,
" is best (min_score "<<min_score
263 <<
" / num inliers: "<<it->num_inliers<<
" )"<<std::endl);
265 BCDOUT(D_PRANSAC_GetSolution,
" score: "<<it->score
266 <<
" / num inliers: "<<it->num_inliers<<std::endl);
276 template <
class SolutionType>
279 : _RANSACEvaluator(shi), _uiSampleSize(0u), _uiMinSamples(50),
281 _uiDataSize(0), _bGreedy(true), _uiNumInitialChecked(8),
282 _uiMinNumInitialInliers(1),
283 _bRefineSolutions(true), _uiEvaluationBlockSize(50),
287 BEXCEPTION(
"PreemptiveRANSAC::PreemptiveRANSAC(): Invalid "
288 <<
"(null) argument.");
302 template <
class SolutionType>
306 BIASASSERT(_RANSACEvaluator);
307 _uiDataSize = _RANSACEvaluator->GetNumMeasurements();
309 _EvaluationOrder.clear();
310 GenerateEvaluationOrder_(_uiDataSize);
311 _bInitialised =
true;
315 template <
class SolutionType>
319 BIASASSERT(_uiDataSize!=0);
320 typename std::vector<SolutionType>::const_iterator it;
322 for (it=guesses.begin(); it!=guesses.end(); it++){
327 st.
inliers.resize(_uiDataSize);
329 _Solutions.push_back(st);
334 template <
class SolutionType>
336 SolveMaster(
const double inlying_data_fraction,
const double max_score,
337 SolutionType &solution, std::vector<bool> &inliers,
338 unsigned &num_inliers,
double& score,
339 const bool auto_compute_max_samples)
341 BIASASSERT(_RANSACEvaluator);
343 BIASERR(
"PreemptiveRANSAC::SolveMaster(): Call Init() before calling "
346 BIASASSERT(_bInitialised);
347 _bInitialised =
false;
349 unsigned oldMinSamples = _uiMinSamples;
350 if (auto_compute_max_samples){
352 const double prob_of_good_solution = 0.9999;
354 (unsigned)ceil(log(1.0-prob_of_good_solution)/
355 log(1.0-pow(inlying_data_fraction,
356 (
double)(_uiSampleSize))));
357 if (_uiMinSamples>_uiMaxSamples){
358 _uiMinSamples = _uiMaxSamples;
362 if (_uiDataSize<_uiSampleSize){
364 return PRANSAC_NOTE_ENOUGH_SAMPLES;
366 const int min_num_inliers =
367 (int)rint(inlying_data_fraction * (
double)_uiDataSize);
368 BIASASSERT(_uiDataSize!=0);
369 BIASASSERT(_uiMaxSamples>=_uiMinSamples);
370 const unsigned num_blocks = _uiMaxSamples / _uiMinSamples;
372 unsigned oldNumInitialChecked = _uiNumInitialChecked;
373 unsigned oldMinNumInitialInliers = _uiMinNumInitialInliers;
374 if (_uiDataSize<_uiNumInitialChecked){
375 std::cerr <<
"Only "<<_uiDataSize<<
" measurements are available, but the "
376 <<
"initial check has been requested for "<<_uiNumInitialChecked
377 <<
" measurements. Checking all "<<_uiDataSize
378 <<
" available measurememts\n" ;
379 _uiNumInitialChecked = _uiDataSize;
380 unsigned num_initial_expected_inliers =
381 (unsigned)floor(inlying_data_fraction * (
double) _uiNumInitialChecked);
382 if (_uiMinNumInitialInliers>=num_initial_expected_inliers){
383 _uiMinNumInitialInliers = num_initial_expected_inliers;
384 if (_uiMinNumInitialInliers>0){
385 _uiMinNumInitialInliers--;
389 unsigned num_initial_expected_inliers =
390 (unsigned)floor(inlying_data_fraction * (
double) _uiNumInitialChecked);
391 if (_uiMinNumInitialInliers>num_initial_expected_inliers){
392 std::cerr <<
"the parameters inyling_data_fraction ("
393 <<inlying_data_fraction<<
") and the ratio of "
394 <<
"MinNumInitialInliers / NumInitialChecked ("
395 <<(double)_uiMinNumInitialInliers/(
double)_uiNumInitialChecked
396 <<
") are not consistent. The latter must be smaller than the "
398 return PRANSAC_INVALID_PARAMETERS;
401 unsigned num_generated_solutions = 0;
402 unsigned num_initially_rejected_solutions = 0;
403 for (
unsigned block=0; block<num_blocks; block++){
404 BCDOUT(D_PRANSAC_SolveMaster,
"\n########## block "<<block<<
" #######\n");
406 num_generated_solutions +=
407 GenerateSolutions_(block, _uiSampleSize, _uiDataSize);
408 BCDOUT(D_PRANSAC_SolveMaster,
"initially generated "<<_Solutions.size()
411 num_initially_rejected_solutions +=
412 InitialRejectTcd_(_uiMinNumInitialInliers, _uiNumInitialChecked);
413 BCDOUT(D_PRANSAC_SolveMaster, _Solutions.size()<<
" solutions remained "
414 "after initial rejection\n");
415 if (_Solutions.empty())
continue;
417 EvaluateSolutions_(_uiNumInitialChecked, _uiDataSize);
418 BCDOUT(D_PRANSAC_SolveMaster, _Solutions.size()<<
" solutions remained "
419 "after evaluation of unrefined solutions\n");
420 if (_Solutions.empty())
continue;
423 if (_bRefineSolutions && !_Solutions.empty()){
424 int num_refined = GenerateRefinedSolutions_(_uiDataSize);
426 BCDOUT(D_PRANSAC_SolveMaster, _Solutions.size()<<
" solutions "
427 "after adding refinements\n");
430 InitialRejectTcd_(_uiMinNumInitialInliers, _uiNumInitialChecked);
431 BCDOUT(D_PRANSAC_SolveMaster, _Solutions.size()<<
" solutions "
432 "after initial rejection of refinements\n");
433 if (_Solutions.empty())
continue;
435 if (num_rejected!=num_refined){
436 EvaluateSolutions_(_uiNumInitialChecked, _uiDataSize);
437 BCDOUT(D_PRANSAC_SolveMaster, _Solutions.size()<<
" solutions "
438 "after evaluation of refinements\n");
439 if (_Solutions.empty())
continue;
441 BCDOUT(D_PRANSAC_SolveMaster,
"no refined solution passed the "
445 BCDOUT(D_PRANSAC_SolveMaster,
"no refined solutions\n");
449 int solution_res = GetSolution_(min_num_inliers, max_score,
450 solution, inliers, num_inliers, score);
451 if (_bGreedy && solution_res==PRANSAC_OK){
452 BCDOUT(D_PRANSAC_SolveMaster,
"solution found!\n");
454 _uiNumInitialChecked = oldNumInitialChecked;
455 _uiMinNumInitialInliers = oldMinNumInitialInliers;
456 _uiMinSamples = oldMinSamples;
462 _uiNumInitialChecked = oldNumInitialChecked;
463 _uiMinNumInitialInliers = oldMinNumInitialInliers;
464 _uiMinSamples = oldMinSamples;
466 const double initially_rejected_solutions_ratio =
467 (double)(num_initially_rejected_solutions) /
468 (double)(num_generated_solutions);
469 const double max_initially_rejected_solution_ratio = 0.95;
470 if (initially_rejected_solutions_ratio >
471 max_initially_rejected_solution_ratio){
472 BIASERR(
"More than "<<max_initially_rejected_solution_ratio*100
473 <<
"% of the solutions have been rejected by the Tcd test "
474 <<
"(c="<<_uiMinNumInitialInliers<<
", d="
475 <<_uiNumInitialChecked<<
").\n");
477 static int num_retries = 0;
478 const unsigned reasonable_min_num_initial_checked = 5;
479 const unsigned reasonable_min_num_initial_inliers = 2;
480 if ( _uiMinNumInitialInliers <= reasonable_min_num_initial_inliers &&
481 _uiNumInitialChecked >= reasonable_min_num_initial_checked){
482 BIASERR(
"Retrying with different evaluation order\n");
483 if (num_retries < 1 ){
485 GenerateEvaluationOrder_(_uiDataSize);
486 SolveMaster(inlying_data_fraction, max_score, solution,
487 inliers, num_inliers, score, auto_compute_max_samples);
490 BIASERR(
"Rerunning PreemptiveRANSAC with more reasonable parameters "
491 <<
"for \"NumInitialChecked\" (is "<<_uiNumInitialChecked
492 <<
", should be at least "<<reasonable_min_num_initial_checked
493 <<
") and \"MinNumInitialInliers\" (is "
494 <<_uiMinNumInitialInliers <<
" an should be at most "
495 <<reasonable_min_num_initial_inliers
496 <<
") could be successfull.");
497 return PRANSAC_SUBOPTIMAL_PARAMETERS;
502 int solution_res = GetSolution_(min_num_inliers, max_score,
503 solution, inliers, num_inliers, score);
504 if (solution_res==PRANSAC_OK){
505 BCDOUT(D_PRANSAC_SolveMaster,
"solution found!\n");
507 }
else if (solution_res>0){
508 BCDOUT(D_PRANSAC_SolveMaster,
"solution found, but minimum quality "
509 <<
"criteria not matched! Best score "<<score<<
" (expected max "
510 <<max_score<<
") / num inliers "<<num_inliers<<
" (expected min "
511 <<min_num_inliers<<
")\n");
512 BIASERR(
"solution found, but minimum quality "
513 <<
"criteria not matched! Best score "<<score<<
" (expected max "
514 <<max_score<<
") / num inliers "<<num_inliers<<
" (expected min "
515 <<min_num_inliers<<
")");
520 BIASERR(
"PreemptiveRANSAC found no solution");
521 return PRANSAC_NO_SOLUTION;
524 template <
class SolutionType>
528 _EvaluationOrder.clear();
529 const unsigned ds = data_size;
530 std::list<unsigned> mlist;
531 for (
unsigned i=0; i<ds; i++)
535 typename std::list<unsigned>::iterator it;
536 BCDOUT(D_PRANSAC_EvalOrder,
"evaluation order: ");
537 for (
unsigned i=0; i<ds; i++){
538 index = randomizer_.GetUniformDistributedInt(0u, ds-i-1);
539 BIASASSERT(index>=0 && index<ds-i);
541 for (
unsigned k=0; k<index; k++) it++;
542 _EvaluationOrder.push_back(*it);
543 BCDOUT(D_PRANSAC_EvalOrder, _EvaluationOrder.back()<<
" ");
546 BCDOUT(D_PRANSAC_EvalOrder, std::endl);
550 template <
class SolutionType>
553 const unsigned data_size)
555 const unsigned max_sample = (block_num+1)*_uiMinSamples;
556 std::vector<unsigned> which_samples;
557 std::vector<SolutionType> solutions;
558 typename std::vector<SolutionType>::const_iterator it;
561 if (block_num == 0) sample_offset = 0;
562 const int max_tries = 25;
564 int num_solutions = 0;
565 BIASASSERT(_RANSACEvaluator);
566 BCDOUT(D_PRANSAC_GenerateSolutions,
"generating "<<block_num
567 <<
"-th block with "<<_uiMinSamples <<
" solutions\n");
568 for (
unsigned sample=block_num * _uiMinSamples;
569 sample<max_sample; sample++){
572 if (_RANSACEvaluator->GenerateSamples(sample+sample_offset, sample_size,
573 data_size, which_samples)) {
574 num = _RANSACEvaluator->GetSampleSolutions(which_samples, solutions);
575 BCDOUT(D_PRANSAC_GenerateSolutions,
"samples: ");
576 for (
unsigned i=0; i<which_samples.size(); i++){
577 BCDOUT(D_PRANSAC_GenerateSolutions, which_samples[i]<<
" ");
579 BCDOUT(D_PRANSAC_GenerateSolutions,
" resulted in "
580 <<solutions.size()<<
" solutions\n");
581 for (it=solutions.begin(); it!=solutions.end(); it++){
588 _Solutions.push_back(st);
592 BIASERR(
"sample generation failed!");
599 }
while (num==0 && tries<max_tries);
601 BCDOUT(D_PRANSAC_GenerateSolutions,
"generated "<<block_num
602 <<
"-th block containing "<<num_solutions<<
" solutions\n");
603 return num_solutions;
606 template <
class SolutionType>
610 typename std::list<SolStruct>::iterator it;
613 std::vector<bool> inliers;
615 BIASASSERT(_RANSACEvaluator);
616 for (it=_Solutions.begin(); it!=_Solutions.end(); it++){
618 BIASASSERT(it->eval_index == data_size);
619 ConvertInliers_(it->inliers, inliers);
621 if (_RANSACEvaluator->RefineSolution(inliers, st.
solution)){
626 _Solutions.push_back(st);
634 template <
class SolutionType>
637 const unsigned num_checked)
639 BIASASSERT(min_num_inliers<=num_checked);
640 typename std::list<SolStruct>::iterator it;
643 int num_rejected = 0;
644 BCDOUT(D_PRANSAC_InitialReject,
"initial reject, checking samples: ");
645 for (data=0; data<num_checked; data++){
646 BCDOUT(D_PRANSAC_InitialReject, _EvaluationOrder[data]<<
" ");
648 BCDOUT(D_PRANSAC_InitialReject, std::endl);
650 for (it=_Solutions.begin(); it!=_Solutions.end();){
651 if (it->eval_index>num_checked) { it++;
continue; }
652 BCDOUT(D_PRANSAC_InitialReject,
" (");
653 for (data=0; data<num_checked; data++){
654 IsInlier_(it, data, score);
655 BCDOUT(D_PRANSAC_InitialReject, ((it->inliers[data])?(
"+"):(
"-")));
657 if (it->num_inliers<min_num_inliers){
658 it = _Solutions.erase(it);
660 BCDOUT(D_PRANSAC_InitialReject,
")*");
663 BCDOUT(D_PRANSAC_InitialReject,
").");
666 BCDOUT(D_PRANSAC_InitialReject,
"\n");
667 if (_Solutions.empty()){
668 std::cout <<
"initially checked "<<num_checked
669 <<
" samples and expected at least "<<min_num_inliers
670 <<
" inliers. No solutions remaining.\n";
675 template <
class SolutionType>
677 IsInlier_(
typename std::list<SolStruct>::iterator solution,
678 const unsigned eval_index,
double& score)
680 BCDOUT(D_PRANSAC_Inlier,
"eval_index: "<<eval_index<<
" ");
681 BCDOUT(D_PRANSAC_Inlier,
"solution->eval_index: "<<solution->eval_index);
682 if (solution->eval_index<=eval_index){
685 BIASASSERT(solution->eval_index==eval_index);
686 BIASASSERT(solution->inliers.size()>eval_index);
687 BIASASSERT(_EvaluationOrder.size()>eval_index);
688 BCDOUT(D_PRANSAC_Inlier,
" (new score) "<<std::endl);
689 BCDOUT(D_PRANSAC_Inlier,
"_EvaluationOrder[eval_index] = "
690 <<_EvaluationOrder[eval_index]<<std::endl);
691 BIASASSERT(_RANSACEvaluator);
692 solution->inliers[eval_index] =
693 _RANSACEvaluator->IsInlier(solution->solution,
694 _EvaluationOrder[eval_index], score);
696 if (solution->inliers[eval_index]){
697 solution->score += score;
698 solution->num_inliers++;
700 solution->eval_index++;
702 BCDOUT(D_PRANSAC_Inlier,
" (already scored) "<<std::endl);
705 BCDOUT(D_PRANSAC_Inlier,
"inlier: "<<std::boolalpha
706 <<solution->inliers[eval_index]<<std::endl);
707 return solution->inliers[eval_index];
711 template <
class SolutionType>
715 if (start_index>=data_size){
718 typename std::list<SolStruct>::iterator it;
720 for (
unsigned data=start_index; data<data_size; data++){
721 for (it=_Solutions.begin(); it!=_Solutions.end(); it++){
722 if (it->eval_index>data) {
continue; }
723 IsInlier_(it, data, score);
725 if ( ( ((
int)data+1-(
int)start_index) % (
int)_uiEvaluationBlockSize)
727 BCDOUT(D_PRANSAC_Evaluate,
"--- eval "<<data<<
" ---\n");
728 RejectSolutions_(data);
733 template <
class SolutionType>
738 std::vector<double> scores;
739 typename std::list<SolStruct>::iterator it;
740 for (it=_Solutions.begin(); it!=_Solutions.end(); it++){
741 if (it->eval_index>eval_index+1) {
continue; }
742 scores.push_back(it->score);
744 if (scores.empty()) {
745 BCDOUT(D_PRANSAC_Evaluate,
"no solutions left to evaluate\n");
751 BCDOUT(D_PRANSAC_Evaluate,
"score threshold = "<<thresh<<std::endl);
753 for (it=_Solutions.begin(); it!=_Solutions.end();){
754 if (it->score > thresh){
755 it = _Solutions.erase(it);
756 BCDOUT(D_PRANSAC_Evaluate,
"*");
760 BCDOUT(D_PRANSAC_Evaluate,
".");
763 BCDOUT(D_PRANSAC_Evaluate, std::endl);
764 BCDOUT(D_PRANSAC_Evaluate, _Solutions.size()<<
" solutions remaining\n");
770 template <
class SolutionType>
773 SolutionType& solution, std::vector<bool>& inliers,
774 unsigned& num_inliers,
double & score)
const
776 if (_Solutions.empty()) {
777 return PRANSAC_NO_SOLUTION_LEFT;
781 GetSolutionMinScore_(min_num_inliers, max_score);
785 score = best_sol->
score;
788 BCDOUT(D_PRANSAC_GetSolution,
"\nbest solution is: "
789 <<solution<<
" score: "<<score<<
" / num inliers: "
790 <<num_inliers<<std::endl);
791 ConvertInliers_(best_sol->
inliers, inliers);
792 bool enough_inliers = (best_sol->
num_inliers >= min_num_inliers);
793 bool score_smaller_than_max_score = (best_sol->
score <= max_score);
794 if (enough_inliers && score_smaller_than_max_score){
795 BCDOUT(D_PRANSAC_GetSolution,
"num_inliers: "<<num_inliers
796 <<
"\nscore: "<<score<<
"\n");
800 BCDOUT(D_PRANSAC_GetSolution,
"minimum quality criteria not met "
801 "(max_score: "<<max_score<<
" / min inliers "<<min_num_inliers
803 if (!enough_inliers){
804 BCDOUT(D_PRANSAC_GetSolution,
"not enough inliers "
805 <<
"(found: "<<best_sol->
num_inliers<<
" / expected: "
806 <<min_num_inliers<<
")\n");
807 res = res | PRANSAC_NOT_ENOUGH_INLIERS;
809 if (!score_smaller_than_max_score){
810 BCDOUT(D_PRANSAC_GetSolution,
"score too big "
811 <<
"(found: "<<best_sol->
score<<
" / expected: "
813 res = res | PRANSAC_SCORE_TOO_BIG;
818 BIASERR(
"no best solution returned");
822 return PRANSAC_NO_SOLUTION_LEFT;
826 template <
class SolutionType>
829 std::vector<bool>& inliers)
const
832 inliers.resize(inliers_in_eval_order.size());
833 const unsigned data_size = (unsigned)inliers.size();
834 BIASASSERT(data_size == _EvaluationOrder.size());
835 for (
unsigned i=0; i<data_size; i++){
836 BIASASSERT(_EvaluationOrder[i]<data_size);
837 inliers[_EvaluationOrder[i]] = inliers_in_eval_order[i];
842 #endif // __PreemptiveRANSAC_hh__
bool _bInitialised
just to check if the class is used correctly
void GenerateEvaluationOrder_(const unsigned data_size)
Interface for computation of solutions and evaluation of measurements.
void SetMinSamples(const unsigned min_samples)
Set min number of samples.
unsigned _uiMinNumInitialInliers
the minimum number of inlier from _uiNumInitialChecked
void AddSolutionGuesses(const std::vector< SolutionType > &guesses)
struct SolStruct * GetSolutionMaxInliers_(const unsigned min_num_inliers, const double max_score) const
void SetEvaluationBlockSize(const unsigned eval_block_size)
after each EvaluationBlockSize-th measurement, the solutions are compared and only the better half is...
BIAS::Random randomizer_
randomizer instance used for evaluation order computation
unsigned _uiNumInitialChecked
the number of datat points that is initially checked
RANSACEvaluatorInterface< SolutionType > * _RANSACEvaluator
the helper class for solution computation and sample evaluation
std::vector< bool > inliers
inlier indicator for the data in the order given by _EvaluationOrder i.e.
struct SolStruct * GetSolutionMinScore_(const unsigned min_num_inliers, const double max_score) const
void SetMinNumInitialInliers(const unsigned min_num_initial_inl)
when less than MinNumInitialInliers are found, the solution is rejected straight away ...
unsigned eval_index
evaluation of the solution has taken place up to eval_index
void SetNumInitialChecked(const unsigned num_initial_checked)
the number of measurements that is initially evaluated
bool refined
has a refined version of this solution lareday be added?
void EvaluateSolutions_(const unsigned start_index, const unsigned data_size)
void SetMaxSamples(const unsigned max_samples)
Set max number of samples.
int GenerateSolutions_(const unsigned block_num, const unsigned sample_size, const unsigned data_size)
returns the number of generated solution
bool IsInlier_(typename std::list< SolStruct >::iterator solution, const unsigned data_index, double &score)
bool _bGreedy
should termination be aborted when first good solution is found?
void ConvertInliers_(const std::vector< bool > &inliers_in_eval_order, std::vector< bool > &inliers) const
void SetRefineSolutions(const bool refine_solutions)
long int NewDebugLevel(const std::string &name)
creates a new debuglevel
unsigned _uiEvaluationBlockSize
after EvaluationBlockSize, bad solutions are removed
unsigned _uiSampleSize
the number of samples needed by GetSampleSolutions
int InitialRejectTcd_(const unsigned min_num_inliers, const unsigned num_checked)
returns the number of rejected solutions
int GetSolution_(const unsigned min_num_inliers, const double max_score, SolutionType &solution, std::vector< bool > &inliers, unsigned &num_inliers, double &score) const
std::list< SolStruct > _Solutions
all (remaining) solutions
int SolveMaster(const double inlying_data_fraction, const double max_score, SolutionType &solution, std::vector< bool > &inliers, unsigned &num_inliers, double &score, const bool auto_compute_max_samples=false)
std::vector< unsigned > _EvaluationOrder
the order in which data is used for solutions evaluation
virtual ~PreemptiveRANSAC()
int sample_offset
prevents that calls to GenerateSample_() generate the same random sample if sample solution creation ...
int RejectSolutions_(const unsigned eval_index)
returns the number of rejected solutions
Fast RANSAC after David Nister, "Preemptive RANSAC for Live Structure And Motion Estimation", Internation Conference on Computer Vision (ICCV) 2003.
int GenerateRefinedSolutions_(const unsigned data_size)
returns the number of succesfully refined solutions
unsigned _uiDataSize
the number of data for evaluation
class for producing random numbers from different distributions
PreemptiveRANSAC(RANSACEvaluatorInterface< SolutionType > *shi)
unsigned _uiMinSamples
the minimu and maximum number of samples investigated
bool _bRefineSolutions
should the solutions be refined?
void SetGreedy(const bool greedy)