mirror of
https://github.com/opencv/opencv.git
synced 2025-01-20 15:59:24 +08:00
solvePnPRansac implementation for Fisheye camera model
This commit is contained in:
parent
f106866d3e
commit
a0471acdd3
@ -4098,6 +4098,53 @@ optimization. It is the \f$max(width,height)/\pi\f$ or the provided \f$f_x\f$, \
|
|||||||
TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 10, 1e-8)
|
TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 10, 1e-8)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Finds an object pose from 3D-2D point correspondences using the RANSAC scheme for fisheye camera moodel.
|
||||||
|
|
||||||
|
@param objectPoints Array of object points in the object coordinate space, Nx3 1-channel or
|
||||||
|
1xN/Nx1 3-channel, where N is the number of points. vector\<Point3d\> can be also passed here.
|
||||||
|
@param imagePoints Array of corresponding image points, Nx2 1-channel or 1xN/Nx1 2-channel,
|
||||||
|
where N is the number of points. vector\<Point2d\> can be also passed here.
|
||||||
|
@param cameraMatrix Input camera intrinsic matrix \f$\cameramatrix{A}\f$ .
|
||||||
|
@param distCoeffs Input vector of distortion coefficients (4x1/1x4).
|
||||||
|
@param rvec Output rotation vector (see @ref Rodrigues ) that, together with tvec, brings points from
|
||||||
|
the model coordinate system to the camera coordinate system.
|
||||||
|
@param tvec Output translation vector.
|
||||||
|
@param useExtrinsicGuess Parameter used for #SOLVEPNP_ITERATIVE. If true (1), the function uses
|
||||||
|
the provided rvec and tvec values as initial approximations of the rotation and translation
|
||||||
|
vectors, respectively, and further optimizes them.
|
||||||
|
@param iterationsCount Number of iterations.
|
||||||
|
@param reprojectionError Inlier threshold value used by the RANSAC procedure. The parameter value
|
||||||
|
is the maximum allowed distance between the observed and computed point projections to consider it
|
||||||
|
an inlier.
|
||||||
|
@param confidence The probability that the algorithm produces a useful result.
|
||||||
|
@param inliers Output vector that contains indices of inliers in objectPoints and imagePoints .
|
||||||
|
@param flags Method for solving a PnP problem: see @ref calib3d_solvePnP_flags
|
||||||
|
This function returns the rotation and the translation vectors that transform a 3D point expressed in the object
|
||||||
|
coordinate frame to the camera coordinate frame, using different methods:
|
||||||
|
- P3P methods (@ref SOLVEPNP_P3P, @ref SOLVEPNP_AP3P): need 4 input points to return a unique solution.
|
||||||
|
- @ref SOLVEPNP_IPPE Input points must be >= 4 and object points must be coplanar.
|
||||||
|
- @ref SOLVEPNP_IPPE_SQUARE Special case suitable for marker pose estimation.
|
||||||
|
Number of input points must be 4. Object points must be defined in the following order:
|
||||||
|
- point 0: [-squareLength / 2, squareLength / 2, 0]
|
||||||
|
- point 1: [ squareLength / 2, squareLength / 2, 0]
|
||||||
|
- point 2: [ squareLength / 2, -squareLength / 2, 0]
|
||||||
|
- point 3: [-squareLength / 2, -squareLength / 2, 0]
|
||||||
|
- for all the other flags, number of input points must be >= 4 and object points can be in any configuration.
|
||||||
|
@param criteria Termination criteria for internal undistortPoints call.
|
||||||
|
The function interally undistorts points with @ref undistortPoints and call @ref cv::solvePnP,
|
||||||
|
thus the input are very similar. More information about Perspective-n-Points is described in @ref calib3d_solvePnP
|
||||||
|
for more information.
|
||||||
|
*/
|
||||||
|
CV_EXPORTS_W bool solvePnPRansac( InputArray objectPoints, InputArray imagePoints,
|
||||||
|
InputArray cameraMatrix, InputArray distCoeffs,
|
||||||
|
OutputArray rvec, OutputArray tvec,
|
||||||
|
bool useExtrinsicGuess = false, int iterationsCount = 100,
|
||||||
|
float reprojectionError = 8.0, double confidence = 0.99,
|
||||||
|
OutputArray inliers = noArray(),int flags = SOLVEPNP_ITERATIVE,
|
||||||
|
TermCriteria criteria = TermCriteria(TermCriteria::MAX_ITER + TermCriteria::EPS, 10, 1e-8)
|
||||||
|
);
|
||||||
|
|
||||||
//! @} calib3d_fisheye
|
//! @} calib3d_fisheye
|
||||||
} // end namespace fisheye
|
} // end namespace fisheye
|
||||||
|
|
||||||
|
@ -1120,6 +1120,22 @@ bool cv::fisheye::solvePnP( InputArray opoints, InputArray ipoints,
|
|||||||
return cv::solvePnP(opoints, imagePointsNormalized, cameraMatrix, noArray(), rvec, tvec, useExtrinsicGuess, flags);
|
return cv::solvePnP(opoints, imagePointsNormalized, cameraMatrix, noArray(), rvec, tvec, useExtrinsicGuess, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// cv::fisheye::solvePnPRansac
|
||||||
|
|
||||||
|
bool cv::fisheye::solvePnPRansac( InputArray opoints, InputArray ipoints,
|
||||||
|
InputArray cameraMatrix, InputArray distCoeffs,
|
||||||
|
OutputArray rvec, OutputArray tvec, bool useExtrinsicGuess,
|
||||||
|
int iterationsCount, float reprojectionError,
|
||||||
|
double confidence, OutputArray inliers,
|
||||||
|
int flags, TermCriteria criteria)
|
||||||
|
{
|
||||||
|
Mat imagePointsNormalized;
|
||||||
|
cv::fisheye::undistortPoints(ipoints, imagePointsNormalized, cameraMatrix, distCoeffs, noArray(), cameraMatrix, criteria);
|
||||||
|
return cv::solvePnPRansac(opoints, imagePointsNormalized, cameraMatrix, noArray(), rvec, tvec,
|
||||||
|
useExtrinsicGuess, iterationsCount, reprojectionError, confidence, inliers, flags);
|
||||||
|
}
|
||||||
|
|
||||||
namespace cv{ namespace {
|
namespace cv{ namespace {
|
||||||
void subMatrix(const Mat& src, Mat& dst, const std::vector<uchar>& cols, const std::vector<uchar>& rows)
|
void subMatrix(const Mat& src, Mat& dst, const std::vector<uchar>& cols, const std::vector<uchar>& rows)
|
||||||
{
|
{
|
||||||
|
@ -256,7 +256,52 @@ TEST_F(fisheyeTest, solvePnP)
|
|||||||
bool converged = cv::fisheye::solvePnP(obj_points, img_points, this->K, this->D, rvec_pred, tvec_pred);
|
bool converged = cv::fisheye::solvePnP(obj_points, img_points, this->K, this->D, rvec_pred, tvec_pred);
|
||||||
EXPECT_MAT_NEAR(rvec, rvec_pred, 1e-6);
|
EXPECT_MAT_NEAR(rvec, rvec_pred, 1e-6);
|
||||||
EXPECT_MAT_NEAR(this->T, tvec_pred, 1e-6);
|
EXPECT_MAT_NEAR(this->T, tvec_pred, 1e-6);
|
||||||
|
ASSERT_TRUE(converged);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(fisheyeTest, solvePnPRansac)
|
||||||
|
{
|
||||||
|
const int inliers_n = 16;
|
||||||
|
const int outliers_n = 4;
|
||||||
|
const bool use_extrinsic_guess = false;
|
||||||
|
const int iterations_count = 100;
|
||||||
|
const float reprojection_error = 1.0;
|
||||||
|
const double confidence = 0.99;
|
||||||
|
|
||||||
|
cv::Mat rvec;
|
||||||
|
cv::Rodrigues(this->R, rvec);
|
||||||
|
|
||||||
|
// inliers
|
||||||
|
cv::Mat inlier_obj_points(1, inliers_n, CV_64FC3);
|
||||||
|
theRNG().fill(inlier_obj_points, cv::RNG::NORMAL, 2, 1);
|
||||||
|
inlier_obj_points = cv::abs(inlier_obj_points) * 10;
|
||||||
|
cv::Mat inlier_img_points;
|
||||||
|
cv::fisheye::projectPoints(inlier_obj_points, inlier_img_points, rvec, this->T, this->K, this->D);
|
||||||
|
|
||||||
|
// outliers
|
||||||
|
cv::Mat outlier_obj_points(1, outliers_n, CV_64FC3);
|
||||||
|
theRNG().fill(outlier_obj_points, cv::RNG::NORMAL, 2, 1);
|
||||||
|
outlier_obj_points = cv::abs(outlier_obj_points) * 10;
|
||||||
|
cv::Mat outlier_img_points;
|
||||||
|
cv::fisheye::projectPoints(outlier_obj_points, outlier_img_points, rvec, (this->T * 10), this->K, this->D);
|
||||||
|
|
||||||
|
cv::Mat obj_points;
|
||||||
|
cv::hconcat(outlier_obj_points, inlier_obj_points, obj_points);
|
||||||
|
|
||||||
|
cv::Mat img_points;
|
||||||
|
cv::hconcat(outlier_img_points, inlier_img_points, img_points);
|
||||||
|
|
||||||
|
cv::Mat rvec_pred;
|
||||||
|
cv::Mat tvec_pred;
|
||||||
|
cv::Mat inliers_pred;
|
||||||
|
|
||||||
|
bool converged = cv::fisheye::solvePnPRansac(obj_points, img_points, this->K, this->D,
|
||||||
|
rvec_pred, tvec_pred, use_extrinsic_guess,
|
||||||
|
iterations_count, reprojection_error, confidence, inliers_pred);
|
||||||
|
|
||||||
|
EXPECT_MAT_NEAR(rvec, rvec_pred, 1e-5);
|
||||||
|
EXPECT_MAT_NEAR(this->T, tvec_pred, 1e-5);
|
||||||
|
EXPECT_EQ(inliers_pred.size[0], inliers_n);
|
||||||
ASSERT_TRUE(converged);
|
ASSERT_TRUE(converged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user