cameraparameters.cpp
Go to the documentation of this file.
1 
16 #include "cameraparameters.h"
17 
18 #include <opencv2/calib3d/calib3d.hpp>
19 #include <opencv2/core/core.hpp>
20 
21 #include <fstream>
22 #include <iostream>
23 
24 using namespace std;
25 namespace aruco
26 {
27 CameraParameters::CameraParameters()
28 {
29  CameraMatrix = cv::Mat();
30  Distorsion = cv::Mat();
31  ExtrinsicMatrix = cv::Mat();
32  CamSize = cv::Size(-1, -1);
33 }
39 CameraParameters::CameraParameters(cv::Mat cameraMatrix, cv::Mat distorsionCoeff, cv::Size size)
40 {
41  setParams(cameraMatrix, distorsionCoeff, size);
42 }
45 CameraParameters::CameraParameters(const CameraParameters &CI)
46 {
47  CI.CameraMatrix.copyTo(CameraMatrix);
48  CI.Distorsion.copyTo(Distorsion);
49  CI.ExtrinsicMatrix.copyTo(ExtrinsicMatrix);
50  CamSize = CI.CamSize;
51 }
52 
55 CameraParameters &CameraParameters::operator=(const CameraParameters &CI)
56 {
57  CI.CameraMatrix.copyTo(CameraMatrix);
58  CI.Distorsion.copyTo(Distorsion);
59  CI.ExtrinsicMatrix.copyTo(ExtrinsicMatrix);
60  CamSize = CI.CamSize;
61  return *this;
62 }
63 void CameraParameters::clear()
64 {
65  CameraMatrix = cv::Mat();
66  CamSize = cv::Size(-1, -1);
67  Distorsion = cv::Mat();
68 }
71 void CameraParameters::setParams(cv::Mat cameraMatrix, cv::Mat distorsionCoeff, cv::Size size)
72 {
73  cv::Mat auxCamMatrix;
74  ExtrinsicMatrix = cv::Mat::zeros(1, 3, CV_64FC1);
75  if (cameraMatrix.rows == 3 && cameraMatrix.cols == 4)
76  {
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);
80 
81  // Change size to 3x3
82  auxCamMatrix = cameraMatrix(cv::Rect(0, 0, 3, 3)).clone();
83  cameraMatrix = auxCamMatrix;
84  }
85 
86  if (cameraMatrix.rows != 3 || cameraMatrix.cols != 3)
87  throw cv::Exception(9000, "invalid input cameraMatrix", "CameraParameters::setParams",
88  __FILE__, __LINE__);
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__);
93  cv::Mat auxD;
94 
95  distorsionCoeff.convertTo(Distorsion, CV_32FC1);
96 
97  // Distorsion.create(1,4,CV_32FC1);
98  // for (int i=0;i<4;i++)
99  // Distorsion.ptr<float>(0)[i]=auxD.ptr<float>(0)[i];
100 
101  CamSize = size;
102 }
103 
106 cv::Point3f CameraParameters::getCameraLocation(const cv::Mat &Rvec, const cv::Mat &Tvec)
107 {
108  cv::Mat m33(3, 3, CV_32FC1);
109  cv::Rodrigues(Rvec, m33);
110 
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);
115 
116  // now, add translation information
117  for (int i = 0; i < 3; i++)
118  m44.at<float>(i, 3) = Tvec.ptr<float>(0)[i];
119 
120 
121  // invert the matrix
122  m44.inv();
123  return cv::Point3f(m44.at<float>(0, 3), m44.at<float>(1, 3), m44.at<float>(2, 3));
124 }
125 
128 void CameraParameters::saveToFile(string path, bool inXML)
129 {
130  if (!isValid())
131  throw cv::Exception(9006, "invalid object", "CameraParameters::saveToFile", __FILE__, __LINE__);
132  if (!inXML)
133  {
134  ofstream file(path.c_str());
135  if (!file)
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;
152  }
153  else
154  {
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;
161  }
162 }
163 
166 void CameraParameters::resize(cv::Size size)
167 {
168  if (!isValid())
169  throw cv::Exception(9007, "invalid object", "CameraParameters::resize", __FILE__, __LINE__);
170  if (size == CamSize)
171  return;
172  // now, read the camera size
173  // resize the camera parameters to fit this image size
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;
180  CamSize = size;
181 }
182 
183 /****
184  *
185  *
186  *
187  *
188  */
189 void CameraParameters::readFromXMLFile(string filePath)
190 {
191  cv::FileStorage fs(filePath, cv::FileStorage::READ);
192  if (!fs.isOpened())
193  throw std::runtime_error("CameraParameters::readFromXMLFile could not open file:" + filePath);
194  int w = -1, h = -1;
195  cv::Mat MCamera, MDist, MExtrinsics;
196 
197 
198  fs["image_width"] >> w;
199  fs["image_height"] >> h;
200  fs["distortion_coefficients"] >> MDist;
201  fs["camera_matrix"] >> MCamera;
202  fs["extrinsics"] >> MExtrinsics;
203 
204  if (MCamera.cols == 0 || MCamera.rows == 0)
205  {
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__);
210  }
211 
212  if (w == -1 || h == 0)
213  {
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__);
219  }
220  if (MCamera.type() != CV_32FC1)
221  MCamera.convertTo(CameraMatrix, CV_32FC1);
222  else
223  CameraMatrix = MCamera;
224 
225  if (MDist.total() < 4)
226  {
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__);
231  }
232  // convert to 32 and get the 4 first elements only
233  cv::Mat mdist32;
234  MDist.convertTo(mdist32, CV_32FC1);
235  // Distorsion.create(1,4,CV_32FC1);
236  // for (int i=0;i<4;i++)
237  // Distorsion.ptr<float>(0)[i]=mdist32.ptr<float>(0)[i];
238 
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];
242  CamSize.width = w;
243  CamSize.height = h;
244 }
245 /****
246  *
247  */
248 void CameraParameters::glGetProjectionMatrix(cv::Size orgImgSize, cv::Size size,
249  double proj_matrix[16], double gnear,
250  double gfar, bool invert)
251 {
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__);
258 
259  // Deterime the rsized info
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 } };
267 
268  argConvGLcpara2(cparam, size.width, size.height, gnear, gfar, proj_matrix, invert);
269 }
270 
271 /*******************
272  *
273  *
274  *******************/
275 double CameraParameters::norm(double a, double b, double c)
276 {
277  return (sqrt(a * a + b * b + c * c));
278 }
279 
280 /*******************
281  *
282  *
283  *******************/
284 
285 double CameraParameters::dot(double a1, double a2, double a3, double b1, double b2, double b3)
286 {
287  return (a1 * b1 + a2 * b2 + a3 * b3);
288 }
289 
290 /*******************
291  *
292  *
293  *******************/
294 
295 void CameraParameters::argConvGLcpara2(double cparam[3][4], int width, int height,
296  double gnear, double gfar, double m[16], bool invert)
297 {
298  double icpara[3][4];
299  double trans[3][4];
300  double p[3][3], q[4][4];
301  int i, j;
302 
303  cparam[0][2] *= -1.0;
304  cparam[1][2] *= -1.0;
305  cparam[2][2] *= -1.0;
306 
307  if (arParamDecompMat(cparam, icpara, trans) < 0)
308  throw cv::Exception(9002, "parameter error", "MarkerDetector::argConvGLcpara2",
309  __FILE__, __LINE__);
310 
311  for (i = 0; i < 3; i++)
312  {
313  for (j = 0; j < 3; j++)
314  {
315  p[i][j] = icpara[i][j] / icpara[2][2];
316  }
317  }
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);
321  q[0][3] = 0.0;
322 
323  q[1][0] = 0.0;
324  q[1][1] = (2.0 * p[1][1] / height);
325  q[1][2] = ((2.0 * p[1][2] / height) - 1.0);
326  q[1][3] = 0.0;
327 
328  q[2][0] = 0.0;
329  q[2][1] = 0.0;
330  q[2][2] = (gfar + gnear) / (gfar - gnear);
331  q[2][3] = -2.0 * gfar * gnear / (gfar - gnear);
332 
333  q[3][0] = 0.0;
334  q[3][1] = 0.0;
335  q[3][2] = 1.0;
336  q[3][3] = 0.0;
337 
338  for (i = 0; i < 4; i++)
339  {
340  for (j = 0; j < 3; j++)
341  {
342  m[i + j * 4] = q[i][0] * trans[0][j] + q[i][1] * trans[1][j] + q[i][2] * trans[2][j];
343  }
344  m[i + 3 * 4] =
345  q[i][0] * trans[0][3] + q[i][1] * trans[1][3] + q[i][2] * trans[2][3] + q[i][3];
346  }
347 
348  if (!invert)
349  {
350  m[13] = -m[13];
351  m[1] = -m[1];
352  m[5] = -m[5];
353  m[9] = -m[9];
354  }
355 }
356 /*******************
357  *
358  *
359  *******************/
360 
361 int CameraParameters::arParamDecompMat(double source[3][4], double cpara[3][4],
362  double trans[3][4])
363 {
364  int r, c;
365  double Cpara[3][4];
366  double rem1, rem2, rem3;
367 
368  if (source[2][3] >= 0)
369  {
370  for (r = 0; r < 3; r++)
371  {
372  for (c = 0; c < 4; c++)
373  {
374  Cpara[r][c] = source[r][c];
375  }
376  }
377  }
378  else
379  {
380  for (r = 0; r < 3; r++)
381  {
382  for (c = 0; c < 4; c++)
383  {
384  Cpara[r][c] = -(source[r][c]);
385  }
386  }
387  }
388 
389  for (r = 0; r < 3; r++)
390  {
391  for (c = 0; c < 4; c++)
392  {
393  cpara[r][c] = 0.0;
394  }
395  }
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];
401 
402  cpara[1][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];
411 
412  cpara[0][2] =
413  dot(trans[2][0], trans[2][1], trans[2][2], Cpara[0][0], Cpara[0][1], Cpara[0][2]);
414  cpara[0][1] =
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];
423 
424  trans[1][3] = (Cpara[1][3] - cpara[1][2] * trans[2][3]) / cpara[1][1];
425  trans[0][3] =
426  (Cpara[0][3] - cpara[0][1] * trans[1][3] - cpara[0][2] * trans[2][3]) / cpara[0][0];
427 
428  for (r = 0; r < 3; r++)
429  {
430  for (c = 0; c < 3; c++)
431  {
432  cpara[r][c] /= cpara[2][2];
433  }
434  }
435 
436  return 0;
437 }
438 
439 /******
440  *
441  */
442 void CameraParameters::OgreGetProjectionMatrix(cv::Size orgImgSize, cv::Size size,
443  double proj_matrix[16], double gnear,
444  double gfar, bool invert)
445 {
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];
452 
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];
457 
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];
462 
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];
467 }
468 /******
469  *
470  */
471 
472 cv::Mat CameraParameters::getRTMatrix(const cv::Mat &R_, const cv::Mat &T_, int forceType)
473 {
474  cv::Mat M;
475  cv::Mat R, T;
476  R_.copyTo(R);
477  T_.copyTo(T);
478  if (R.type() == CV_64F)
479  {
480  assert(T.type() == CV_64F);
481  cv::Mat Matrix = cv::Mat::eye(4, 4, CV_64FC1);
482 
483  cv::Mat R33 = cv::Mat(Matrix, cv::Rect(0, 0, 3, 3));
484  if (R.total() == 3)
485  {
486  cv::Rodrigues(R, R33);
487  }
488  else if (R.total() == 9)
489  {
490  cv::Mat R64;
491  R.convertTo(R64, CV_64F);
492  R.copyTo(R33);
493  }
494  for (int i = 0; i < 3; i++)
495  Matrix.at<double>(i, 3) = T.ptr<double>(0)[i];
496  M = Matrix;
497  }
498  else if (R.depth() == CV_32F)
499  {
500  cv::Mat Matrix = cv::Mat::eye(4, 4, CV_32FC1);
501  cv::Mat R33 = cv::Mat(Matrix, cv::Rect(0, 0, 3, 3));
502  if (R.total() == 3)
503  {
504  cv::Rodrigues(R, R33);
505  }
506  else if (R.total() == 9)
507  {
508  cv::Mat R32;
509  R.convertTo(R32, CV_32F);
510  R.copyTo(R33);
511  }
512 
513  for (int i = 0; i < 3; i++)
514  Matrix.at<float>(i, 3) = T.ptr<float>(0)[i];
515  M = Matrix;
516  }
517 
518  if (forceType == -1)
519  return M;
520  else
521  {
522  cv::Mat MTyped;
523  M.convertTo(MTyped, forceType);
524  return MTyped;
525  }
526 }
527 
528 std::ostream &operator<<(std::ostream &str, const CameraParameters &cp)
529 {
530  str << cp.CamSize.width << " " << cp.CamSize.height << " ";
531  for (std::size_t i = 0; i < cp.CameraMatrix.total(); i++)
532  str << cp.CameraMatrix.ptr<float>(0)[i] << " ";
533  str << cp.Distorsion.total() << " ";
534  for (std::size_t i = 0; i < cp.Distorsion.total(); i++)
535  str << cp.Distorsion.ptr<float>(0)[i] << " ";
536  for (std::size_t i = 0; i < cp.ExtrinsicMatrix.total(); i++)
537  str << cp.ExtrinsicMatrix.ptr<float>(0)[i] << " ";
538  return str;
539 }
540 
541 std::istream &operator>>(std::istream &str, CameraParameters &cp)
542 {
543  str >> cp.CamSize.width >> cp.CamSize.height;
544  cp.CameraMatrix.create(3, 3, CV_32F);
545  for (std::size_t i = 0; i < cp.CameraMatrix.total(); i++)
546  str >> cp.CameraMatrix.ptr<float>(0)[i];
547  int t;
548  str >> t;
549  cp.Distorsion.create(1, t, CV_32F);
550  for (std::size_t i = 0; i < cp.Distorsion.total(); i++)
551  str >> cp.Distorsion.ptr<float>(0)[i];
552  cp.Distorsion.create(1, 3, CV_32F);
553  for (std::size_t i = 0; i < cp.ExtrinsicMatrix.total(); i++)
554  str >> cp.ExtrinsicMatrix.ptr<float>(0)[i];
555  return str;
556 }
557 
558 }; // namespace aruco
aruco::operator>>
std::istream & operator>>(std::istream &str, CameraParameters &cp)
Definition: cameraparameters.cpp:541
aruco::CameraParameters
Parameters of the camera.
Definition: cameraparameters.h:29
aruco::getRTMatrix
cv::Mat getRTMatrix(const cv::Mat &R_, const cv::Mat &T_, int forceType)
Definition: ippe.cpp:33
aruco::operator<<
std::ostream & operator<<(std::ostream &str, const CameraParameters &cp)
Definition: cameraparameters.cpp:528
aruco::CameraParameters::CameraMatrix
cv::Mat CameraMatrix
Definition: cameraparameters.h:33
aruco::CameraParameters::ExtrinsicMatrix
cv::Mat ExtrinsicMatrix
Definition: cameraparameters.h:40
std
aruco
Definition: cameraparameters.h:24
aruco::CameraParameters::CamSize
cv::Size CamSize
Definition: cameraparameters.h:37
cameraparameters.h
aruco::CameraParameters::Distorsion
cv::Mat Distorsion
Definition: cameraparameters.h:35


aruco
Author(s): Rafael Muñoz Salinas , Bence Magyar
autogenerated on Sat Sep 23 2023 02:26:45