Skip to content

Commit

Permalink
Merge pull request #24005 from ivashmak:merge_usac_5.x
Browse files Browse the repository at this point in the history
Merge usac to 5.x #24005

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch
- [x] There is a reference to the original bug report and related work
- [x] There is accuracy test, performance test and test data in opencv_extra repository, if applicable
      Patch to opencv_extra has the same branch name.
- [x] The feature is well documented and sample code can be built with the project CMake


Base branch is PR #23979. Merging PR #23078, 23900 and PR #23806  to 5.x
  • Loading branch information
ivashmak committed Jul 27, 2023
1 parent 4d695cd commit 0e87487
Show file tree
Hide file tree
Showing 26 changed files with 4,737 additions and 2,565 deletions.
15 changes: 9 additions & 6 deletions modules/3d/include/opencv2/3d.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,12 +419,13 @@ enum { FM_7POINT = 1, //!< 7-point algorithm
FM_RANSAC = 8 //!< RANSAC algorithm. It needs at least 15 points. 7-point algorithm is used.
};

enum SamplingMethod { SAMPLING_UNIFORM, SAMPLING_PROGRESSIVE_NAPSAC, SAMPLING_NAPSAC,
SAMPLING_PROSAC };
enum LocalOptimMethod {LOCAL_OPTIM_NULL, LOCAL_OPTIM_INNER_LO, LOCAL_OPTIM_INNER_AND_ITER_LO,
LOCAL_OPTIM_GC, LOCAL_OPTIM_SIGMA};
enum ScoreMethod {SCORE_METHOD_RANSAC, SCORE_METHOD_MSAC, SCORE_METHOD_MAGSAC, SCORE_METHOD_LMEDS};
enum NeighborSearchMethod { NEIGH_FLANN_KNN, NEIGH_GRID, NEIGH_FLANN_RADIUS };
enum SamplingMethod { SAMPLING_UNIFORM=0, SAMPLING_PROGRESSIVE_NAPSAC=1, SAMPLING_NAPSAC=2,
SAMPLING_PROSAC=3 };
enum LocalOptimMethod {LOCAL_OPTIM_NULL=0, LOCAL_OPTIM_INNER_LO=1, LOCAL_OPTIM_INNER_AND_ITER_LO=2,
LOCAL_OPTIM_GC=3, LOCAL_OPTIM_SIGMA=4};
enum ScoreMethod {SCORE_METHOD_RANSAC=0, SCORE_METHOD_MSAC=1, SCORE_METHOD_MAGSAC=2, SCORE_METHOD_LMEDS=3};
enum NeighborSearchMethod { NEIGH_FLANN_KNN=0, NEIGH_GRID=1, NEIGH_FLANN_RADIUS=2 };
enum PolishingMethod { NONE_POLISHER=0, LSQ_POLISHER=1, MAGSAC=2, COV_POLISHER=3 };

struct CV_EXPORTS_W_SIMPLE UsacParams
{ // in alphabetical order
Expand All @@ -440,6 +441,8 @@ struct CV_EXPORTS_W_SIMPLE UsacParams
CV_PROP_RW SamplingMethod sampler;
CV_PROP_RW ScoreMethod score;
CV_PROP_RW double threshold;
CV_PROP_RW PolishingMethod final_polisher;
CV_PROP_RW int final_polisher_iterations;
};

