|
|
|
@ -47,6 +47,18 @@ |
|
|
|
|
namespace cv |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This class estimates a homography \f$H\in \mathbb{R}^{3\times 3}\f$ |
|
|
|
|
* between \f$\mathbf{x} \in \mathbb{R}^3\f$ and |
|
|
|
|
* \f$\mathbf{X} \in \mathbb{R}^3\f$ using DLT (direct linear transform) |
|
|
|
|
* with algebraic distance. |
|
|
|
|
* |
|
|
|
|
* \f[ |
|
|
|
|
* \lambda \mathbf{x} = H \mathbf{X} |
|
|
|
|
* \f] |
|
|
|
|
* where \f$\lambda \in \mathbb{R} \f$. |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
class HomographyEstimatorCallback : public PointSetRegistrator::Callback |
|
|
|
|
{ |
|
|
|
|
public: |
|
|
|
@ -87,6 +99,20 @@ public: |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Normalization method: |
|
|
|
|
* - $x$ and $y$ coordinates are normalized independently |
|
|
|
|
* - first the coordinates are shifted so that the average coordinate is \f$(0,0)\f$ |
|
|
|
|
* - then the coordinates are scaled so that the average L1 norm is 1, i.e, |
|
|
|
|
* the average L1 norm of the \f$x\f$ coordinates is 1 and the average |
|
|
|
|
* L1 norm of the \f$y\f$ coordinates is also 1. |
|
|
|
|
* |
|
|
|
|
* @param _m1 source points containing (X,Y), depth is CV_32F with 1 column 2 channels or |
|
|
|
|
* 2 columns 1 channel |
|
|
|
|
* @param _m2 destination points containing (x,y), depth is CV_32F with 1 column 2 channels or |
|
|
|
|
* 2 columns 1 channel |
|
|
|
|
* @param _model, CV_64FC1, 3x3, normalized, i.e., the last element is 1 |
|
|
|
|
*/ |
|
|
|
|
int runKernel( InputArray _m1, InputArray _m2, OutputArray _model ) const |
|
|
|
|
{ |
|
|
|
|
Mat m1 = _m1.getMat(), m2 = _m2.getMat(); |
|
|
|
@ -154,6 +180,14 @@ public: |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Compute the reprojection error. |
|
|
|
|
* m2 = H*m1 |
|
|
|
|
* @param _m1 depth CV_32F, 1-channel with 2 columns or 2-channel with 1 column |
|
|
|
|
* @param _m2 depth CV_32F, 1-channel with 2 columns or 2-channel with 1 column |
|
|
|
|
* @param _model CV_64FC1, 3x3 |
|
|
|
|
* @param _err, output, CV_32FC1, square of the L2 norm |
|
|
|
|
*/ |
|
|
|
|
void computeError( InputArray _m1, InputArray _m2, InputArray _model, OutputArray _err ) const |
|
|
|
|
{ |
|
|
|
|
Mat m1 = _m1.getMat(), m2 = _m2.getMat(), model = _model.getMat(); |
|
|
|
@ -233,10 +267,7 @@ public: |
|
|
|
|
|
|
|
|
|
Mat src, dst; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} // end namesapce cv
|
|
|
|
|
|
|
|
|
|
namespace cv{ |
|
|
|
|
static bool createAndRunRHORegistrator(double confidence, |
|
|
|
@ -277,7 +308,7 @@ static bool createAndRunRHORegistrator(double confidence, |
|
|
|
|
rhoEnsureCapacity(p, npoints, beta); |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* The critical call. All parameters are heavily documented in rhorefc.h. |
|
|
|
|
* The critical call. All parameters are heavily documented in rho.h. |
|
|
|
|
* |
|
|
|
|
* Currently, NR (Non-Randomness criterion) and Final Refinement (with |
|
|
|
|
* internal, optimized Levenberg-Marquardt method) are enabled. However, |
|
|
|
@ -305,7 +336,7 @@ static bool createAndRunRHORegistrator(double confidence, |
|
|
|
|
/* Convert float homography to double precision. */ |
|
|
|
|
tmpH.convertTo(_H, CV_64FC1); |
|
|
|
|
|
|
|
|
|
/* Maps non-zero mask elems to 1, for the sake of the testcase. */ |
|
|
|
|
/* Maps non-zero mask elements to 1, for the sake of the test case. */ |
|
|
|
|
for(int k=0;k<npoints;k++){ |
|
|
|
|
tempMask.data[k] = !!tempMask.data[k]; |
|
|
|
|
} |
|
|
|
@ -421,6 +452,28 @@ cv::Mat cv::findHomography( InputArray _points1, InputArray _points2, |
|
|
|
|
namespace cv |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Compute the fundamental matrix using the 7-point algorithm. |
|
|
|
|
* |
|
|
|
|
* \f[ |
|
|
|
|
* (\mathrm{m2}_i,1)^T \mathrm{fmatrix} (\mathrm{m1}_i,1) = 0 |
|
|
|
|
* \f] |
|
|
|
|
* |
|
|
|
|
* @param _m1 Contain points in the reference view. Depth CV_32F with 2-channel |
|
|
|
|
* 1 column or 1-channel 2 columns. It has 7 rows. |
|
|
|
|
* @param _m2 Contain points in the other view. Depth CV_32F with 2-channel |
|
|
|
|
* 1 column or 1-channel 2 columns. It has 7 rows. |
|
|
|
|
* @param _fmatrix Output fundamental matrix (or matrices) of type CV_64FC1. |
|
|
|
|
* The user is responsible for allocating the memory before calling |
|
|
|
|
* this function. |
|
|
|
|
* @return Number of fundamental matrices. Valid values are 1, 2 or 3. |
|
|
|
|
* - 1, row 0 to row 2 in _fmatrix is a valid fundamental matrix |
|
|
|
|
* - 2, row 3 to row 5 in _fmatrix is a valid fundamental matrix |
|
|
|
|
* - 3, row 6 to row 8 in _fmatrix is a valid fundamental matrix |
|
|
|
|
* |
|
|
|
|
* Note that the computed fundamental matrix is normalized, i.e., |
|
|
|
|
* the last element \f$F_{33}\f$ is 1. |
|
|
|
|
*/ |
|
|
|
|
static int run7Point( const Mat& _m1, const Mat& _m2, Mat& _fmatrix ) |
|
|
|
|
{ |
|
|
|
|
double a[7*9], w[7], u[9*9], v[9*9], c[4], r[3] = {0}; |
|
|
|
@ -463,7 +516,7 @@ static int run7Point( const Mat& _m1, const Mat& _m2, Mat& _fmatrix ) |
|
|
|
|
f1 = v + 7*9; |
|
|
|
|
f2 = v + 8*9; |
|
|
|
|
|
|
|
|
|
// f1, f2 is a basis => lambda*f1 + mu*f2 is an arbitrary f. matrix.
|
|
|
|
|
// f1, f2 is a basis => lambda*f1 + mu*f2 is an arbitrary fundamental matrix,
|
|
|
|
|
// as it is determined up to a scale, normalize lambda & mu (lambda + mu = 1),
|
|
|
|
|
// so f ~ lambda*f1 + (1 - lambda)*f2.
|
|
|
|
|
// use the additional constraint det(f) = det(lambda*f1 + (1-lambda)*f2) to find lambda.
|
|
|
|
@ -529,7 +582,25 @@ static int run7Point( const Mat& _m1, const Mat& _m2, Mat& _fmatrix ) |
|
|
|
|
return n; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Compute the fundamental matrix using the 8-point algorithm. |
|
|
|
|
* |
|
|
|
|
* \f[ |
|
|
|
|
* (\mathrm{m2}_i,1)^T \mathrm{fmatrix} (\mathrm{m1}_i,1) = 0 |
|
|
|
|
* \f] |
|
|
|
|
* |
|
|
|
|
* @param _m1 Contain points in the reference view. Depth CV_32F with 2-channel |
|
|
|
|
* 1 column or 1-channel 2 columns. It has 8 rows. |
|
|
|
|
* @param _m2 Contain points in the other view. Depth CV_32F with 2-channel |
|
|
|
|
* 1 column or 1-channel 2 columns. It has 8 rows. |
|
|
|
|
* @param _fmatrix Output fundamental matrix (or matrices) of type CV_64FC1. |
|
|
|
|
* The user is responsible for allocating the memory before calling |
|
|
|
|
* this function. |
|
|
|
|
* @return 1 on success, 0 on failure. |
|
|
|
|
* |
|
|
|
|
* Note that the computed fundamental matrix is normalized, i.e., |
|
|
|
|
* the last element \f$F_{33}\f$ is 1. |
|
|
|
|
*/ |
|
|
|
|
static int run8Point( const Mat& _m1, const Mat& _m2, Mat& _fmatrix ) |
|
|
|
|
{ |
|
|
|
|
Point2d m1c(0,0), m2c(0,0); |
|
|
|
@ -690,7 +761,7 @@ public: |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cv::Mat cv::findFundamentalMat( InputArray _points1, InputArray _points2, |
|
|
|
|
int method, double param1, double param2, |
|
|
|
|
int method, double ransacReprojThreshold, double confidence, |
|
|
|
|
OutputArray _mask ) |
|
|
|
|
{ |
|
|
|
|
CV_INSTRUMENT_REGION() |
|
|
|
@ -737,15 +808,15 @@ cv::Mat cv::findFundamentalMat( InputArray _points1, InputArray _points2, |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
if( param1 <= 0 ) |
|
|
|
|
param1 = 3; |
|
|
|
|
if( param2 < DBL_EPSILON || param2 > 1 - DBL_EPSILON ) |
|
|
|
|
param2 = 0.99; |
|
|
|
|
if( ransacReprojThreshold <= 0 ) |
|
|
|
|
ransacReprojThreshold = 3; |
|
|
|
|
if( confidence < DBL_EPSILON || confidence > 1 - DBL_EPSILON ) |
|
|
|
|
confidence = 0.99; |
|
|
|
|
|
|
|
|
|
if( (method & ~3) == FM_RANSAC && npoints >= 15 ) |
|
|
|
|
result = createRANSACPointSetRegistrator(cb, 7, param1, param2)->run(m1, m2, F, _mask); |
|
|
|
|
result = createRANSACPointSetRegistrator(cb, 7, ransacReprojThreshold, confidence)->run(m1, m2, F, _mask); |
|
|
|
|
else |
|
|
|
|
result = createLMeDSPointSetRegistrator(cb, 7, param2)->run(m1, m2, F, _mask); |
|
|
|
|
result = createLMeDSPointSetRegistrator(cb, 7, confidence)->run(m1, m2, F, _mask); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if( result <= 0 ) |
|
|
|
@ -755,9 +826,10 @@ cv::Mat cv::findFundamentalMat( InputArray _points1, InputArray _points2, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
cv::Mat cv::findFundamentalMat( InputArray _points1, InputArray _points2, |
|
|
|
|
OutputArray _mask, int method, double param1, double param2 ) |
|
|
|
|
OutputArray _mask, int method, |
|
|
|
|
double ransacReprojThreshold , double confidence) |
|
|
|
|
{ |
|
|
|
|
return cv::findFundamentalMat(_points1, _points2, method, param1, param2, _mask); |
|
|
|
|
return cv::findFundamentalMat(_points1, _points2, method, ransacReprojThreshold, confidence, _mask); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|