Merge pull request #3670 from obilaniu:master
This commit is contained in:
commit
0545aeb11b
@ -184,7 +184,8 @@ namespace cv
|
||||
|
||||
//! type of the robust estimation algorithm
|
||||
enum { LMEDS = 4, //!< least-median algorithm
|
||||
RANSAC = 8 //!< RANSAC algorithm
|
||||
RANSAC = 8, //!< RANSAC algorithm
|
||||
RHO = 16 //!< RHO algorithm
|
||||
};
|
||||
|
||||
enum { SOLVEPNP_ITERATIVE = 0,
|
||||
@ -265,8 +266,9 @@ a vector\<Point2f\> .
|
||||
- **0** - a regular method using all the points
|
||||
- **RANSAC** - RANSAC-based robust method
|
||||
- **LMEDS** - Least-Median robust method
|
||||
- **RHO** - PROSAC-based robust method
|
||||
@param ransacReprojThreshold Maximum allowed reprojection error to treat a point pair as an inlier
|
||||
(used in the RANSAC method only). That is, if
|
||||
(used in the RANSAC and RHO methods only). That is, if
|
||||
\f[\| \texttt{dstPoints} _i - \texttt{convertPointsHomogeneous} ( \texttt{H} * \texttt{srcPoints} _i) \| > \texttt{ransacReprojThreshold}\f]
|
||||
then the point \f$i\f$ is considered an outlier. If srcPoints and dstPoints are measured in pixels,
|
||||
it usually makes sense to set this parameter somewhere in the range of 1 to 10.
|
||||
@ -289,7 +291,7 @@ pairs to compute an initial homography estimate with a simple least-squares sche
|
||||
|
||||
However, if not all of the point pairs ( \f$srcPoints_i\f$, \f$dstPoints_i\f$ ) fit the rigid perspective
|
||||
transformation (that is, there are some outliers), this initial estimate will be poor. In this case,
|
||||
you can use one of the two robust methods. Both methods, RANSAC and LMeDS , try many different
|
||||
you can use one of the three robust methods. The methods RANSAC, LMeDS and RHO try many different
|
||||
random subsets of the corresponding point pairs (of four pairs each), estimate the homography matrix
|
||||
using this subset and a simple least-square algorithm, and then compute the quality/goodness of the
|
||||
computed homography (which is the number of inliers for RANSAC or the median re-projection error for
|
||||
@ -300,7 +302,7 @@ Regardless of the method, robust or not, the computed homography matrix is refin
|
||||
inliers only in case of a robust method) with the Levenberg-Marquardt method to reduce the
|
||||
re-projection error even more.
|
||||
|
||||
The method RANSAC can handle practically any ratio of outliers but it needs a threshold to
|
||||
The methods RANSAC and RHO can handle practically any ratio of outliers but need a threshold to
|
||||
distinguish inliers from outliers. The method LMeDS does not need any threshold but it works
|
||||
correctly only when there are more than 50% of inliers. Finally, if there are no outliers and the
|
||||
noise is rather small, use the default method (method=0).
|
||||
|
@ -41,6 +41,7 @@
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
#include "rho.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace cv
|
||||
@ -259,6 +260,85 @@ public:
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace cv{
|
||||
static bool createAndRunRHORegistrator(double confidence,
|
||||
int maxIters,
|
||||
double ransacReprojThreshold,
|
||||
int npoints,
|
||||
InputArray _src,
|
||||
InputArray _dst,
|
||||
OutputArray _H,
|
||||
OutputArray _tempMask){
|
||||
Mat src = _src.getMat();
|
||||
Mat dst = _dst.getMat();
|
||||
Mat tempMask;
|
||||
bool result;
|
||||
double beta = 0.35;/* 0.35 is a value that often works. */
|
||||
|
||||
/* Create temporary output matrix (RHO outputs a single-precision H only). */
|
||||
Mat tmpH = Mat(3, 3, CV_32FC1);
|
||||
|
||||
/* Create output mask. */
|
||||
tempMask = Mat(npoints, 1, CV_8U);
|
||||
|
||||
/**
|
||||
* Make use of the RHO estimator API.
|
||||
*
|
||||
* This is where the math happens. A homography estimation context is
|
||||
* initialized, used, then finalized.
|
||||
*/
|
||||
|
||||
Ptr<RHO_HEST> p = rhoInit();
|
||||
|
||||
/**
|
||||
* Optional. Ideally, the context would survive across calls to
|
||||
* findHomography(), but no clean way appears to exit to do so. The price
|
||||
* to pay is marginally more computational work than strictly needed.
|
||||
*/
|
||||
|
||||
rhoEnsureCapacity(p, npoints, beta);
|
||||
|
||||
/**
|
||||
* The critical call. All parameters are heavily documented in rhorefc.h.
|
||||
*
|
||||
* Currently, NR (Non-Randomness criterion) and Final Refinement (with
|
||||
* internal, optimized Levenberg-Marquardt method) are enabled. However,
|
||||
* while refinement seems to correctly smooth jitter most of the time, when
|
||||
* refinement fails it tends to make the estimate visually very much worse.
|
||||
* It may be necessary to remove the refinement flags in a future commit if
|
||||
* this behaviour is too problematic.
|
||||
*/
|
||||
|
||||
result = !!rhoHest(p,
|
||||
(const float*)src.data,
|
||||
(const float*)dst.data,
|
||||
(char*) tempMask.data,
|
||||
(unsigned) npoints,
|
||||
(float) ransacReprojThreshold,
|
||||
(unsigned) maxIters,
|
||||
(unsigned) maxIters,
|
||||
confidence,
|
||||
4U,
|
||||
beta,
|
||||
RHO_FLAG_ENABLE_NR | RHO_FLAG_ENABLE_FINAL_REFINEMENT,
|
||||
NULL,
|
||||
(float*)tmpH.data);
|
||||
|
||||
/* Convert float homography to double precision. */
|
||||
tmpH.convertTo(_H, CV_64FC1);
|
||||
|
||||
/* Maps non-zero mask elems to 1, for the sake of the testcase. */
|
||||
for(int k=0;k<npoints;k++){
|
||||
tempMask.data[k] = !!tempMask.data[k];
|
||||
}
|
||||
tempMask.copyTo(_tempMask);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cv::Mat cv::findHomography( InputArray _points1, InputArray _points2,
|
||||
int method, double ransacReprojThreshold, OutputArray _mask,
|
||||
const int maxIters, const double confidence)
|
||||
@ -303,10 +383,12 @@ cv::Mat cv::findHomography( InputArray _points1, InputArray _points2,
|
||||
result = createRANSACPointSetRegistrator(cb, 4, ransacReprojThreshold, confidence, maxIters)->run(src, dst, H, tempMask);
|
||||
else if( method == LMEDS )
|
||||
result = createLMeDSPointSetRegistrator(cb, 4, confidence, maxIters)->run(src, dst, H, tempMask);
|
||||
else if( method == RHO )
|
||||
result = createAndRunRHORegistrator(confidence, maxIters, ransacReprojThreshold, npoints, src, dst, H, tempMask);
|
||||
else
|
||||
CV_Error(Error::StsBadArg, "Unknown estimation method");
|
||||
|
||||
if( result && npoints > 4 )
|
||||
if( result && npoints > 4 && method != RHO)
|
||||
{
|
||||
compressElems( src.ptr<Point2f>(), tempMask.ptr<uchar>(), 1, npoints );
|
||||
npoints = compressElems( dst.ptr<Point2f>(), tempMask.ptr<uchar>(), 1, npoints );
|
||||
|
2673
modules/calib3d/src/rho.cpp
Normal file
2673
modules/calib3d/src/rho.cpp
Normal file
File diff suppressed because it is too large
Load Diff
268
modules/calib3d/src/rho.h
Normal file
268
modules/calib3d/src/rho.h
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
|
||||
By downloading, copying, installing or using the software you agree to this license.
|
||||
If you do not agree to this license, do not download, install,
|
||||
copy or use the software.
|
||||
|
||||
|
||||
BSD 3-Clause License
|
||||
|
||||
Copyright (C) 2014, Olexa Bilaniuk, Hamid Bazargani & Robert Laganiere, all rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistribution's of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistribution's in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
* The name of the copyright holders may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
This software is provided by the copyright holders and contributors "as is" and
|
||||
any express or implied warranties, including, but not limited to, the implied
|
||||
warranties of merchantability and fitness for a particular purpose are disclaimed.
|
||||
In no event shall the Intel Corporation or contributors be liable for any direct,
|
||||
indirect, incidental, special, exemplary, or consequential damages
|
||||
(including, but not limited to, procurement of substitute goods or services;
|
||||
loss of use, data, or profits; or business interruption) however caused
|
||||
and on any theory of liability, whether in contract, strict liability,
|
||||
or tort (including negligence or otherwise) arising in any way out of
|
||||
the use of this software, even if advised of the possibility of such damage.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Bilaniuk, Olexa, Hamid Bazargani, and Robert Laganiere. "Fast Target
|
||||
* Recognition on Mobile Devices: Revisiting Gaussian Elimination for the
|
||||
* Estimation of Planar Homographies." In Computer Vision and Pattern
|
||||
* Recognition Workshops (CVPRW), 2014 IEEE Conference on, pp. 119-125.
|
||||
* IEEE, 2014.
|
||||
*/
|
||||
|
||||
/* Include Guards */
|
||||
#ifndef __OPENCV_RHO_H__
|
||||
#define __OPENCV_RHO_H__
|
||||
|
||||
|
||||
|
||||
/* Includes */
|
||||
#include <opencv2/core.hpp>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Defines */
|
||||
|
||||
|
||||
/* Flags */
|
||||
#ifndef RHO_FLAG_NONE
|
||||
#define RHO_FLAG_NONE (0U<<0)
|
||||
#endif
|
||||
#ifndef RHO_FLAG_ENABLE_NR
|
||||
#define RHO_FLAG_ENABLE_NR (1U<<0)
|
||||
#endif
|
||||
#ifndef RHO_FLAG_ENABLE_REFINEMENT
|
||||
#define RHO_FLAG_ENABLE_REFINEMENT (1U<<1)
|
||||
#endif
|
||||
#ifndef RHO_FLAG_ENABLE_FINAL_REFINEMENT
|
||||
#define RHO_FLAG_ENABLE_FINAL_REFINEMENT (1U<<2)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Namespace cv */
|
||||
namespace cv{
|
||||
|
||||
/* Data structures */
|
||||
|
||||
/**
|
||||
* Homography Estimation context.
|
||||
*/
|
||||
|
||||
struct RHO_HEST;
|
||||
typedef struct RHO_HEST RHO_HEST;
|
||||
|
||||
|
||||
/* Functions */
|
||||
|
||||
/**
|
||||
* Initialize the estimator context, by allocating the aligned buffers
|
||||
* internally needed.
|
||||
*
|
||||
* @return A pointer to the context if successful; NULL if an error occured.
|
||||
*/
|
||||
|
||||
Ptr<RHO_HEST> rhoInit(void);
|
||||
|
||||
|
||||
/**
|
||||
* Ensure that the estimator context's internal table for non-randomness
|
||||
* criterion is at least of the given size, and uses the given beta. The table
|
||||
* should be larger than the maximum number of matches fed into the estimator.
|
||||
*
|
||||
* A value of N of 0 requests deallocation of the table.
|
||||
*
|
||||
* @param [in] p The initialized estimator context
|
||||
* @param [in] N If 0, deallocate internal table. If > 0, ensure that the
|
||||
* internal table is of at least this size, reallocating if
|
||||
* necessary.
|
||||
* @param [in] beta The beta-factor to use within the table.
|
||||
* @return 0 if unsuccessful; non-zero otherwise.
|
||||
*/
|
||||
|
||||
int rhoEnsureCapacity(Ptr<RHO_HEST> p, unsigned N, double beta);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Seeds the internal PRNG with the given seed.
|
||||
*
|
||||
* Although it is not required to call this function, since context
|
||||
* initialization seeds itself with entropy from rand(), this function allows
|
||||
* reproducible results by using a specified seed.
|
||||
*
|
||||
* @param [in] p The estimator context whose PRNG is to be seeded.
|
||||
* @param [in] seed The 64-bit integer seed.
|
||||
*/
|
||||
|
||||
void rhoSeed(Ptr<RHO_HEST> p, uint64_t seed);
|
||||
|
||||
|
||||
/**
|
||||
* Estimates the homography using the given context, matches and parameters to
|
||||
* PROSAC.
|
||||
*
|
||||
* The given context must have been initialized.
|
||||
*
|
||||
* The matches are provided as two arrays of N single-precision, floating-point
|
||||
* (x,y) points. Points with corresponding offsets in the two arrays constitute
|
||||
* a match. The homography estimation attempts to find the 3x3 matrix H which
|
||||
* best maps the homogeneous-coordinate points in the source array to their
|
||||
* corresponding homogeneous-coordinate points in the destination array.
|
||||
*
|
||||
* Note: At least 4 matches must be provided (N >= 4).
|
||||
* Note: A point in either array takes up 2 floats. The first of two stores
|
||||
* the x-coordinate and the second of the two stores the y-coordinate.
|
||||
* Thus, the arrays resemble this in memory:
|
||||
*
|
||||
* src = [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, ...]
|
||||
* Matches: | | | | |
|
||||
* dst = [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, ...]
|
||||
* Note: The matches are expected to be provided sorted by quality, or at
|
||||
* least not be worse-than-random in ordering.
|
||||
*
|
||||
* A pointer to the base of an array of N bytes can be provided. It serves as
|
||||
* an output mask to indicate whether the corresponding match is an inlier to
|
||||
* the returned homography, if any. A zero indicates an outlier; A non-zero
|
||||
* value indicates an inlier.
|
||||
*
|
||||
* The PROSAC estimator requires a few parameters of its own. These are:
|
||||
*
|
||||
* - The maximum distance that a source point projected onto the destination
|
||||
* plane can be from its putative match and still be considered an
|
||||
* inlier. Must be non-negative.
|
||||
* A sane default is 3.0.
|
||||
* - The maximum number of PROSAC iterations. This corresponds to the
|
||||
* largest number of samples that will be drawn and tested.
|
||||
* A sane default is 2000.
|
||||
* - The RANSAC convergence parameter. This corresponds to the number of
|
||||
* iterations after which PROSAC will start sampling like RANSAC.
|
||||
* A sane default is 2000.
|
||||
* - The confidence threshold. This corresponds to the probability of
|
||||
* finding a correct solution. Must be bounded by [0, 1].
|
||||
* A sane default is 0.995.
|
||||
* - The minimum number of inliers acceptable. Only a solution with at
|
||||
* least this many inliers will be returned. The minimum is 4.
|
||||
* A sane default is 10% of N.
|
||||
* - The beta-parameter for the non-randomness termination criterion.
|
||||
* Ignored if non-randomness criterion disabled, otherwise must be
|
||||
* bounded by (0, 1).
|
||||
* A sane default is 0.35.
|
||||
* - Optional flags to control the estimation. Available flags are:
|
||||
* HEST_FLAG_NONE:
|
||||
* No special processing.
|
||||
* HEST_FLAG_ENABLE_NR:
|
||||
* Enable non-randomness criterion. If set, the beta parameter
|
||||
* must also be set.
|
||||
* HEST_FLAG_ENABLE_REFINEMENT:
|
||||
* Enable refinement of each new best model, as they are found.
|
||||
* HEST_FLAG_ENABLE_FINAL_REFINEMENT:
|
||||
* Enable one final refinement of the best model found before
|
||||
* returning it.
|
||||
*
|
||||
* The PROSAC estimator optionally accepts an extrinsic initial guess of H.
|
||||
*
|
||||
* The PROSAC estimator outputs a final estimate of H provided it was able to
|
||||
* find one with a minimum of supporting inliers. If it was not, it outputs
|
||||
* the all-zero matrix.
|
||||
*
|
||||
* The extrinsic guess at and final estimate of H are both in the same form:
|
||||
* A 3x3 single-precision floating-point matrix with step 3. Thus, it is a
|
||||
* 9-element array of floats, with the elements as follows:
|
||||
*
|
||||
* [ H00, H01, H02,
|
||||
* H10, H11, H12,
|
||||
* H20, H21, 1.0 ]
|
||||
*
|
||||
* Notice that the homography is normalized to H22 = 1.0.
|
||||
*
|
||||
* The function returns the number of inliers if it was able to find a
|
||||
* homography with at least the minimum required support, and 0 if it was not.
|
||||
*
|
||||
*
|
||||
* @param [in/out] p The context to use for homography estimation. Must
|
||||
* be already initialized. Cannot be NULL.
|
||||
* @param [in] src The pointer to the source points of the matches.
|
||||
* Must be aligned to 4 bytes. Cannot be NULL.
|
||||
* @param [in] dst The pointer to the destination points of the matches.
|
||||
* Must be aligned to 4 bytes. Cannot be NULL.
|
||||
* @param [out] inl The pointer to the output mask of inlier matches.
|
||||
* Must be aligned to 4 bytes. May be NULL.
|
||||
* @param [in] N The number of matches. Minimum 4.
|
||||
* @param [in] maxD The maximum distance. Minimum 0.
|
||||
* @param [in] maxI The maximum number of PROSAC iterations.
|
||||
* @param [in] rConvg The RANSAC convergence parameter.
|
||||
* @param [in] cfd The required confidence in the solution.
|
||||
* @param [in] minInl The minimum required number of inliers. Minimum 4.
|
||||
* @param [in] beta The beta-parameter for the non-randomness criterion.
|
||||
* @param [in] flags A union of flags to fine-tune the estimation.
|
||||
* @param [in] guessH An extrinsic guess at the solution H, or NULL if
|
||||
* none provided.
|
||||
* @param [out] finalH The final estimation of H, or the zero matrix if
|
||||
* the minimum number of inliers was not met.
|
||||
* Cannot be NULL.
|
||||
* @return The number of inliers if the minimum number of
|
||||
* inliers for acceptance was reached; 0 otherwise.
|
||||
*/
|
||||
|
||||
unsigned rhoHest(Ptr<RHO_HEST> p, /* Homography estimation context. */
|
||||
const float* src, /* Source points */
|
||||
const float* dst, /* Destination points */
|
||||
char* inl, /* Inlier mask */
|
||||
unsigned N, /* = src.length = dst.length = inl.length */
|
||||
float maxD, /* 3.0 */
|
||||
unsigned maxI, /* 2000 */
|
||||
unsigned rConvg, /* 2000 */
|
||||
double cfd, /* 0.995 */
|
||||
unsigned minInl, /* 4 */
|
||||
double beta, /* 0.35 */
|
||||
unsigned flags, /* 0 */
|
||||
const float* guessH, /* Extrinsic guess, NULL if none provided */
|
||||
float* finalH); /* Final result. */
|
||||
|
||||
|
||||
|
||||
|
||||
/* End Namespace cv */
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
@ -62,10 +62,10 @@
|
||||
|
||||
#define MAX_COUNT_OF_POINTS 303
|
||||
#define COUNT_NORM_TYPES 3
|
||||
#define METHODS_COUNT 3
|
||||
#define METHODS_COUNT 4
|
||||
|
||||
int NORM_TYPE[COUNT_NORM_TYPES] = {cv::NORM_L1, cv::NORM_L2, cv::NORM_INF};
|
||||
int METHOD[METHODS_COUNT] = {0, cv::RANSAC, cv::LMEDS};
|
||||
int METHOD[METHODS_COUNT] = {0, cv::RANSAC, cv::LMEDS, cv::RHO};
|
||||
|
||||
using namespace cv;
|
||||
using namespace std;
|
||||
@ -94,12 +94,12 @@ private:
|
||||
|
||||
void print_information_1(int j, int N, int method, const Mat& H);
|
||||
void print_information_2(int j, int N, int method, const Mat& H, const Mat& H_res, int k, double diff);
|
||||
void print_information_3(int j, int N, const Mat& mask);
|
||||
void print_information_3(int method, int j, int N, const Mat& mask);
|
||||
void print_information_4(int method, int j, int N, int k, int l, double diff);
|
||||
void print_information_5(int method, int j, int N, int l, double diff);
|
||||
void print_information_6(int j, int N, int k, double diff, bool value);
|
||||
void print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value);
|
||||
void print_information_8(int j, int N, int k, int l, double diff);
|
||||
void print_information_6(int method, int j, int N, int k, double diff, bool value);
|
||||
void print_information_7(int method, int j, int N, int k, double diff, bool original_value, bool found_value);
|
||||
void print_information_8(int method, int j, int N, int k, int l, double diff);
|
||||
};
|
||||
|
||||
CV_HomographyTest::CV_HomographyTest() : max_diff(1e-2f), max_2diff(2e-2f)
|
||||
@ -144,7 +144,7 @@ void CV_HomographyTest::print_information_1(int j, int N, int _method, const Mat
|
||||
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
|
||||
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
|
||||
cout << "Count of points: " << N << endl; cout << endl;
|
||||
cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;
|
||||
cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else if (_method == cv::RHO) cout << "RHO"; else cout << "LMEDS"; cout << endl;
|
||||
cout << "Homography matrix:" << endl; cout << endl;
|
||||
cout << H << endl; cout << endl;
|
||||
cout << "Number of rows: " << H.rows << " Number of cols: " << H.cols << endl; cout << endl;
|
||||
@ -156,7 +156,7 @@ void CV_HomographyTest::print_information_2(int j, int N, int _method, const Mat
|
||||
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
|
||||
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
|
||||
cout << "Count of points: " << N << endl; cout << endl;
|
||||
cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else cout << "LMEDS"; cout << endl;
|
||||
cout << "Method: "; if (_method == 0) cout << 0; else if (_method == 8) cout << "RANSAC"; else if (_method == cv::RHO) cout << "RHO"; else cout << "LMEDS"; cout << endl;
|
||||
cout << "Original matrix:" << endl; cout << endl;
|
||||
cout << H << endl; cout << endl;
|
||||
cout << "Found matrix:" << endl; cout << endl;
|
||||
@ -166,13 +166,13 @@ void CV_HomographyTest::print_information_2(int j, int N, int _method, const Mat
|
||||
cout << "Maximum allowed difference: " << max_diff << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_3(int j, int N, const Mat& mask)
|
||||
void CV_HomographyTest::print_information_3(int _method, int j, int N, const Mat& mask)
|
||||
{
|
||||
cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl;
|
||||
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
|
||||
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
|
||||
cout << "Count of points: " << N << endl; cout << endl;
|
||||
cout << "Method: RANSAC" << endl;
|
||||
cout << "Method: "; if (_method == RANSAC) cout << "RANSAC" << endl; else if (_method == cv::RHO) cout << "RHO" << endl; else cout << _method << endl;
|
||||
cout << "Found mask:" << endl; cout << endl;
|
||||
cout << mask << endl; cout << endl;
|
||||
cout << "Number of rows: " << mask.rows << " Number of cols: " << mask.cols << endl; cout << endl;
|
||||
@ -205,10 +205,10 @@ void CV_HomographyTest::print_information_5(int _method, int j, int N, int l, do
|
||||
cout << "Maxumum allowed difference: " << max_diff << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_6(int j, int N, int k, double diff, bool value)
|
||||
void CV_HomographyTest::print_information_6(int _method, int j, int N, int k, double diff, bool value)
|
||||
{
|
||||
cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl;
|
||||
cout << "Method: RANSAC" << endl;
|
||||
cout << "Method: "; if (_method == RANSAC) cout << "RANSAC" << endl; else if (_method == cv::RHO) cout << "RHO" << endl; else cout << _method << endl;
|
||||
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
|
||||
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
|
||||
cout << "Count of points: " << N << " " << endl;
|
||||
@ -218,10 +218,10 @@ void CV_HomographyTest::print_information_6(int j, int N, int k, double diff, bo
|
||||
cout << "Value of found mask: "<< value << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_7(int j, int N, int k, double diff, bool original_value, bool found_value)
|
||||
void CV_HomographyTest::print_information_7(int _method, int j, int N, int k, double diff, bool original_value, bool found_value)
|
||||
{
|
||||
cout << endl; cout << "Checking for inliers/outliers mask..." << endl; cout << endl;
|
||||
cout << "Method: RANSAC" << endl;
|
||||
cout << "Method: "; if (_method == RANSAC) cout << "RANSAC" << endl; else if (_method == cv::RHO) cout << "RHO" << endl; else cout << _method << endl;
|
||||
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
|
||||
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
|
||||
cout << "Count of points: " << N << " " << endl;
|
||||
@ -231,10 +231,10 @@ void CV_HomographyTest::print_information_7(int j, int N, int k, double diff, bo
|
||||
cout << "Value of original mask: "<< original_value << " Value of found mask: " << found_value << endl; cout << endl;
|
||||
}
|
||||
|
||||
void CV_HomographyTest::print_information_8(int j, int N, int k, int l, double diff)
|
||||
void CV_HomographyTest::print_information_8(int _method, int j, int N, int k, int l, double diff)
|
||||
{
|
||||
cout << endl; cout << "Checking for reprojection error of inlier..." << endl; cout << endl;
|
||||
cout << "Method: RANSAC" << endl;
|
||||
cout << "Method: "; if (_method == RANSAC) cout << "RANSAC" << endl; else if (_method == cv::RHO) cout << "RHO" << endl; else cout << _method << endl;
|
||||
cout << "Sigma of normal noise: " << sigma << endl;
|
||||
cout << "Type of srcPoints: "; if ((j>-1) && (j<2)) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>";
|
||||
cout << " Type of dstPoints: "; if (j % 2 == 0) cout << "Mat of CV_32FC2"; else cout << "vector <Point2f>"; cout << endl;
|
||||
@ -339,14 +339,15 @@ void CV_HomographyTest::run(int)
|
||||
|
||||
continue;
|
||||
}
|
||||
case cv::RHO:
|
||||
case RANSAC:
|
||||
{
|
||||
cv::Mat mask [4]; double diff;
|
||||
|
||||
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, RANSAC, reproj_threshold, mask[0]),
|
||||
cv::findHomography(src_mat_2f, dst_vec, RANSAC, reproj_threshold, mask[1]),
|
||||
cv::findHomography(src_vec, dst_mat_2f, RANSAC, reproj_threshold, mask[2]),
|
||||
cv::findHomography(src_vec, dst_vec, RANSAC, reproj_threshold, mask[3]) };
|
||||
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, method, reproj_threshold, mask[0]),
|
||||
cv::findHomography(src_mat_2f, dst_vec, method, reproj_threshold, mask[1]),
|
||||
cv::findHomography(src_vec, dst_mat_2f, method, reproj_threshold, mask[2]),
|
||||
cv::findHomography(src_vec, dst_vec, method, reproj_threshold, mask[3]) };
|
||||
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
@ -370,7 +371,7 @@ void CV_HomographyTest::run(int)
|
||||
|
||||
if (code)
|
||||
{
|
||||
print_information_3(j, N, mask[j]);
|
||||
print_information_3(method, j, N, mask[j]);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
@ -466,14 +467,15 @@ void CV_HomographyTest::run(int)
|
||||
|
||||
continue;
|
||||
}
|
||||
case cv::RHO:
|
||||
case RANSAC:
|
||||
{
|
||||
cv::Mat mask_res [4];
|
||||
|
||||
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, RANSAC, reproj_threshold, mask_res[0]),
|
||||
cv::findHomography(src_mat_2f, dst_vec, RANSAC, reproj_threshold, mask_res[1]),
|
||||
cv::findHomography(src_vec, dst_mat_2f, RANSAC, reproj_threshold, mask_res[2]),
|
||||
cv::findHomography(src_vec, dst_vec, RANSAC, reproj_threshold, mask_res[3]) };
|
||||
Mat H_res_64 [4] = { cv::findHomography(src_mat_2f, dst_mat_2f, method, reproj_threshold, mask_res[0]),
|
||||
cv::findHomography(src_mat_2f, dst_vec, method, reproj_threshold, mask_res[1]),
|
||||
cv::findHomography(src_vec, dst_mat_2f, method, reproj_threshold, mask_res[2]),
|
||||
cv::findHomography(src_vec, dst_vec, method, reproj_threshold, mask_res[3]) };
|
||||
|
||||
for (int j = 0; j < 4; ++j)
|
||||
{
|
||||
@ -488,7 +490,7 @@ void CV_HomographyTest::run(int)
|
||||
|
||||
if (code)
|
||||
{
|
||||
print_information_3(j, N, mask_res[j]);
|
||||
print_information_3(method, j, N, mask_res[j]);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
@ -520,14 +522,14 @@ void CV_HomographyTest::run(int)
|
||||
|
||||
if (mask_res[j].at<bool>(k, 0) != (diff <= reproj_threshold))
|
||||
{
|
||||
print_information_6(j, N, k, diff, mask_res[j].at<bool>(k, 0));
|
||||
print_information_6(method, j, N, k, diff, mask_res[j].at<bool>(k, 0));
|
||||
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mask.at<bool>(k, 0) && !mask_res[j].at<bool>(k, 0))
|
||||
{
|
||||
print_information_7(j, N, k, diff, mask.at<bool>(k, 0), mask_res[j].at<bool>(k, 0));
|
||||
print_information_7(method, j, N, k, diff, mask.at<bool>(k, 0), mask_res[j].at<bool>(k, 0));
|
||||
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_MASK, MESSAGE_RANSAC_MASK_5);
|
||||
return;
|
||||
}
|
||||
@ -547,7 +549,7 @@ void CV_HomographyTest::run(int)
|
||||
|
||||
if (diff - cv::norm(noise_2d, NORM_TYPE[l]) > max_2diff)
|
||||
{
|
||||
print_information_8(j, N, k, l, diff - cv::norm(noise_2d, NORM_TYPE[l]));
|
||||
print_information_8(method, j, N, k, l, diff - cv::norm(noise_2d, NORM_TYPE[l]));
|
||||
CV_Error(CALIB3D_HOMOGRAPHY_ERROR_RANSAC_DIFF, MESSAGE_RANSAC_DIFF);
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user