/** @brief Converts a rotation matrix to a rotation vector or vice versa.
Expand Down
4 changes: 2 additions & 2 deletions modules/3d/src/five-point.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,9 +504,9 @@ Mat findEssentialMat( InputArray points1, InputArray points2,
InputArray cameraMatrix1, InputArray cameraMatrix2,
InputArray dist_coeff1, InputArray dist_coeff2, OutputArray mask, const UsacParams &params) {
Ptr<usac::Model> model;
usac::setParameters(model, usac::EstimationMethod::Essential, params, mask.needed());
usac::setParameters(model, usac::EstimationMethod::ESSENTIAL, params, mask.needed());
Ptr<usac::RansacOutput> ransac_output;
if (usac::run(model, points1, points2, model->getRandomGeneratorState(),
if (usac::run(model, points1, points2,
ransac_output, cameraMatrix1, cameraMatrix2, dist_coeff1, dist_coeff2)) {
usac::saveMask(mask, ransac_output->getInliersMask());
return ransac_output->getModel();
Expand Down
8 changes: 4 additions & 4 deletions modules/3d/src/fundam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,9 +438,9 @@ Mat findHomography( InputArray _points1, InputArray _points2,
Mat findHomography(InputArray srcPoints, InputArray dstPoints, OutputArray mask,
const UsacParams &params) {
Ptr<usac::Model> model;
usac::setParameters(model, usac::EstimationMethod::Homography, params, mask.needed());
usac::setParameters(model, usac::EstimationMethod::HOMOGRAPHY, params, mask.needed());
Ptr<usac::RansacOutput> ransac_output;
if (usac::run(model, srcPoints, dstPoints, model->getRandomGeneratorState(),
if (usac::run(model, srcPoints, dstPoints,
ransac_output, noArray(), noArray(), noArray(), noArray())) {
usac::saveMask(mask, ransac_output->getInliersMask());
return ransac_output->getModel() / ransac_output->getModel().at<double>(2,2);
Expand Down Expand Up @@ -895,10 +895,10 @@ Mat findFundamentalMat( InputArray points1, InputArray points2, OutputArray mask
Mat findFundamentalMat( InputArray points1, InputArray points2,
OutputArray mask, const UsacParams &params) {
Ptr<usac::Model> model;
setParameters(model, usac::EstimationMethod::Fundamental, params, mask.needed());
setParameters(model, usac::EstimationMethod::FUNDAMENTAL, params, mask.needed());
CV_Assert(model);
Ptr<usac::RansacOutput> ransac_output;
if (usac::run(model, points1, points2, model->getRandomGeneratorState(),
if (usac::run(model, points1, points2,
ransac_output, noArray(), noArray(), noArray(), noArray())) {
usac::saveMask(mask, ransac_output->getInliersMask());
return ransac_output->getModel();
Expand Down
15 changes: 6 additions & 9 deletions modules/3d/src/ptcloud/sac_segmentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ SACSegmentationImpl::segmentSingle(Mat &points, std::vector<bool> &label, Mat &m

// RANSAC
using namespace usac;
int _max_iterations_before_lo = 100, _max_num_hypothesis_to_test_before_rejection = 15;
SamplingMethod _sampling_method = SamplingMethod::SAMPLING_UNIFORM;
LocalOptimMethod _lo_method = LocalOptimMethod::LOCAL_OPTIM_INNER_LO;
ScoreMethod _score_method = ScoreMethod::SCORE_METHOD_RANSAC;
Expand All @@ -70,16 +69,17 @@ SACSegmentationImpl::segmentSingle(Mat &points, std::vector<bool> &label, Mat &m
Ptr <ModelVerifier> verifier;
Ptr <LocalOptimization> lo;
Ptr <Degeneracy> degeneracy;
Ptr <TerminationCriteria> termination;
Ptr <Termination> termination;
Ptr <FinalModelPolisher> polisher;
Ptr <MinimalSolver> min_solver;
Ptr <NonMinimalSolver> non_min_solver;
Ptr <Estimator> estimator;
Ptr <usac::Error> error;

EstimationMethod est_method;
switch (sac_model_type)
{
case SAC_MODEL_PLANE:
est_method = EstimationMethod::PLANE;
min_solver = PlaneModelMinimalSolver::create(points);
non_min_solver = PlaneModelNonMinimalSolver::create(points);
error = PlaneModelError::create(points);
Expand All @@ -90,6 +90,7 @@ SACSegmentationImpl::segmentSingle(Mat &points, std::vector<bool> &label, Mat &m
// error = CylinderModelError::create(points);
// break;
case SAC_MODEL_SPHERE:
est_method = EstimationMethod::SPHERE;
min_solver = SphereModelMinimalSolver::create(points);
non_min_solver = SphereModelNonMinimalSolver::create(points);
error = SphereModelError::create(points);
Expand All @@ -114,7 +115,7 @@ SACSegmentationImpl::segmentSingle(Mat &points, std::vector<bool> &label, Mat &m
estimator = PointCloudModelEstimator::create(min_solver, non_min_solver, constraint_func);
sampler = UniformSampler::create(state++, min_sample_size, points_size);
quality = RansacQuality::create(points_size, _threshold, error);
verifier = ModelVerifier::create();
verifier = ModelVerifier::create(quality);


Ptr <RandomGenerator> lo_sampler = UniformRandomGenerator::create(state++, points_size,
Expand All @@ -128,11 +129,8 @@ SACSegmentationImpl::segmentSingle(Mat &points, std::vector<bool> &label, Mat &m
termination = StandardTerminationCriteria::create
(confidence, points_size, min_sample_size, max_iterations);

Ptr <SimpleUsacConfig> usacConfig = SimpleUsacConfig::create();
Ptr <SimpleUsacConfig> usacConfig = SimpleUsacConfig::create(est_method);
usacConfig->setMaxIterations(max_iterations);
usacConfig->setMaxIterationsBeforeLo(_max_iterations_before_lo);
usacConfig->setMaxNumHypothesisToTestBeforeRejection(
_max_num_hypothesis_to_test_before_rejection);
usacConfig->setRandomGeneratorState(state);
usacConfig->setParallel(is_parallel);
usacConfig->setNeighborsSearchMethod(_neighbors_search_method);
Expand All @@ -146,7 +144,6 @@ SACSegmentationImpl::segmentSingle(Mat &points, std::vector<bool> &label, Mat &m
UniversalRANSAC ransac(usacConfig, points_size, estimator, quality, sampler,
termination, verifier, degeneracy, lo, polisher);
Ptr <usac::RansacOutput> ransac_output;

if (!ransac.run(ransac_output))
{
return 0;
Expand Down
4 changes: 2 additions & 2 deletions modules/3d/src/ptsetreg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1022,9 +1022,9 @@ Mat estimateAffine2D(InputArray _from, InputArray _to, OutputArray _inliers,
Mat estimateAffine2D(InputArray _from, InputArray _to, OutputArray inliers,
const UsacParams &params) {
Ptr<usac::Model> model;
usac::setParameters(model, usac::EstimationMethod::Affine, params, inliers.needed());
usac::setParameters(model, usac::EstimationMethod::AFFINE, params, inliers.needed());
Ptr<usac::RansacOutput> ransac_output;
if (usac::run(model, _from, _to, model->getRandomGeneratorState(),
if (usac::run(model, _from, _to,
ransac_output, noArray(), noArray(), noArray(), noArray())) {
usac::saveMask(inliers, ransac_output->getInliersMask());
return ransac_output->getModel().rowRange(0,2);
Expand Down
17 changes: 1 addition & 16 deletions modules/3d/src/solvepnp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,21 +199,6 @@ class PnPRansacCallback CV_FINAL : public PointSetRegistrator::Callback
Mat tvec;
};

UsacParams::UsacParams()
{
confidence = 0.99;
isParallel = false;
loIterations = 5;
loMethod = LocalOptimMethod::LOCAL_OPTIM_INNER_LO;
loSampleSize = 14;
maxIterations = 5000;
neighborsSearch = NeighborSearchMethod::NEIGH_GRID;
randomGeneratorState = 0;
sampler = SamplingMethod::SAMPLING_UNIFORM;
score = ScoreMethod::SCORE_METHOD_MSAC;
threshold = 1.5;
}

bool solvePnPRansac(InputArray _opoints, InputArray _ipoints,
InputArray _cameraMatrix, InputArray _distCoeffs,
OutputArray _rvec, OutputArray _tvec, bool useExtrinsicGuess,
Expand Down Expand Up @@ -407,7 +392,7 @@ bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints,
usac::setParameters(model_params, cameraMatrix.empty() ? usac::EstimationMethod::P6P :
usac::EstimationMethod::P3P, params, inliers.needed());
Ptr<usac::RansacOutput> ransac_output;
if (usac::run(model_params, imagePoints, objectPoints, model_params->getRandomGeneratorState(),
if (usac::run(model_params, imagePoints, objectPoints,
ransac_output, cameraMatrix, noArray(), distCoeffs, noArray())) {
if (inliers.needed()) {
const auto &inliers_mask = ransac_output->getInliersMask();
Expand Down

0 comments on commit 0e87487

Please sign in to comment.