1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
5 #ifndef OPENCV_USAC_USAC_HPP
6 #define OPENCV_USAC_USAC_HPP
8 namespace cv { namespace usac {
9 enum EstimationMethod { Homography, Fundamental, Fundamental8, Essential, Affine, P3P, P6P};
10 enum VerificationMethod { NullVerifier, SprtVerifier };
11 enum PolishingMethod { NonePolisher, LSQPolisher };
12 enum ErrorMetric {DIST_TO_LINE, SAMPSON_ERR, SGD_ERR, SYMM_REPR_ERR, FORW_REPR_ERR, RERPOJ};
14 // Abstract Error class
15 class Error : public Algorithm {
17 // set model to use getError() function
18 virtual void setModelParameters (const Mat &model) = 0;
19 // returns error of point wih @point_idx w.r.t. model
20 virtual float getError (int point_idx) const = 0;
21 virtual const std::vector<float> &getErrors (const Mat &model) = 0;
22 virtual Ptr<Error> clone () const = 0;
25 // Symmetric Reprojection Error for Homography
26 class ReprojectionErrorSymmetric : public Error {
28 static Ptr<ReprojectionErrorSymmetric> create(const Mat &points);
31 // Forward Reprojection Error for Homography
32 class ReprojectionErrorForward : public Error {
34 static Ptr<ReprojectionErrorForward> create(const Mat &points);
37 // Sampson Error for Fundamental matrix
38 class SampsonError : public Error {
40 static Ptr<SampsonError> create(const Mat &points);
43 // Symmetric Geometric Distance (to epipolar lines) for Fundamental and Essential matrix
44 class SymmetricGeometricDistance : public Error {
46 static Ptr<SymmetricGeometricDistance> create(const Mat &points);
49 // Reprojection Error for Projection matrix
50 class ReprojectionErrorPmatrix : public Error {
52 static Ptr<ReprojectionErrorPmatrix> create(const Mat &points);
55 // Reprojection Error for Affine matrix
56 class ReprojectionErrorAffine : public Error {
58 static Ptr<ReprojectionErrorAffine> create(const Mat &points);
61 // Normalizing transformation of data points
62 class NormTransform : public Algorithm {
65 * @norm_points is output matrix of size pts_size x 4
66 * @sample constains indices of points
67 * @sample_number is number of used points in sample <0; sample_number)
68 * @T1, T2 are output transformation matrices
70 virtual void getNormTransformation (Mat &norm_points, const std::vector<int> &sample,
71 int sample_number, Matx33d &T1, Matx33d &T2) const = 0;
72 static Ptr<NormTransform> create (const Mat &points);
75 /////////////////////////////////////////////////////////////////////////////////////////////
76 ////////////////////////////////////////// SOLVER ///////////////////////////////////////////
77 class MinimalSolver : public Algorithm {
79 // Estimate models from minimal sample. models.size() == number of found solutions
80 virtual int estimate (const std::vector<int> &sample, std::vector<Mat> &models) const = 0;
81 // return minimal sample size required for estimation.
82 virtual int getSampleSize() const = 0;
83 // return maximum number of possible solutions.
84 virtual int getMaxNumberOfSolutions () const = 0;
85 virtual Ptr<MinimalSolver> clone () const = 0;
88 //-------------------------- HOMOGRAPHY MATRIX -----------------------
89 class HomographyMinimalSolver4ptsGEM : public MinimalSolver {
91 static Ptr<HomographyMinimalSolver4ptsGEM> create(const Mat &points_);
94 //-------------------------- FUNDAMENTAL MATRIX -----------------------
95 class FundamentalMinimalSolver7pts : public MinimalSolver {
97 static Ptr<FundamentalMinimalSolver7pts> create(const Mat &points_);
100 class FundamentalMinimalSolver8pts : public MinimalSolver {
102 static Ptr<FundamentalMinimalSolver8pts> create(const Mat &points_);
105 //-------------------------- ESSENTIAL MATRIX -----------------------
106 class EssentialMinimalSolverStewenius5pts : public MinimalSolver {
108 static Ptr<EssentialMinimalSolverStewenius5pts> create(const Mat &points_);
111 //-------------------------- PNP -----------------------
112 class PnPMinimalSolver6Pts : public MinimalSolver {
114 static Ptr<PnPMinimalSolver6Pts> create(const Mat &points_);
117 class P3PSolver : public MinimalSolver {
119 static Ptr<P3PSolver> create(const Mat &points_, const Mat &calib_norm_pts, const Mat &K);
122 //-------------------------- AFFINE -----------------------
123 class AffineMinimalSolver : public MinimalSolver {
125 static Ptr<AffineMinimalSolver> create(const Mat &points_);
128 //////////////////////////////////////// NON MINIMAL SOLVER ///////////////////////////////////////
129 class NonMinimalSolver : public Algorithm {
131 // Estimate models from non minimal sample. models.size() == number of found solutions
132 virtual int estimate (const std::vector<int> &sample, int sample_size,
133 std::vector<Mat> &models, const std::vector<double> &weights) const = 0;
134 // return minimal sample size required for non-minimal estimation.
135 virtual int getMinimumRequiredSampleSize() const = 0;
136 // return maximum number of possible solutions.
137 virtual int getMaxNumberOfSolutions () const = 0;
138 virtual Ptr<NonMinimalSolver> clone () const = 0;
141 //-------------------------- HOMOGRAPHY MATRIX -----------------------
142 class HomographyNonMinimalSolver : public NonMinimalSolver {
144 static Ptr<HomographyNonMinimalSolver> create(const Mat &points_);
147 //-------------------------- FUNDAMENTAL MATRIX -----------------------
148 class FundamentalNonMinimalSolver : public NonMinimalSolver {
150 static Ptr<FundamentalNonMinimalSolver> create(const Mat &points_);
153 //-------------------------- ESSENTIAL MATRIX -----------------------
154 class EssentialNonMinimalSolver : public NonMinimalSolver {
156 static Ptr<EssentialNonMinimalSolver> create(const Mat &points_);
159 //-------------------------- PNP -----------------------
160 class PnPNonMinimalSolver : public NonMinimalSolver {
162 static Ptr<PnPNonMinimalSolver> create(const Mat &points);
165 class DLSPnP : public NonMinimalSolver {
167 static Ptr<DLSPnP> create(const Mat &points_, const Mat &calib_norm_pts, const Mat &K);
170 //-------------------------- AFFINE -----------------------
171 class AffineNonMinimalSolver : public NonMinimalSolver {
173 static Ptr<AffineNonMinimalSolver> create(const Mat &points_);
176 //////////////////////////////////////////////////////////////////////////////////////////////
177 ////////////////////////////////////////// SCORE ///////////////////////////////////////////
182 Score () { // set worst case
184 score = std::numeric_limits<double>::max();
186 Score (int inlier_number_, double score_) { // copy constructor
187 inlier_number = inlier_number_;
190 // Compare two scores. Objective is minimization of score. Lower score is better.
191 inline bool isBetter (const Score &score2) const {
192 return score < score2.score;
198 const double max_range_complete /*= 4.62*/, max_range_gamma /*= 1.52*/;
199 const int max_size_table /* = 3000 */;
201 std::vector<double> gamma_complete, gamma_incomplete, gamma;
203 GammaValues(); // use getSingleton()
206 static const GammaValues& getSingleton();
208 const std::vector<double>& getCompleteGammaValues() const;
209 const std::vector<double>& getIncompleteGammaValues() const;
210 const std::vector<double>& getGammaValues() const;
211 double getScaleOfGammaCompleteValues () const;
212 double getScaleOfGammaValues () const;
213 int getTableSize () const;
216 ////////////////////////////////////////// QUALITY ///////////////////////////////////////////
217 class Quality : public Algorithm {
219 virtual ~Quality() override = default;
221 * Calculates number of inliers and score of the @model.
222 * return Score with calculated inlier_number and score.
223 * @model: Mat current model, e.g., H matrix.
225 virtual Score getScore (const Mat &model) const = 0;
226 virtual Score getScore (const std::vector<float> &/*errors*/) const {
227 CV_Error(cv::Error::StsNotImplemented, "getScore(errors)");
229 // get @inliers of the @model. Assume threshold is given
230 // @inliers must be preallocated to maximum points size.
231 virtual int getInliers (const Mat &model, std::vector<int> &inliers) const = 0;
232 // get @inliers of the @model for given threshold
233 virtual int getInliers (const Mat &model, std::vector<int> &inliers, double thr) const = 0;
234 // Set the best score, so evaluation of the model can terminate earlier
235 virtual void setBestScore (double best_score_) = 0;
236 // set @inliers_mask: true if point i is inlier, false - otherwise.
237 virtual int getInliers (const Mat &model, std::vector<bool> &inliers_mask) const = 0;
238 virtual int getPointsSize() const = 0;
239 virtual Ptr<Quality> clone () const = 0;
240 static int getInliers (const Ptr<Error> &error, const Mat &model,
241 std::vector<bool> &inliers_mask, double threshold);
242 static int getInliers (const Ptr<Error> &error, const Mat &model,
243 std::vector<int> &inliers, double threshold);
246 // RANSAC (binary) quality
247 class RansacQuality : public Quality {
249 static Ptr<RansacQuality> create(int points_size_, double threshold_,const Ptr<Error> &error_);
252 // M-estimator quality - truncated Squared error
253 class MsacQuality : public Quality {
255 static Ptr<MsacQuality> create(int points_size_, double threshold_, const Ptr<Error> &error_);
258 // Marginlizing Sample Consensus quality, D. Barath et al.
259 class MagsacQuality : public Quality {
261 static Ptr<MagsacQuality> create(double maximum_thr, int points_size_,const Ptr<Error> &error_,
262 double tentative_inlier_threshold_, int DoF, double sigma_quantile,
263 double upper_incomplete_of_sigma_quantile,
264 double lower_incomplete_of_sigma_quantile, double C_);
267 // Least Median of Squares Quality
268 class LMedsQuality : public Quality {
270 static Ptr<LMedsQuality> create(int points_size_, double threshold_, const Ptr<Error> &error_);
273 //////////////////////////////////////////////////////////////////////////////////////
274 //////////////////////////////////////// DEGENERACY //////////////////////////////////
275 class Degeneracy : public Algorithm {
277 virtual ~Degeneracy() override = default;
279 * Check if sample causes degenerate configurations.
280 * For example, test if points are collinear.
282 virtual bool isSampleGood (const std::vector<int> &/*sample*/) const {
286 * Check if model satisfies constraints.
287 * For example, test if epipolar geometry satisfies oriented constraint.
289 virtual bool isModelValid (const Mat &/*model*/, const std::vector<int> &/*sample*/) const {
293 * Fix degenerate model.
294 * Return true if model is degenerate, false - otherwise
296 virtual bool recoverIfDegenerate (const std::vector<int> &/*sample*/,const Mat &/*best_model*/,
297 Mat &/*non_degenerate_model*/, Score &/*non_degenerate_model_score*/) {
300 virtual Ptr<Degeneracy> clone(int /*state*/) const { return makePtr<Degeneracy>(); }
303 class EpipolarGeometryDegeneracy : public Degeneracy {
305 static void recoverRank (Mat &model, bool is_fundamental_mat);
306 static Ptr<EpipolarGeometryDegeneracy> create (const Mat &points_, int sample_size_);
309 class EssentialDegeneracy : public EpipolarGeometryDegeneracy {
311 static Ptr<EssentialDegeneracy>create (const Mat &points, int sample_size);
314 class HomographyDegeneracy : public Degeneracy {
316 static Ptr<HomographyDegeneracy> create(const Mat &points_);
319 class FundamentalDegeneracy : public EpipolarGeometryDegeneracy {
321 // threshold for homography is squared so is around 2.236 pixels
322 static Ptr<FundamentalDegeneracy> create (int state, const Ptr<Quality> &quality_,
323 const Mat &points_, int sample_size_, double homography_threshold);
326 /////////////////////////////////////////////////////////////////////////////////////
327 //////////////////////////////////////// ESTIMATOR //////////////////////////////////
328 class Estimator : public Algorithm{
331 * Estimate models with minimal solver.
332 * Return number of valid solutions after estimation.
333 * Return models accordingly to number of solutions.
334 * Note, vector of models must allocated before.
335 * Note, not all degenerate tests are included in estimation.
338 estimateModels (const std::vector<int> &sample, std::vector<Mat> &models) const = 0;
340 * Estimate model with non-minimal solver.
341 * Return number of valid solutions after estimation.
342 * Note, not all degenerate tests are included in estimation.
345 estimateModelNonMinimalSample (const std::vector<int> &sample, int sample_size,
346 std::vector<Mat> &models, const std::vector<double> &weights) const = 0;
347 // return minimal sample size required for minimal estimation.
348 virtual int getMinimalSampleSize () const = 0;
349 // return minimal sample size required for non-minimal estimation.
350 virtual int getNonMinimalSampleSize () const = 0;
351 // return maximum number of possible solutions of minimal estimation.
352 virtual int getMaxNumSolutions () const = 0;
353 // return maximum number of possible solutions of non-minimal estimation.
354 virtual int getMaxNumSolutionsNonMinimal () const = 0;
355 virtual Ptr<Estimator> clone() const = 0;
358 class HomographyEstimator : public Estimator {
360 static Ptr<HomographyEstimator> create (const Ptr<MinimalSolver> &min_solver_,
361 const Ptr<NonMinimalSolver> &non_min_solver_, const Ptr<Degeneracy> °eneracy_);
364 class FundamentalEstimator : public Estimator {
366 static Ptr<FundamentalEstimator> create (const Ptr<MinimalSolver> &min_solver_,
367 const Ptr<NonMinimalSolver> &non_min_solver_, const Ptr<Degeneracy> °eneracy_);
370 class EssentialEstimator : public Estimator {
372 static Ptr<EssentialEstimator> create (const Ptr<MinimalSolver> &min_solver_,
373 const Ptr<NonMinimalSolver> &non_min_solver_, const Ptr<Degeneracy> °eneracy_);
376 class AffineEstimator : public Estimator {
378 static Ptr<AffineEstimator> create (const Ptr<MinimalSolver> &min_solver_,
379 const Ptr<NonMinimalSolver> &non_min_solver_);
382 class PnPEstimator : public Estimator {
384 static Ptr<PnPEstimator> create (const Ptr<MinimalSolver> &min_solver_,
385 const Ptr<NonMinimalSolver> &non_min_solver_);
388 //////////////////////////////////////////////////////////////////////////////////////////////
389 ////////////////////////////////////////// MODEL VERIFIER ////////////////////////////////////
390 class ModelVerifier : public Algorithm {
392 virtual ~ModelVerifier() override = default;
393 // Return true if model is good, false - otherwise.
394 virtual bool isModelGood(const Mat &model) = 0;
395 // Return true if score was computed during evaluation.
396 virtual bool getScore(Score &score) const = 0;
397 // update verifier by given inlier number
398 virtual void update (int highest_inlier_number) = 0;
399 virtual const std::vector<float> &getErrors() const = 0;
400 virtual bool hasErrors () const = 0;
401 virtual Ptr<ModelVerifier> clone (int state) const = 0;
402 static Ptr<ModelVerifier> create();
405 struct SPRT_history {
408 * The probability of a data point being consistent
409 * with a ‘bad’ model is modeled as a probability of
410 * a random event with Bernoulli distribution with parameter
414 * The probability p(1|Hg) = ε
415 * that any randomly chosen data point is consistent with a ‘good’ model
416 * is approximated by the fraction of inliers ε among the data
419 * A is the decision threshold, the only parameter of the Adapted SPRT
421 double epsilon, delta, A;
422 // number of samples processed by test
423 int tested_samples; // k
429 ///////////////////////////////// SPRT VERIFIER /////////////////////////////////////////
431 * Matas, Jiri, and Ondrej Chum. "Randomized RANSAC with sequential probability ratio test."
432 * Tenth IEEE International Conference on Computer Vision (ICCV'05) Volume 1. Vol. 2. IEEE, 2005.
434 class SPRT : public ModelVerifier {
436 // return constant reference of vector of SPRT histories for SPRT termination.
437 virtual const std::vector<SPRT_history> &getSPRTvector () const = 0;
438 static Ptr<SPRT> create (int state, const Ptr<Error> &err_, int points_size_,
439 double inlier_threshold_, double prob_pt_of_good_model,
440 double prob_pt_of_bad_model, double time_sample, double avg_num_models,
441 ScoreMethod score_type_);
444 //////////////////////////////////////////////////////////////////////////////////////////
445 ////////////////////////////////////////// SAMPLER ///////////////////////////////////////
446 class Sampler : public Algorithm {
448 virtual ~Sampler() override = default;
449 // set new points size
450 virtual void setNewPointsSize (int points_size) = 0;
451 // generate sample. Fill @sample with indices of points.
452 virtual void generateSample (std::vector<int> &sample) = 0;
453 virtual Ptr<Sampler> clone (int state) const = 0;
456 ////////////////////////////////////////////////////////////////////////////////////////////////
457 /////////////////////////////////// NEIGHBORHOOD GRAPH /////////////////////////////////////////
458 class NeighborhoodGraph : public Algorithm {
460 virtual ~NeighborhoodGraph() override = default;
461 // Return neighbors of the point with index @point_idx_ in the graph.
462 virtual const std::vector<int> &getNeighbors(int point_idx_) const = 0;
465 class RadiusSearchNeighborhoodGraph : public NeighborhoodGraph {
467 static Ptr<RadiusSearchNeighborhoodGraph> create (const Mat &points, int points_size,
468 double radius_, int flann_search_params, int num_kd_trees);
471 class FlannNeighborhoodGraph : public NeighborhoodGraph {
473 static Ptr<FlannNeighborhoodGraph> create(const Mat &points, int points_size,
474 int k_nearest_neighbors_, bool get_distances, int flann_search_params, int num_kd_trees);
475 virtual const std::vector<double> &getNeighborsDistances (int idx) const = 0;
478 class GridNeighborhoodGraph : public NeighborhoodGraph {
480 static Ptr<GridNeighborhoodGraph> create(const Mat &points, int points_size,
481 int cell_size_x_img1_, int cell_size_y_img1_,
482 int cell_size_x_img2_, int cell_size_y_img2_, int max_neighbors);
485 ////////////////////////////////////// UNIFORM SAMPLER ////////////////////////////////////////////
486 class UniformSampler : public Sampler {
488 static Ptr<UniformSampler> create(int state, int sample_size_, int points_size_);
491 /////////////////////////////////// PROSAC (SIMPLE) SAMPLER ///////////////////////////////////////
492 class ProsacSimpleSampler : public Sampler {
494 static Ptr<ProsacSimpleSampler> create(int state, int points_size_, int sample_size_,
495 int max_prosac_samples_count);
498 ////////////////////////////////////// PROSAC SAMPLER ////////////////////////////////////////////
499 class ProsacSampler : public Sampler {
501 static Ptr<ProsacSampler> create(int state, int points_size_, int sample_size_,
502 int growth_max_samples);
503 // return number of samples generated (for prosac termination).
504 virtual int getKthSample () const = 0;
505 // return constant reference of growth function of prosac sampler (for prosac termination)
506 virtual const std::vector<int> &getGrowthFunction () const = 0;
507 virtual void setTerminationLength (int termination_length) = 0;
510 ////////////////////////// NAPSAC (N adjacent points sample consensus) SAMPLER ////////////////////
511 class NapsacSampler : public Sampler {
513 static Ptr<NapsacSampler> create(int state, int points_size_, int sample_size_,
514 const Ptr<NeighborhoodGraph> &neighborhood_graph_);
517 ////////////////////////////////////// P-NAPSAC SAMPLER /////////////////////////////////////////
518 class ProgressiveNapsac : public Sampler {
520 static Ptr<ProgressiveNapsac> create(int state, int points_size_, int sample_size_,
521 const std::vector<Ptr<NeighborhoodGraph>> &layers, int sampler_length);
524 /////////////////////////////////////////////////////////////////////////////////////////////////
525 ///////////////////////////////////////// TERMINATION ///////////////////////////////////////////
526 class TerminationCriteria : public Algorithm {
528 // update termination object by given @model and @inlier number.
529 // and return maximum number of predicted iteration
530 virtual int update(const Mat &model, int inlier_number) = 0;
532 virtual Ptr<TerminationCriteria> clone () const = 0;
535 //////////////////////////////// STANDARD TERMINATION ///////////////////////////////////////////
536 class StandardTerminationCriteria : public TerminationCriteria {
538 static Ptr<StandardTerminationCriteria> create(double confidence, int points_size_,
539 int sample_size_, int max_iterations_);
542 ///////////////////////////////////// SPRT TERMINATION //////////////////////////////////////////
543 class SPRTTermination : public TerminationCriteria {
545 static Ptr<SPRTTermination> create(const std::vector<SPRT_history> &sprt_histories_,
546 double confidence, int points_size_, int sample_size_, int max_iterations_);
549 ///////////////////////////// PROGRESSIVE-NAPSAC-SPRT TERMINATION /////////////////////////////////
550 class SPRTPNapsacTermination : public TerminationCriteria {
552 static Ptr<SPRTPNapsacTermination> create(const std::vector<SPRT_history>&
553 sprt_histories_, double confidence, int points_size_, int sample_size_,
554 int max_iterations_, double relax_coef_);
557 ////////////////////////////////////// PROSAC TERMINATION /////////////////////////////////////////
558 class ProsacTerminationCriteria : public TerminationCriteria {
560 static Ptr<ProsacTerminationCriteria> create(const Ptr<ProsacSampler> &sampler_,
561 const Ptr<Error> &error_, int points_size_, int sample_size, double confidence,
562 int max_iters, int min_termination_length, double beta, double non_randomness_phi,
563 double inlier_thresh);
566 //////////////////////////////////////////////////////////////////////////////////////////////////
567 /////////////////////////////////////////// UTILS ////////////////////////////////////////////////
570 * calibrate points: [x'; 1] = K^-1 [x; 1]
571 * @points is matrix N x 4.
572 * @norm_points is output matrix N x 4 with calibrated points.
574 void calibratePoints (const Mat &K1, const Mat &K2, const Mat &points, Mat &norm_points);
575 void calibrateAndNormalizePointsPnP (const Mat &K, const Mat &pts, Mat &calib_norm_pts);
576 void normalizeAndDecalibPointsPnP (const Mat &K, Mat &pts, Mat &calib_norm_pts);
577 void decomposeProjection (const Mat &P, Mat &K_, Mat &R, Mat &t, bool same_focal=false);
578 double getCalibratedThreshold (double threshold, const Mat &K1, const Mat &K2);
579 float findMedian (std::vector<float> &array);
582 // return skew symmetric matrix
583 Matx33d getSkewSymmetric(const Vec3d &v_);
584 // eliminate matrix with m rows and n columns to be upper triangular.
585 bool eliminateUpperTriangular (std::vector<double> &a, int m, int n);
586 Matx33d rotVec2RotMat (const Vec3d &v);
587 Vec3d rotMat2RotVec (const Matx33d &R);
590 ///////////////////////////////////////// RANDOM GENERATOR /////////////////////////////////////
591 class RandomGenerator : public Algorithm {
593 virtual ~RandomGenerator() override = default;
594 // interval is <0, max_range);
595 virtual void resetGenerator (int max_range) = 0;
596 // return sample filled with random numbers
597 virtual void generateUniqueRandomSet (std::vector<int> &sample) = 0;
598 // fill @sample of size @subset_size with random numbers in range <0, @max_range)
599 virtual void generateUniqueRandomSet (std::vector<int> &sample, int subset_size,
601 // fill @sample of size @sample.size() with random numbers in range <0, @max_range)
602 virtual void generateUniqueRandomSet (std::vector<int> &sample, int max_range) = 0;
603 // return subset=sample size
604 virtual void setSubsetSize (int subset_sz) = 0;
605 virtual int getSubsetSize () const = 0;
606 // return random number from <0, max_range), where max_range is from constructor
607 virtual int getRandomNumber () = 0;
608 // return random number from <0, max_rng)
609 virtual int getRandomNumber (int max_rng) = 0;
610 virtual const std::vector<int> &generateUniqueRandomSubset (std::vector<int> &array1,
612 virtual Ptr<RandomGenerator> clone (int state) const = 0;
615 class UniformRandomGenerator : public RandomGenerator {
617 static Ptr<UniformRandomGenerator> create (int state);
618 static Ptr<UniformRandomGenerator> create (int state, int max_range, int subset_size_);
621 ///////////////////////////////////////////////////////////////////////////////////////////////////
622 ////////////////////////////////////// LOCAL OPTIMIZATION /////////////////////////////////////////
623 class LocalOptimization : public Algorithm {
625 virtual ~LocalOptimization() override = default;
627 * Refine so-far-the-best RANSAC model in local optimization step.
628 * @best_model: so-far-the-best model
629 * @new_model: output refined new model.
630 * @new_model_score: score of @new_model.
631 * Returns bool if model was refined successfully, false - otherwise
633 virtual bool refineModel (const Mat &best_model, const Score &best_model_score,
634 Mat &new_model, Score &new_model_score) = 0;
635 virtual Ptr<LocalOptimization> clone(int state) const = 0;
638 //////////////////////////////////// GRAPH CUT LO ////////////////////////////////////////
639 class GraphCut : public LocalOptimization {
642 create(const Ptr<Estimator> &estimator_, const Ptr<Error> &error_,
643 const Ptr<Quality> &quality_, const Ptr<NeighborhoodGraph> &neighborhood_graph_,
644 const Ptr<RandomGenerator> &lo_sampler_, double threshold_,
645 double spatial_coherence_term, int gc_iters);
648 //////////////////////////////////// INNER + ITERATIVE LO ///////////////////////////////////////
649 class InnerIterativeLocalOptimization : public LocalOptimization {
651 static Ptr<InnerIterativeLocalOptimization>
652 create(const Ptr<Estimator> &estimator_, const Ptr<Quality> &quality_,
653 const Ptr<RandomGenerator> &lo_sampler_, int pts_size, double threshold_,
654 bool is_iterative_, int lo_iter_sample_size_, int lo_inner_iterations,
655 int lo_iter_max_iterations, double threshold_multiplier);
658 class SigmaConsensus : public LocalOptimization {
660 static Ptr<SigmaConsensus>
661 create(const Ptr<Estimator> &estimator_, const Ptr<Error> &error_,
662 const Ptr<Quality> &quality, const Ptr<ModelVerifier> &verifier_,
663 int max_lo_sample_size, int number_of_irwls_iters_,
664 int DoF, double sigma_quantile, double upper_incomplete_of_sigma_quantile,
665 double C_, double maximum_thr);
668 ///////////////////////////////////////////////////////////////////////////////////////////////////
669 /////////////////////////////////////// FINAL MODEL POLISHER //////////////////////////////////////
670 class FinalModelPolisher : public Algorithm {
672 virtual ~FinalModelPolisher() override = default;
674 * Polish so-far-the-best RANSAC model in the end of RANSAC.
675 * @model: input final RANSAC model.
676 * @new_model: output polished model.
677 * @new_score: score of output model.
678 * Return true if polishing was successful, false - otherwise.
680 virtual bool polishSoFarTheBestModel (const Mat &model, const Score &best_model_score,
681 Mat &new_model, Score &new_model_score) = 0;
684 ///////////////////////////////////// LEAST SQUARES POLISHER //////////////////////////////////////
685 class LeastSquaresPolishing : public FinalModelPolisher {
687 static Ptr<LeastSquaresPolishing> create (const Ptr<Estimator> &estimator_,
688 const Ptr<Quality> &quality_, int lsq_iterations);
691 /////////////////////////////////// RANSAC OUTPUT ///////////////////////////////////
692 class RansacOutput : public Algorithm {
694 virtual ~RansacOutput() override = default;
695 static Ptr<RansacOutput> create(const Mat &model_,
696 const std::vector<bool> &inliers_mask_,
697 int time_mcs_, double score_, int number_inliers_, int number_iterations_,
698 int number_estimated_models_, int number_good_models_);
700 // Return inliers' indices. size of vector = number of inliers
701 virtual const std::vector<int > &getInliers() = 0;
702 // Return inliers mask. Vector of points size. 1-inlier, 0-outlier.
703 virtual const std::vector<bool> &getInliersMask() const = 0;
704 virtual int getTimeMicroSeconds() const = 0;
705 virtual int getTimeMicroSeconds1() const = 0;
706 virtual int getTimeMilliSeconds2() const = 0;
707 virtual int getTimeSeconds3() const = 0;
708 virtual int getNumberOfInliers() const = 0;
709 virtual int getNumberOfMainIterations() const = 0;
710 virtual int getNumberOfGoodModels () const = 0;
711 virtual int getNumberOfEstimatedModels () const = 0;
712 virtual const Mat &getModel() const = 0;
715 ////////////////////////////////////////////// MODEL /////////////////////////////////////////////
717 class Model : public Algorithm {
719 virtual bool isFundamental () const = 0;
720 virtual bool isHomography () const = 0;
721 virtual bool isEssential () const = 0;
722 virtual bool isPnP () const = 0;
725 virtual int getSampleSize () const = 0;
726 virtual bool isParallel() const = 0;
727 virtual int getMaxNumHypothesisToTestBeforeRejection() const = 0;
728 virtual PolishingMethod getFinalPolisher () const = 0;
729 virtual LocalOptimMethod getLO () const = 0;
730 virtual ErrorMetric getError () const = 0;
731 virtual EstimationMethod getEstimator () const = 0;
732 virtual ScoreMethod getScore () const = 0;
733 virtual int getMaxIters () const = 0;
734 virtual double getConfidence () const = 0;
735 virtual double getThreshold () const = 0;
736 virtual VerificationMethod getVerifier () const = 0;
737 virtual SamplingMethod getSampler () const = 0;
738 virtual double getTimeForModelEstimation () const = 0;
739 virtual double getSPRTdelta () const = 0;
740 virtual double getSPRTepsilon () const = 0;
741 virtual double getSPRTavgNumModels () const = 0;
742 virtual NeighborSearchMethod getNeighborsSearch () const = 0;
743 virtual int getKNN () const = 0;
744 virtual int getCellSize () const = 0;
745 virtual int getGraphRadius() const = 0;
746 virtual double getRelaxCoef () const = 0;
748 virtual int getFinalLSQIterations () const = 0;
749 virtual int getDegreesOfFreedom () const = 0;
750 virtual double getSigmaQuantile () const = 0;
751 virtual double getUpperIncompleteOfSigmaQuantile () const = 0;
752 virtual double getLowerIncompleteOfSigmaQuantile () const = 0;
753 virtual double getC () const = 0;
754 virtual double getMaximumThreshold () const = 0;
755 virtual double getGraphCutSpatialCoherenceTerm () const = 0;
756 virtual int getLOSampleSize () const = 0;
757 virtual int getLOThresholdMultiplier() const = 0;
758 virtual int getLOIterativeSampleSize() const = 0;
759 virtual int getLOIterativeMaxIters() const = 0;
760 virtual int getLOInnerMaxIters() const = 0;
761 virtual const std::vector<int> &getGridCellNumber () const = 0;
762 virtual int getRandomGeneratorState () const = 0;
763 virtual int getMaxItersBeforeLO () const = 0;
766 virtual void setLocalOptimization (LocalOptimMethod lo_) = 0;
767 virtual void setKNearestNeighhbors (int knn_) = 0;
768 virtual void setNeighborsType (NeighborSearchMethod neighbors) = 0;
769 virtual void setCellSize (int cell_size_) = 0;
770 virtual void setParallel (bool is_parallel) = 0;
771 virtual void setVerifier (VerificationMethod verifier_) = 0;
772 virtual void setPolisher (PolishingMethod polisher_) = 0;
773 virtual void setError (ErrorMetric error_) = 0;
774 virtual void setLOIterations (int iters) = 0;
775 virtual void setLOIterativeIters (int iters) = 0;
776 virtual void setLOSampleSize (int lo_sample_size) = 0;
777 virtual void setThresholdMultiplierLO (double thr_mult) = 0;
778 virtual void setRandomGeneratorState (int state) = 0;
780 virtual void maskRequired (bool required) = 0;
781 virtual bool isMaskRequired () const = 0;
782 static Ptr<Model> create(double threshold_, EstimationMethod estimator_, SamplingMethod sampler_,
783 double confidence_=0.95, int max_iterations_=5000, ScoreMethod score_ =ScoreMethod::SCORE_METHOD_MSAC);
786 Mat findHomography(InputArray srcPoints, InputArray dstPoints, int method,
787 double ransacReprojThreshold, OutputArray mask,
788 const int maxIters, const double confidence);
790 Mat findFundamentalMat( InputArray points1, InputArray points2,
791 int method, double ransacReprojThreshold, double confidence,
792 int maxIters, OutputArray mask=noArray());
794 bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints,
795 InputArray cameraMatrix, InputArray distCoeffs,
796 OutputArray rvec, OutputArray tvec,
797 bool useExtrinsicGuess, int iterationsCount,
798 float reprojectionError, double confidence,
799 OutputArray inliers, int flags);
801 Mat findEssentialMat( InputArray points1, InputArray points2,
802 InputArray cameraMatrix1,
803 int method, double prob,
804 double threshold, OutputArray mask);
806 Mat estimateAffine2D(InputArray from, InputArray to, OutputArray inliers,
807 int method, double ransacReprojThreshold, int maxIters,
808 double confidence, int refineIters);
810 void saveMask (OutputArray mask, const std::vector<bool> &inliers_mask);
811 void setParameters (Ptr<Model> ¶ms, EstimationMethod estimator, const UsacParams &usac_params,
813 bool run (const Ptr<const Model> ¶ms, InputArray points1, InputArray points2, int state,
814 Ptr<RansacOutput> &ransac_output, InputArray K1_, InputArray K2_,
815 InputArray dist_coeff1, InputArray dist_coeff2);
818 #endif //OPENCV_USAC_USAC_HPP