mirror of
https://github.com/opencv/opencv.git
synced 2026-09-25 04:09:57 +03:00
Merge pull request #29910 from vrabaud:k4
Only optimize upon 4 distortion parameters when the input has dim==4
This commit is contained in:
@@ -2861,9 +2861,10 @@ static Mat prepareDistCoeffs(Mat& distCoeffs0, int rtype, int outputSize)
|
|||||||
int n = sz.area();
|
int n = sz.area();
|
||||||
if (n > 0)
|
if (n > 0)
|
||||||
CV_Assert(sz.width == 1 || sz.height == 1);
|
CV_Assert(sz.width == 1 || sz.height == 1);
|
||||||
|
CV_Assert(n == 0 || n == 4 || n == 5 || n == 8 || n == 12 || n == 14);
|
||||||
CV_Assert((int)distCoeffs0.total() <= outputSize);
|
CV_Assert((int)distCoeffs0.total() <= outputSize);
|
||||||
Mat distCoeffs = Mat::zeros(sz.width == 1 ? Size(1, outputSize) : Size(outputSize, 1), rtype);
|
Mat distCoeffs = Mat::zeros(sz.width == 1 ? Size(1, outputSize) : Size(outputSize, 1), rtype);
|
||||||
if( n == 4 || n == 5 || n == 8 || n == 12 || n == 14 )
|
if( n > 0 )
|
||||||
{
|
{
|
||||||
distCoeffs0.convertTo(distCoeffs(Rect(Point(), sz)), rtype);
|
distCoeffs0.convertTo(distCoeffs(Rect(Point(), sz)), rtype);
|
||||||
}
|
}
|
||||||
@@ -2932,6 +2933,7 @@ double calibrateCameraRO(InputArrayOfArrays _objectPoints,
|
|||||||
Mat cameraMatrix = _cameraMatrix.getMat();
|
Mat cameraMatrix = _cameraMatrix.getMat();
|
||||||
cameraMatrix = prepareCameraMatrix(cameraMatrix, rtype, flags);
|
cameraMatrix = prepareCameraMatrix(cameraMatrix, rtype, flags);
|
||||||
Mat distCoeffs = _distCoeffs.getMat();
|
Mat distCoeffs = _distCoeffs.getMat();
|
||||||
|
int dist_total = distCoeffs.total();
|
||||||
distCoeffs =
|
distCoeffs =
|
||||||
(flags & CALIB_THIN_PRISM_MODEL) &&
|
(flags & CALIB_THIN_PRISM_MODEL) &&
|
||||||
!(flags & CALIB_TILTED_MODEL) ?
|
!(flags & CALIB_TILTED_MODEL) ?
|
||||||
@@ -2940,7 +2942,10 @@ double calibrateCameraRO(InputArrayOfArrays _objectPoints,
|
|||||||
if( !(flags & CALIB_RATIONAL_MODEL) &&
|
if( !(flags & CALIB_RATIONAL_MODEL) &&
|
||||||
(!(flags & CALIB_THIN_PRISM_MODEL)) &&
|
(!(flags & CALIB_THIN_PRISM_MODEL)) &&
|
||||||
(!(flags & CALIB_TILTED_MODEL)))
|
(!(flags & CALIB_TILTED_MODEL)))
|
||||||
distCoeffs = distCoeffs.rows == 1 ? distCoeffs.colRange(0, 5) : distCoeffs.rowRange(0, 5);
|
{
|
||||||
|
int out_size = (dist_total == 0) ? 5 : std::min(5, dist_total);
|
||||||
|
distCoeffs = distCoeffs.rows == 1 ? distCoeffs.colRange(0, out_size) : distCoeffs.rowRange(0, out_size);
|
||||||
|
}
|
||||||
|
|
||||||
int nimages = int(_objectPoints.total());
|
int nimages = int(_objectPoints.total());
|
||||||
CV_Assert( nimages > 0 );
|
CV_Assert( nimages > 0 );
|
||||||
@@ -3115,6 +3120,8 @@ double stereoCalibrate( InputArrayOfArrays _objectPoints,
|
|||||||
Mat cameraMatrix2 = _cameraMatrix2.getMat();
|
Mat cameraMatrix2 = _cameraMatrix2.getMat();
|
||||||
Mat distCoeffs1 = _distCoeffs1.getMat();
|
Mat distCoeffs1 = _distCoeffs1.getMat();
|
||||||
Mat distCoeffs2 = _distCoeffs2.getMat();
|
Mat distCoeffs2 = _distCoeffs2.getMat();
|
||||||
|
int dist1_total = distCoeffs1.total();
|
||||||
|
int dist2_total = distCoeffs2.total();
|
||||||
cameraMatrix1 = prepareCameraMatrix(cameraMatrix1, rtype, flags);
|
cameraMatrix1 = prepareCameraMatrix(cameraMatrix1, rtype, flags);
|
||||||
cameraMatrix2 = prepareCameraMatrix(cameraMatrix2, rtype, flags);
|
cameraMatrix2 = prepareCameraMatrix(cameraMatrix2, rtype, flags);
|
||||||
distCoeffs1 = prepareDistCoeffs(distCoeffs1, rtype, 14);
|
distCoeffs1 = prepareDistCoeffs(distCoeffs1, rtype, 14);
|
||||||
@@ -3124,8 +3131,10 @@ double stereoCalibrate( InputArrayOfArrays _objectPoints,
|
|||||||
(!(flags & CALIB_THIN_PRISM_MODEL)) &&
|
(!(flags & CALIB_THIN_PRISM_MODEL)) &&
|
||||||
(!(flags & CALIB_TILTED_MODEL)))
|
(!(flags & CALIB_TILTED_MODEL)))
|
||||||
{
|
{
|
||||||
distCoeffs1 = distCoeffs1.rows == 1 ? distCoeffs1.colRange(0, 5) : distCoeffs1.rowRange(0, 5);
|
int out_size1 = (dist1_total == 0) ? 5 : std::min(5, dist1_total);
|
||||||
distCoeffs2 = distCoeffs2.rows == 1 ? distCoeffs2.colRange(0, 5) : distCoeffs2.rowRange(0, 5);
|
int out_size2 = (dist2_total == 0) ? 5 : std::min(5, dist2_total);
|
||||||
|
distCoeffs1 = distCoeffs1.rows == 1 ? distCoeffs1.colRange(0, out_size1) : distCoeffs1.rowRange(0, out_size1);
|
||||||
|
distCoeffs2 = distCoeffs2.rows == 1 ? distCoeffs2.colRange(0, out_size2) : distCoeffs2.rowRange(0, out_size2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((flags & CALIB_USE_EXTRINSIC_GUESS) == 0)
|
if((flags & CALIB_USE_EXTRINSIC_GUESS) == 0)
|
||||||
|
|||||||
@@ -1898,4 +1898,51 @@ TEST(Calib_StereoCalibrate, regression_22421)
|
|||||||
EXPECT_LE(terr, 0.0000001);
|
EXPECT_LE(terr, 0.0000001);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Calib_CalibrateCamera, size4DistortionCoeffs)
|
||||||
|
{
|
||||||
|
std::vector<std::vector<cv::Point3f>> objectPoints(3);
|
||||||
|
std::vector<std::vector<cv::Point2f>> imagePoints(3);
|
||||||
|
cv::Size boardSize(9, 6);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int y = 0; y < boardSize.height; y++) {
|
||||||
|
for (int x = 0; x < boardSize.width; x++) {
|
||||||
|
objectPoints[i].push_back(cv::Point3f(x * 0.1f, y * 0.1f, 0.f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Matx33d cameraMatrix(800, 0, 320, 0, 800, 240, 0, 0, 1);
|
||||||
|
cv::Vec4d distCoeffs(0.1, -0.05, 0.001, -0.002);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
cv::Vec3d rvec(0.1 * i, -0.2 * i, 0.05 * i);
|
||||||
|
cv::Vec3d tvec(-0.1 * i, 0.05 * i, 1.0 + 0.1 * i);
|
||||||
|
cv::projectPoints(objectPoints[i], rvec, tvec, cameraMatrix, distCoeffs, imagePoints[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. Test calibrateCamera
|
||||||
|
cv::Matx33d cameraMatrix_est = cameraMatrix;
|
||||||
|
cv::Mat1d distCoeffs_est = cv::Mat1d::zeros(1, 4);
|
||||||
|
std::vector<cv::Mat> rvecs, tvecs;
|
||||||
|
double rms = cv::calibrateCamera(objectPoints, imagePoints, cv::Size(640, 480),
|
||||||
|
cameraMatrix_est, distCoeffs_est, rvecs, tvecs,
|
||||||
|
cv::CALIB_USE_INTRINSIC_GUESS);
|
||||||
|
|
||||||
|
EXPECT_LT(rms, 1e-4);
|
||||||
|
EXPECT_LE(cv::norm(cv::Vec4d(distCoeffs_est), distCoeffs, NORM_INF), 1e-4);
|
||||||
|
|
||||||
|
// 2. Test stereoCalibrate
|
||||||
|
cv::Matx33d K1 = cameraMatrix;
|
||||||
|
cv::Matx33d K2 = cameraMatrix;
|
||||||
|
cv::Mat1d D1 = cv::Mat1d::zeros(1, 4);
|
||||||
|
cv::Mat1d D2 = cv::Mat1d::zeros(1, 4);
|
||||||
|
cv::Mat R, T, E, F;
|
||||||
|
double stereo_rms = cv::stereoCalibrate(objectPoints, imagePoints, imagePoints,
|
||||||
|
K1, D1, K2, D2, cv::Size(640, 480),
|
||||||
|
R, T, E, F, cv::CALIB_USE_INTRINSIC_GUESS);
|
||||||
|
|
||||||
|
EXPECT_LT(stereo_rms, 1e-4);
|
||||||
|
EXPECT_LE(cv::norm(cv::Vec4d(D1), distCoeffs, NORM_INF), 1e-4);
|
||||||
|
EXPECT_LE(cv::norm(cv::Vec4d(D2), distCoeffs, NORM_INF), 1e-4);
|
||||||
|
}
|
||||||
|
|
||||||
}} // namespace
|
}} // namespace
|
||||||
|
|||||||
Reference in New Issue
Block a user