1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-29 15:23:05 +04:00

Improve the doc for fundamental matrix.

This commit is contained in:
Fangjun Kuang
2018-01-19 13:23:09 +01:00
parent 18ce529256
commit eb2901bd69
4 changed files with 111 additions and 30 deletions
+89 -17
View File
@@ -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);
}