From 6d738f6a3f3248859339164a748ad98f8abd5a93 Mon Sep 17 00:00:00 2001 From: jmbuena Date: Fri, 11 Jan 2013 01:55:56 +0100 Subject: [PATCH 1/2] Changed RANSAC Homography estimation for speed. Each minimal set is checked for consistency before actually fit a candidate homography. --- modules/calib3d/src/_modelest.h | 1 + modules/calib3d/src/fundam.cpp | 80 ++++++++++++++++++++++++++++++++ modules/calib3d/src/modelest.cpp | 12 +++++ 3 files changed, 93 insertions(+) diff --git a/modules/calib3d/src/_modelest.h b/modules/calib3d/src/_modelest.h index b86485e491..9ce737194f 100644 --- a/modules/calib3d/src/_modelest.h +++ b/modules/calib3d/src/_modelest.h @@ -69,6 +69,7 @@ protected: virtual bool getSubset( const CvMat* m1, const CvMat* m2, CvMat* ms1, CvMat* ms2, int maxAttempts=1000 ); virtual bool checkSubset( const CvMat* ms1, int count ); + virtual bool isMinimalSetConsistent( const CvMat* m1, const CvMat* m2 ) { return true; }; CvRNG rng; int modelPoints; diff --git a/modules/calib3d/src/fundam.cpp b/modules/calib3d/src/fundam.cpp index a823c4cdd6..b2272df13a 100644 --- a/modules/calib3d/src/fundam.cpp +++ b/modules/calib3d/src/fundam.cpp @@ -68,6 +68,7 @@ public: protected: virtual void computeReprojError( const CvMat* m1, const CvMat* m2, const CvMat* model, CvMat* error ); + virtual bool isMinimalSetConsistent( const CvMat* m1, const CvMat* m2 ); }; @@ -287,6 +288,85 @@ cvFindHomography( const CvMat* objectPoints, const CvMat* imagePoints, return (int)result; } +// We check whether three correspondences for the homography estimation +// are geometrically consistent (the points in the source image should +// maintain the same circular order than in the destination image). +// +// The usefullness of this constraint is explained in the paper: +// +// "Speeding-up homography estimation in mobile devices" +// Journal of Real-Time Image Processing. 2013. DOI: 10.1007/s11554-012-0314-1 +// Pablo Marquez-Neila, Javier Lopez-Alberca, Jose M. Buenaposada, Luis Baumela +CV_IMPL bool +weakConstraint + ( + const CvMat* srcPoints, + const CvMat* dstPoints, + int t1, + int t2, + int t3 + ) +{ + const CvPoint2D64f* src = (const CvPoint2D64f*)srcPoints->data.ptr; + const CvPoint2D64f* dst = (const CvPoint2D64f*)dstPoints->data.ptr; + + CvMat* A = cvCreateMat( 3, 3, CV_64F ); + CvMat* B = cvCreateMat( 3, 3, CV_64F ); + + double detA; + double detB; + + cvmSet(A, 0, 0, src[t1].x); + cvmSet(A, 0, 1, src[t1].y); + cvmSet(A, 0, 2, 1); + cvmSet(A, 1, 0, src[t2].x); + cvmSet(A, 1, 1, src[t2].y); + cvmSet(A, 1, 2, 1); + cvmSet(A, 2, 0, src[t3].x); + cvmSet(A, 2, 1, src[t3].y); + cvmSet(A, 2, 2, 1); + + cvmSet(B, 0, 0, dst[t1].x); + cvmSet(B, 0, 1, dst[t1].y); + cvmSet(B, 0, 2, 1); + cvmSet(B, 1, 0, dst[t2].x); + cvmSet(B, 1, 1, dst[t2].y); + cvmSet(B, 1, 2, 1); + cvmSet(B, 2, 0, dst[t3].x); + cvmSet(B, 2, 1, dst[t3].y); + cvmSet(B, 2, 2, 1); + + detA = cvDet(A); + detB = cvDet(B); + + cvReleaseMat(&A); + cvReleaseMat(&B); + + return (detA*detB >= 0); +}; + +// We check whether the minimal set of points for the homography estimation +// are geometrically consistent. We check if every 3 correspondences sets +// fulfills the constraint. +// +// The usefullness of this constraint is explained in the paper: +// +// "Speeding-up homography estimation in mobile devices" +// Journal of Real-Time Image Processing. 2013. DOI: 10.1007/s11554-012-0314-1 +// Pablo Marquez-Neila, Javier Lopez-Alberca, Jose M. Buenaposada, Luis Baumela +bool +CvHomographyEstimator::isMinimalSetConsistent + ( + const CvMat* srcPoints, + const CvMat* dstPoints + ) +{ + return weakConstraint(srcPoints, dstPoints, 0, 1, 2) && + weakConstraint(srcPoints, dstPoints, 1, 2, 3) && + weakConstraint(srcPoints, dstPoints, 0, 2, 3) && + weakConstraint(srcPoints, dstPoints, 0, 1, 3); +} + /* Evaluation of Fundamental Matrix from point correspondences. The original code has been written by Valery Mosyagin */ diff --git a/modules/calib3d/src/modelest.cpp b/modules/calib3d/src/modelest.cpp index b6441e22cb..4aec4b6c53 100644 --- a/modules/calib3d/src/modelest.cpp +++ b/modules/calib3d/src/modelest.cpp @@ -152,6 +152,18 @@ bool CvModelEstimator2::runRANSAC( const CvMat* m1, const CvMat* m2, CvMat* mode return false; break; } + + // Here we check for model specific geometrical + // constraints that allow to avoid "runKernel" + // and not checking for inliers if not fulfilled. + // + // The usefullness of this constraint for homographies is explained in the paper: + // + // "Speeding-up homography estimation in mobile devices" + // Journal of Real-Time Image Processing. 2013. DOI: 10.1007/s11554-012-0314-1 + // Pablo Márquez-Neila, Javier López-Alberca, José M. Buenaposada, Luis Baumela + if ( !isMinimalSetConsistent( ms1, ms2 ) ) + continue; } nmodels = runKernel( ms1, ms2, models ); From 28a7be69ea770808ecca078aa2a9baabcc596062 Mon Sep 17 00:00:00 2001 From: jmbuena Date: Sat, 12 Jan 2013 12:32:51 +0100 Subject: [PATCH 2/2] Fixed compile warnings on CvHomographyEstimator --- modules/calib3d/src/_modelest.h | 2 +- modules/calib3d/src/fundam.cpp | 18 ++++-------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/modules/calib3d/src/_modelest.h b/modules/calib3d/src/_modelest.h index 9ce737194f..2a94add861 100644 --- a/modules/calib3d/src/_modelest.h +++ b/modules/calib3d/src/_modelest.h @@ -69,7 +69,7 @@ protected: virtual bool getSubset( const CvMat* m1, const CvMat* m2, CvMat* ms1, CvMat* ms2, int maxAttempts=1000 ); virtual bool checkSubset( const CvMat* ms1, int count ); - virtual bool isMinimalSetConsistent( const CvMat* m1, const CvMat* m2 ) { return true; }; + virtual bool isMinimalSetConsistent( const CvMat* /*m1*/, const CvMat* /*m2*/ ) { return true; }; CvRNG rng; int modelPoints; diff --git a/modules/calib3d/src/fundam.cpp b/modules/calib3d/src/fundam.cpp index b2272df13a..f15dac1f9d 100644 --- a/modules/calib3d/src/fundam.cpp +++ b/modules/calib3d/src/fundam.cpp @@ -69,6 +69,7 @@ protected: virtual void computeReprojError( const CvMat* m1, const CvMat* m2, const CvMat* model, CvMat* error ); virtual bool isMinimalSetConsistent( const CvMat* m1, const CvMat* m2 ); + virtual bool weakConstraint ( const CvMat* srcPoints, const CvMat* dstPoints, int t1, int t2, int t3 ); }; @@ -297,15 +298,8 @@ cvFindHomography( const CvMat* objectPoints, const CvMat* imagePoints, // "Speeding-up homography estimation in mobile devices" // Journal of Real-Time Image Processing. 2013. DOI: 10.1007/s11554-012-0314-1 // Pablo Marquez-Neila, Javier Lopez-Alberca, Jose M. Buenaposada, Luis Baumela -CV_IMPL bool -weakConstraint - ( - const CvMat* srcPoints, - const CvMat* dstPoints, - int t1, - int t2, - int t3 - ) +bool +CvHomographyEstimator::weakConstraint ( const CvMat* srcPoints, const CvMat* dstPoints, int t1, int t2, int t3 ) { const CvPoint2D64f* src = (const CvPoint2D64f*)srcPoints->data.ptr; const CvPoint2D64f* dst = (const CvPoint2D64f*)dstPoints->data.ptr; @@ -355,11 +349,7 @@ weakConstraint // Journal of Real-Time Image Processing. 2013. DOI: 10.1007/s11554-012-0314-1 // Pablo Marquez-Neila, Javier Lopez-Alberca, Jose M. Buenaposada, Luis Baumela bool -CvHomographyEstimator::isMinimalSetConsistent - ( - const CvMat* srcPoints, - const CvMat* dstPoints - ) +CvHomographyEstimator::isMinimalSetConsistent ( const CvMat* srcPoints, const CvMat* dstPoints ) { return weakConstraint(srcPoints, dstPoints, 0, 1, 2) && weakConstraint(srcPoints, dstPoints, 1, 2, 3) &&