Merge pull request #10644 from csukuangfj:doc-fundamental-matrix

pull/10675/head
Vadim Pisarevsky 7 years ago
commit 8f04c8b16c
  1. 32
      modules/calib3d/include/opencv2/calib3d.hpp
  2. 106
      modules/calib3d/src/fundam.cpp
  3. 2
      modules/calib3d/src/rho.h
  4. 1
      modules/core/include/opencv2/core.hpp

@ -227,7 +227,7 @@ namespace cv
//! @{
//! type of the robust estimation algorithm
enum { LMEDS = 4, //!< least-median algorithm
enum { LMEDS = 4, //!< least-median of squares algorithm
RANSAC = 8, //!< RANSAC algorithm
RHO = 16 //!< RHO algorithm
};
@ -281,8 +281,8 @@ enum { CALIB_USE_INTRINSIC_GUESS = 0x00001,
//! the algorithm for finding fundamental matrix
enum { FM_7POINT = 1, //!< 7-point algorithm
FM_8POINT = 2, //!< 8-point algorithm
FM_LMEDS = 4, //!< least-median algorithm
FM_RANSAC = 8 //!< RANSAC algorithm
FM_LMEDS = 4, //!< least-median algorithm. 7-point algorithm is used.
FM_RANSAC = 8 //!< RANSAC algorithm. It needs at least 15 points. 7-point algorithm is used.
};
@ -1412,11 +1412,11 @@ floating-point (single or double precision).
- **CV_FM_8POINT** for an 8-point algorithm. \f$N \ge 8\f$
- **CV_FM_RANSAC** for the RANSAC algorithm. \f$N \ge 8\f$
- **CV_FM_LMEDS** for the LMedS algorithm. \f$N \ge 8\f$
@param param1 Parameter used for RANSAC. It is the maximum distance from a point to an epipolar
@param ransacReprojThreshold Parameter used only for RANSAC. It is the maximum distance from a point to an epipolar
line in pixels, beyond which the point is considered an outlier and is not used for computing the
final fundamental matrix. It can be set to something like 1-3, depending on the accuracy of the
point localization, image resolution, and the image noise.
@param param2 Parameter used for the RANSAC or LMedS methods only. It specifies a desirable level
@param confidence Parameter used for the RANSAC and LMedS methods only. It specifies a desirable level
of confidence (probability) that the estimated matrix is correct.
@param mask
@ -1454,13 +1454,13 @@ stereoRectifyUncalibrated to compute the rectification transformation. :
*/
CV_EXPORTS_W Mat findFundamentalMat( InputArray points1, InputArray points2,
int method = FM_RANSAC,
double param1 = 3., double param2 = 0.99,
double ransacReprojThreshold = 3., double confidence = 0.99,
OutputArray mask = noArray() );
/** @overload */
CV_EXPORTS Mat findFundamentalMat( InputArray points1, InputArray points2,
OutputArray mask, int method = FM_RANSAC,
double param1 = 3., double param2 = 0.99 );
double ransacReprojThreshold = 3., double confidence = 0.99 );
/** @brief Calculates an essential matrix from the corresponding points in two images.
@ -1770,12 +1770,20 @@ CV_EXPORTS_W void reprojectImageTo3D( InputArray disparity,
/** @brief Calculates the Sampson Distance between two points.
The function sampsonDistance calculates and returns the first order approximation of the geometric error as:
\f[sd( \texttt{pt1} , \texttt{pt2} )= \frac{(\texttt{pt2}^t \cdot \texttt{F} \cdot \texttt{pt1})^2}{(\texttt{F} \cdot \texttt{pt1})(0) + (\texttt{F} \cdot \texttt{pt1})(1) + (\texttt{F}^t \cdot \texttt{pt2})(0) + (\texttt{F}^t \cdot \texttt{pt2})(1)}\f]
The fundamental matrix may be calculated using the cv::findFundamentalMat function. See HZ 11.4.3 for details.
The function cv::sampsonDistance calculates and returns the first order approximation of the geometric error as:
\f[
sd( \texttt{pt1} , \texttt{pt2} )=
\frac{(\texttt{pt2}^t \cdot \texttt{F} \cdot \texttt{pt1})^2}
{((\texttt{F} \cdot \texttt{pt1})(0))^2 +
((\texttt{F} \cdot \texttt{pt1})(1))^2 +
((\texttt{F}^t \cdot \texttt{pt2})(0))^2 +
((\texttt{F}^t \cdot \texttt{pt2})(1))^2}
\f]
The fundamental matrix may be calculated using the cv::findFundamentalMat function. See @cite HartleyZ00 11.4.3 for details.
@param pt1 first homogeneous 2d point
@param pt2 second homogeneous 2d point
@param F fundamental matrix
@return The computed Sampson distance.
*/
CV_EXPORTS_W double sampsonDistance(InputArray pt1, InputArray pt2, InputArray F);
@ -2402,9 +2410,9 @@ optimization. It stays at the center or at a different location specified when C
TermCriteria criteria = TermCriteria(TermCriteria::COUNT + TermCriteria::EPS, 100, DBL_EPSILON));
//! @} calib3d_fisheye
}
} // end namespace fisheye
} // cv
} //end namespace cv
#ifndef DISABLE_OPENCV_24_COMPATIBILITY
#include "opencv2/calib3d/calib3d_c.h"

@ -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);
}

@ -95,7 +95,7 @@ typedef struct RHO_HEST RHO_HEST;
* Initialize the estimator context, by allocating the aligned buffers
* internally needed.
*
* @return A pointer to the context if successful; NULL if an error occured.
* @return A pointer to the context if successful; NULL if an error occurred.
*/
Ptr<RHO_HEST> rhoInit(void);

@ -1894,6 +1894,7 @@ The function solveCubic finds the real roots of a cubic equation:
The roots are stored in the roots array.
@param coeffs equation coefficients, an array of 3 or 4 elements.
@param roots output array of real roots that has 1 or 3 elements.
@return number of real roots. It can be 0, 1 or 2.
*/
CV_EXPORTS_W int solveCubic(InputArray coeffs, OutputArray roots);

Loading…
Cancel
Save