From edf2cbd5f7d310af9bb2e746caa8402a955b4880 Mon Sep 17 00:00:00 2001 From: armenpoghosov <39712046+armenpoghosov@users.noreply.github.com> Date: Mon, 1 Jul 2019 20:57:28 +0200 Subject: [PATCH] Merge pull request #14828 from armenpoghosov:parmen_RANSACPointSetRegistrator_getSubset_disaster_cleanup Parmen ransac point set registrator get subset disaster cleanup (#14828) --- modules/calib3d/src/ptsetreg.cpp | 73 +++++++++++++++++--------------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/modules/calib3d/src/ptsetreg.cpp b/modules/calib3d/src/ptsetreg.cpp index ae9ac459bc..88e1815c35 100644 --- a/modules/calib3d/src/ptsetreg.cpp +++ b/modules/calib3d/src/ptsetreg.cpp @@ -99,55 +99,60 @@ public: return nz; } - bool getSubset( const Mat& m1, const Mat& m2, - Mat& ms1, Mat& ms2, RNG& rng, - int maxAttempts=1000 ) const + bool getSubset( const Mat& m1, const Mat& m2, Mat& ms1, Mat& ms2, RNG& rng, int maxAttempts=1000 ) const { cv::AutoBuffer _idx(modelPoints); int* idx = _idx.data(); - int i = 0, j, k, iters = 0; - int d1 = m1.channels() > 1 ? m1.channels() : m1.cols; - int d2 = m2.channels() > 1 ? m2.channels() : m2.cols; - int esz1 = (int)m1.elemSize1()*d1, esz2 = (int)m2.elemSize1()*d2; - int count = m1.checkVector(d1), count2 = m2.checkVector(d2); - const int *m1ptr = m1.ptr(), *m2ptr = m2.ptr(); + + const int d1 = m1.channels() > 1 ? m1.channels() : m1.cols; + const int d2 = m2.channels() > 1 ? m2.channels() : m2.cols; + + int esz1 = (int)m1.elemSize1() * d1; + int esz2 = (int)m2.elemSize1() * d2; + CV_Assert((esz1 % sizeof(int)) == 0 && (esz2 % sizeof(int)) == 0); + esz1 /= sizeof(int); + esz2 /= sizeof(int); + + const int count = m1.checkVector(d1); + const int count2 = m2.checkVector(d2); + CV_Assert(count >= modelPoints && count == count2); + + const int *m1ptr = m1.ptr(); + const int *m2ptr = m2.ptr(); ms1.create(modelPoints, 1, CV_MAKETYPE(m1.depth(), d1)); ms2.create(modelPoints, 1, CV_MAKETYPE(m2.depth(), d2)); - int *ms1ptr = ms1.ptr(), *ms2ptr = ms2.ptr(); + int *ms1ptr = ms1.ptr(); + int *ms2ptr = ms2.ptr(); - CV_Assert( count >= modelPoints && count == count2 ); - CV_Assert( (esz1 % sizeof(int)) == 0 && (esz2 % sizeof(int)) == 0 ); - esz1 /= sizeof(int); - esz2 /= sizeof(int); - - for(; iters < maxAttempts; iters++) + for( int iters = 0; iters < maxAttempts; ++iters ) { - for( i = 0; i < modelPoints && iters < maxAttempts; ) + int i; + + for( i = 0; i < modelPoints; ++i ) { - int idx_i = 0; - for(;;) - { - idx_i = idx[i] = rng.uniform(0, count); - for( j = 0; j < i; j++ ) - if( idx_i == idx[j] ) - break; - if( j == i ) - break; - } - for( k = 0; k < esz1; k++ ) + int idx_i; + + for ( idx_i = rng.uniform(0, count); + std::find(idx, idx + i, idx_i) != idx + i; + idx_i = rng.uniform(0, count) ) + {} + + idx[i] = idx_i; + + for( int k = 0; k < esz1; ++k ) ms1ptr[i*esz1 + k] = m1ptr[idx_i*esz1 + k]; - for( k = 0; k < esz2; k++ ) + + for( int k = 0; k < esz2; ++k ) ms2ptr[i*esz2 + k] = m2ptr[idx_i*esz2 + k]; - i++; } - if( i == modelPoints && !cb->checkSubset(ms1, ms2, i) ) - continue; - break; + + if( cb->checkSubset(ms1, ms2, i) ) + return true; } - return i == modelPoints && iters < maxAttempts; + return false; } bool run(InputArray _m1, InputArray _m2, OutputArray _model, OutputArray _mask) const CV_OVERRIDE