18 #include <opencv2/calib3d/calib3d.hpp>
19 #include <opencv2/core/core.hpp>
27 CameraParameters::CameraParameters()
29 CameraMatrix = cv::Mat();
30 Distorsion = cv::Mat();
31 ExtrinsicMatrix = cv::Mat();
32 CamSize = cv::Size(-1, -1);
39 CameraParameters::CameraParameters(cv::Mat cameraMatrix, cv::Mat distorsionCoeff, cv::Size size)
41 setParams(cameraMatrix, distorsionCoeff, size);
63 void CameraParameters::clear()
65 CameraMatrix = cv::Mat();
66 CamSize = cv::Size(-1, -1);
67 Distorsion = cv::Mat();
71 void CameraParameters::setParams(cv::Mat cameraMatrix, cv::Mat distorsionCoeff, cv::Size size)
74 ExtrinsicMatrix = cv::Mat::zeros(1, 3, CV_64FC1);
75 if (cameraMatrix.rows == 3 && cameraMatrix.cols == 4)
77 ExtrinsicMatrix.at<
double>(0, 0) = cameraMatrix.at<
double>(0, 3);
78 ExtrinsicMatrix.at<
double>(0, 1) = cameraMatrix.at<
double>(1, 3);
79 ExtrinsicMatrix.at<
double>(0, 2) = cameraMatrix.at<
double>(2, 3);
82 auxCamMatrix = cameraMatrix(cv::Rect(0, 0, 3, 3)).clone();
83 cameraMatrix = auxCamMatrix;
86 if (cameraMatrix.rows != 3 || cameraMatrix.cols != 3)
87 throw cv::Exception(9000,
"invalid input cameraMatrix",
"CameraParameters::setParams",
89 cameraMatrix.convertTo(CameraMatrix, CV_32FC1);
90 if (distorsionCoeff.total() < 4 || distorsionCoeff.total() >= 7)
91 throw cv::Exception(9000,
"invalid input distorsionCoeff",
92 "CameraParameters::setParams", __FILE__, __LINE__);
95 distorsionCoeff.convertTo(Distorsion, CV_32FC1);
106 cv::Point3f CameraParameters::getCameraLocation(
const cv::Mat &Rvec,
const cv::Mat &Tvec)
108 cv::Mat m33(3, 3, CV_32FC1);
109 cv::Rodrigues(Rvec, m33);
111 cv::Mat m44 = cv::Mat::eye(4, 4, CV_32FC1);
112 for (
int i = 0; i < 3; i++)
113 for (
int j = 0; j < 3; j++)
114 m44.at<
float>(i, j) = m33.at<
float>(i, j);
117 for (
int i = 0; i < 3; i++)
118 m44.at<
float>(i, 3) = Tvec.ptr<
float>(0)[i];
123 return cv::Point3f(m44.at<
float>(0, 3), m44.at<
float>(1, 3), m44.at<
float>(2, 3));
128 void CameraParameters::saveToFile(
string path,
bool inXML)
131 throw cv::Exception(9006,
"invalid object",
"CameraParameters::saveToFile", __FILE__, __LINE__);
134 ofstream file(path.c_str());
136 throw cv::Exception(9006,
"could not open file:" + path,
137 "CameraParameters::saveToFile", __FILE__, __LINE__);
138 file <<
"# Aruco 1.0 CameraParameters" << endl;
139 file <<
"fx = " << CameraMatrix.at<
float>(0, 0) << endl;
140 file <<
"cx = " << CameraMatrix.at<
float>(0, 2) << endl;
141 file <<
"fy = " << CameraMatrix.at<
float>(1, 1) << endl;
142 file <<
"cy = " << CameraMatrix.at<
float>(1, 2) << endl;
143 file <<
"k1 = " << Distorsion.at<
float>(0, 0) << endl;
144 file <<
"k2 = " << Distorsion.at<
float>(1, 0) << endl;
145 file <<
"p1 = " << Distorsion.at<
float>(2, 0) << endl;
146 file <<
"p2 = " << Distorsion.at<
float>(3, 0) << endl;
147 file <<
"tx = " << ExtrinsicMatrix.at<
float>(0, 0) << std::endl;
148 file <<
"ty = " << ExtrinsicMatrix.at<
float>(1, 0) << std::endl;
149 file <<
"tz = " << ExtrinsicMatrix.at<
float>(2, 0) << std::endl;
150 file <<
"width = " << CamSize.width << endl;
151 file <<
"height = " << CamSize.height << endl;
155 cv::FileStorage fs(path, cv::FileStorage::WRITE);
156 fs <<
"image_width" << CamSize.width;
157 fs <<
"image_height" << CamSize.height;
158 fs <<
"camera_matrix" << CameraMatrix;
159 fs <<
"distortion_coefficients" << Distorsion;
160 fs <<
"extrinsics" << ExtrinsicMatrix;
166 void CameraParameters::resize(cv::Size size)
169 throw cv::Exception(9007,
"invalid object",
"CameraParameters::resize", __FILE__, __LINE__);
174 float AxFactor = float(size.width) / float(CamSize.width);
175 float AyFactor = float(size.height) / float(CamSize.height);
176 CameraMatrix.at<
float>(0, 0) *= AxFactor;
177 CameraMatrix.at<
float>(0, 2) *= AxFactor;
178 CameraMatrix.at<
float>(1, 1) *= AyFactor;
179 CameraMatrix.at<
float>(1, 2) *= AyFactor;
189 void CameraParameters::readFromXMLFile(
string filePath)
191 cv::FileStorage fs(filePath, cv::FileStorage::READ);
193 throw std::runtime_error(
"CameraParameters::readFromXMLFile could not open file:" + filePath);
195 cv::Mat MCamera, MDist, MExtrinsics;
198 fs[
"image_width"] >> w;
199 fs[
"image_height"] >> h;
200 fs[
"distortion_coefficients"] >> MDist;
201 fs[
"camera_matrix"] >> MCamera;
202 fs[
"extrinsics"] >> MExtrinsics;
204 if (MCamera.cols == 0 || MCamera.rows == 0)
206 fs[
"Camera_Matrix"] >> MCamera;
207 if (MCamera.cols == 0 || MCamera.rows == 0)
208 throw cv::Exception(9007,
"File :" + filePath +
" does not contains valid camera matrix",
209 "CameraParameters::readFromXML", __FILE__, __LINE__);
212 if (w == -1 || h == 0)
214 fs[
"image_Width"] >> w;
215 fs[
"image_Height"] >> h;
216 if (w == -1 || h == 0)
217 throw cv::Exception(9007,
"File :" + filePath +
" does not contains valid camera dimensions",
218 "CameraParameters::readFromXML", __FILE__, __LINE__);
220 if (MCamera.type() != CV_32FC1)
221 MCamera.convertTo(CameraMatrix, CV_32FC1);
223 CameraMatrix = MCamera;
225 if (MDist.total() < 4)
227 fs[
"Distortion_Coefficients"] >> MDist;
228 if (MDist.total() < 4)
229 throw cv::Exception(9007,
"File :" + filePath +
" does not contains valid distortion_coefficients",
230 "CameraParameters::readFromXML", __FILE__, __LINE__);
234 MDist.convertTo(mdist32, CV_32FC1);
239 Distorsion.create(1, 5, CV_32FC1);
240 for (
int i = 0; i < 5; i++)
241 Distorsion.ptr<
float>(0)[i] = mdist32.ptr<
float>(0)[i];
248 void CameraParameters::glGetProjectionMatrix(cv::Size orgImgSize, cv::Size size,
249 double proj_matrix[16],
double gnear,
250 double gfar,
bool invert)
252 if (cv::countNonZero(Distorsion) != 0)
253 std::cerr <<
"CameraParameters::glGetProjectionMatrix :: The camera has distortion coefficients "
254 << __FILE__ <<
" " << __LINE__ << endl;
255 if (isValid() ==
false)
256 throw cv::Exception(9100,
"invalid camera parameters",
257 "CameraParameters::glGetProjectionMatrix", __FILE__, __LINE__);
260 double Ax = double(size.width) / double(orgImgSize.width);
261 double Ay = double(size.height) / double(orgImgSize.height);
262 double _fx = CameraMatrix.at<
float>(0, 0) * Ax;
263 double _cx = CameraMatrix.at<
float>(0, 2) * Ax;
264 double _fy = CameraMatrix.at<
float>(1, 1) * Ay;
265 double _cy = CameraMatrix.at<
float>(1, 2) * Ay;
266 double cparam[3][4] = { { _fx, 0, _cx, 0 }, { 0, _fy, _cy, 0 }, { 0, 0, 1, 0 } };
268 argConvGLcpara2(cparam, size.width, size.height, gnear, gfar, proj_matrix, invert);
275 double CameraParameters::norm(
double a,
double b,
double c)
277 return (sqrt(a * a + b * b + c * c));
285 double CameraParameters::dot(
double a1,
double a2,
double a3,
double b1,
double b2,
double b3)
287 return (a1 * b1 + a2 * b2 + a3 * b3);
295 void CameraParameters::argConvGLcpara2(
double cparam[3][4],
int width,
int height,
296 double gnear,
double gfar,
double m[16],
bool invert)
300 double p[3][3], q[4][4];
303 cparam[0][2] *= -1.0;
304 cparam[1][2] *= -1.0;
305 cparam[2][2] *= -1.0;
307 if (arParamDecompMat(cparam, icpara, trans) < 0)
308 throw cv::Exception(9002,
"parameter error",
"MarkerDetector::argConvGLcpara2",
311 for (i = 0; i < 3; i++)
313 for (j = 0; j < 3; j++)
315 p[i][j] = icpara[i][j] / icpara[2][2];
318 q[0][0] = (2.0 * p[0][0] / width);
319 q[0][1] = (2.0 * p[0][1] / width);
320 q[0][2] = ((2.0 * p[0][2] / width) - 1.0);
324 q[1][1] = (2.0 * p[1][1] / height);
325 q[1][2] = ((2.0 * p[1][2] / height) - 1.0);
330 q[2][2] = (gfar + gnear) / (gfar - gnear);
331 q[2][3] = -2.0 * gfar * gnear / (gfar - gnear);
338 for (i = 0; i < 4; i++)
340 for (j = 0; j < 3; j++)
342 m[i + j * 4] = q[i][0] * trans[0][j] + q[i][1] * trans[1][j] + q[i][2] * trans[2][j];
345 q[i][0] * trans[0][3] + q[i][1] * trans[1][3] + q[i][2] * trans[2][3] + q[i][3];
361 int CameraParameters::arParamDecompMat(
double source[3][4],
double cpara[3][4],
366 double rem1, rem2, rem3;
368 if (source[2][3] >= 0)
370 for (r = 0; r < 3; r++)
372 for (c = 0; c < 4; c++)
374 Cpara[r][c] = source[r][c];
380 for (r = 0; r < 3; r++)
382 for (c = 0; c < 4; c++)
384 Cpara[r][c] = -(source[r][c]);
389 for (r = 0; r < 3; r++)
391 for (c = 0; c < 4; c++)
396 cpara[2][2] = norm(Cpara[2][0], Cpara[2][1], Cpara[2][2]);
397 trans[2][0] = Cpara[2][0] / cpara[2][2];
398 trans[2][1] = Cpara[2][1] / cpara[2][2];
399 trans[2][2] = Cpara[2][2] / cpara[2][2];
400 trans[2][3] = Cpara[2][3] / cpara[2][2];
403 dot(trans[2][0], trans[2][1], trans[2][2], Cpara[1][0], Cpara[1][1], Cpara[1][2]);
404 rem1 = Cpara[1][0] - cpara[1][2] * trans[2][0];
405 rem2 = Cpara[1][1] - cpara[1][2] * trans[2][1];
406 rem3 = Cpara[1][2] - cpara[1][2] * trans[2][2];
407 cpara[1][1] = norm(rem1, rem2, rem3);
408 trans[1][0] = rem1 / cpara[1][1];
409 trans[1][1] = rem2 / cpara[1][1];
410 trans[1][2] = rem3 / cpara[1][1];
413 dot(trans[2][0], trans[2][1], trans[2][2], Cpara[0][0], Cpara[0][1], Cpara[0][2]);
415 dot(trans[1][0], trans[1][1], trans[1][2], Cpara[0][0], Cpara[0][1], Cpara[0][2]);
416 rem1 = Cpara[0][0] - cpara[0][1] * trans[1][0] - cpara[0][2] * trans[2][0];
417 rem2 = Cpara[0][1] - cpara[0][1] * trans[1][1] - cpara[0][2] * trans[2][1];
418 rem3 = Cpara[0][2] - cpara[0][1] * trans[1][2] - cpara[0][2] * trans[2][2];
419 cpara[0][0] = norm(rem1, rem2, rem3);
420 trans[0][0] = rem1 / cpara[0][0];
421 trans[0][1] = rem2 / cpara[0][0];
422 trans[0][2] = rem3 / cpara[0][0];
424 trans[1][3] = (Cpara[1][3] - cpara[1][2] * trans[2][3]) / cpara[1][1];
426 (Cpara[0][3] - cpara[0][1] * trans[1][3] - cpara[0][2] * trans[2][3]) / cpara[0][0];
428 for (r = 0; r < 3; r++)
430 for (c = 0; c < 3; c++)
432 cpara[r][c] /= cpara[2][2];
442 void CameraParameters::OgreGetProjectionMatrix(cv::Size orgImgSize, cv::Size size,
443 double proj_matrix[16],
double gnear,
444 double gfar,
bool invert)
446 double temp_matrix[16];
447 (*this).glGetProjectionMatrix(orgImgSize, size, temp_matrix, gnear, gfar, invert);
448 proj_matrix[0] = -temp_matrix[0];
449 proj_matrix[1] = -temp_matrix[4];
450 proj_matrix[2] = -temp_matrix[8];
451 proj_matrix[3] = temp_matrix[12];
453 proj_matrix[4] = -temp_matrix[1];
454 proj_matrix[5] = -temp_matrix[5];
455 proj_matrix[6] = -temp_matrix[9];
456 proj_matrix[7] = temp_matrix[13];
458 proj_matrix[8] = -temp_matrix[2];
459 proj_matrix[9] = -temp_matrix[6];
460 proj_matrix[10] = -temp_matrix[10];
461 proj_matrix[11] = temp_matrix[14];
463 proj_matrix[12] = -temp_matrix[3];
464 proj_matrix[13] = -temp_matrix[7];
465 proj_matrix[14] = -temp_matrix[11];
466 proj_matrix[15] = temp_matrix[15];
478 if (R.type() == CV_64F)
480 assert(T.type() == CV_64F);
481 cv::Mat Matrix = cv::Mat::eye(4, 4, CV_64FC1);
483 cv::Mat R33 = cv::Mat(Matrix, cv::Rect(0, 0, 3, 3));
486 cv::Rodrigues(R, R33);
488 else if (R.total() == 9)
491 R.convertTo(R64, CV_64F);
494 for (
int i = 0; i < 3; i++)
495 Matrix.at<
double>(i, 3) = T.ptr<
double>(0)[i];
498 else if (R.depth() == CV_32F)
500 cv::Mat Matrix = cv::Mat::eye(4, 4, CV_32FC1);
501 cv::Mat R33 = cv::Mat(Matrix, cv::Rect(0, 0, 3, 3));
504 cv::Rodrigues(R, R33);
506 else if (R.total() == 9)
509 R.convertTo(R32, CV_32F);
513 for (
int i = 0; i < 3; i++)
514 Matrix.at<
float>(i, 3) = T.ptr<
float>(0)[i];
523 M.convertTo(MTyped, forceType);
531 for (std::size_t i = 0; i < cp.
CameraMatrix.total(); i++)
534 for (std::size_t i = 0; i < cp.
Distorsion.total(); i++)
545 for (std::size_t i = 0; i < cp.
CameraMatrix.total(); i++)
550 for (std::size_t i = 0; i < cp.
Distorsion.total(); i++)