Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkCameraIntrinsics.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkCameraIntrinsics.h"
18 #include <itkMutexLockHolder.h>
19 #include <mitkEndoMacros.h>
20 #include <mitkEndoDebug.h>
21 
23  : m_Valid(false), m_Mutex(itk::FastMutexLock::New())
24 {
25  m_CameraMatrix = cv::Mat::zeros(3, 3, cv::DataType<double>::type);
26  m_CameraMatrix.at<double>(2,2) = 1.0;
27  m_DistorsionCoeffs = cv::Mat::zeros(1, 5, cv::DataType<double>::type);
28 }
29 
31  : itk::Object()
33  , m_Valid(false)
34  , m_Mutex(itk::FastMutexLock::New())
35 {
36  this->Copy(&other);
37 }
38 
40 {
41 
42 }
43 
45 {
46  return other->GetDistorsionCoeffsAsPoint4D()==
47  this->GetDistorsionCoeffsAsPoint4D() &&
48  other->GetFocalPoint()==
49  this->GetFocalPoint() &&
50  other->GetPrincipalPoint()
51  == this->GetPrincipalPoint();
52 }
53 
55 {
56  this->SetIntrinsics( other->GetCameraMatrix().clone()
57  , other->GetDistorsionCoeffs().clone() );
58  this->SetValid(other->m_Valid);
59 }
60 
62 {
64  return m_Valid;
65 }
66 
67 vnl_matrix_fixed<mitk::ScalarType, 3, 3>
69 {
70  vnl_matrix_fixed<mitk::ScalarType, 3, 3> mat;
71  mat.set_identity();
72 
73  {
75  mat(0,0) = m_CameraMatrix.at<double>(0,0);
76  mat(1,1) = m_CameraMatrix.at<double>(1,1);
77 
78  mat(0,2) = m_CameraMatrix.at<double>(0,2);
79  mat(1,2) = m_CameraMatrix.at<double>(1,2);
80  }
81 
82  return mat;
83 }
84 
86  const vnl_matrix_fixed<mitk::ScalarType, 3, 3>& _CameraMatrix )
87 {
89  m_CameraMatrix.at<double>(0,0) = _CameraMatrix(0,0);
90  m_CameraMatrix.at<double>(1,1) = _CameraMatrix(1,1);
91 
92  m_CameraMatrix.at<double>(0,2) = _CameraMatrix(0,2);
93  m_CameraMatrix.at<double>(1,2) = _CameraMatrix(1,2);
94 }
95 
96 vnl_matrix_fixed<mitk::ScalarType, 3, 4>
98 {
99  vnl_matrix_fixed<mitk::ScalarType, 3, 4> mat;
100  mat.fill(0);
101  mat.update( this->GetVnlCameraMatrix().as_matrix() );
102 
103  return mat;
104 }
105 
106 void mitk::CameraIntrinsics::SetIntrinsics( const cv::Mat& _CameraMatrix
107  , const cv::Mat& _DistorsionCoeffs)
108 {
109  {
111  if( _CameraMatrix.cols != 3 || _CameraMatrix.rows != 3)
112  throw std::invalid_argument("Wrong format of camera matrix. Should be 3x3"
113  " double.");
114 
115  endoAssertMsg( (_DistorsionCoeffs.cols == 5) &&
116  _DistorsionCoeffs.rows == 1, "Wrong format of distorsion coefficients"
117  " vector. Should be 5x1 double.");
118 
119  m_CameraMatrix = _CameraMatrix.clone();
120  m_DistorsionCoeffs = _DistorsionCoeffs.clone();
121 
122  m_Valid = true;
123  }
124  this->Modified();
125 }
126 
128  const mitk::Point3D& principalPoint,
129  const mitk::Point4D& distortionCoefficients)
130 
131 {
132  {
134  m_CameraMatrix.at<double>(0,0) = focalPoint[0];
135  m_CameraMatrix.at<double>(1,1) = focalPoint[1];
136 
137  m_CameraMatrix.at<double>(0,2) = principalPoint[0];
138  m_CameraMatrix.at<double>(1,2) = principalPoint[1];
139 
140  m_DistorsionCoeffs.at<double>(0,0) = distortionCoefficients[0];
141  m_DistorsionCoeffs.at<double>(0,1) = distortionCoefficients[1];
142  m_DistorsionCoeffs.at<double>(0,2) = distortionCoefficients[2];
143  m_DistorsionCoeffs.at<double>(0,3) = distortionCoefficients[3];
144  }
145  this->Modified();
146 }
147 
148 void mitk::CameraIntrinsics::SetFocalLength( double x, double y )
149 {
150  {
152  m_CameraMatrix.at<double>(0,0) = x;
153  m_CameraMatrix.at<double>(1,1) = y;
154  }
155  this->Modified();
156 }
157 
159 {
160  {
162  m_CameraMatrix.at<double>(0,2) = x;
163  m_CameraMatrix.at<double>(1,2) = y;
164  }
165  this->Modified();
166 }
167 
169  double p1, double p2 )
170 {
171 
172  {
174 
175  m_DistorsionCoeffs.at<double>(0,0) = k1;
176  m_DistorsionCoeffs.at<double>(0,1) = k2;
177  m_DistorsionCoeffs.at<double>(0,2) = p1;
178  m_DistorsionCoeffs.at<double>(0,3) = p2;
179  }
180  this->Modified();
181 }
182 
184 {
186  return m_CameraMatrix.clone(); // return a copy of this small matrix
187 }
188 
190 {
192  return m_DistorsionCoeffs.clone(); // return a copy of this small matrix
193 }
194 
196 {
197  const CameraIntrinsics* intrinsics = this;
198  return intrinsics->GetDistorsionCoeffs();
199 }
200 
202 {
204  std::ostringstream s; s.precision(12);
205  const cv::Mat& CameraMatrix = m_CameraMatrix;
206  const cv::Mat& DistorsionCoeffs = m_DistorsionCoeffs;
207 
208  s.str(""); s << this->GetNameOfClass() << ": ";
209  s << "fx = " << CameraMatrix.at<double>(0,0);
210  s << ", fy = " << CameraMatrix.at<double>(1,1);
211  s << ", cx = " << CameraMatrix.at<double>(0,2);
212  s << ", cy = " << CameraMatrix.at<double>(1,2);
213 
214  s << ", k1 = " << DistorsionCoeffs.at<double>(0,0);
215  s << ", k2 = " << DistorsionCoeffs.at<double>(0,1);
216  s << ", p1 = " << DistorsionCoeffs.at<double>(0,2);
217  s << ", p2 = " << DistorsionCoeffs.at<double>(0,3);
218  //s << ", k3 = " << DistorsionCoeffs.at<double>(0,4);
219 
220  return s.str();
221 }
222 
223 void mitk::CameraIntrinsics::ToXML(TiXmlElement* elem) const
224 {
226  elem->SetValue(this->GetNameOfClass());
227  std::ostringstream s; s.precision(12);
228  const cv::Mat& CameraMatrix = m_CameraMatrix;
229  s.str(""); s << CameraMatrix.at<double>(0,0);
230  elem->SetAttribute( "fx", s.str() );
231  s.str(""); s << CameraMatrix.at<double>(1,1);
232  elem->SetAttribute( "fy", s.str() );
233  s.str(""); s << CameraMatrix.at<double>(0,2);
234  elem->SetAttribute( "cx", s.str() );
235  s.str(""); s << CameraMatrix.at<double>(1,2);
236  elem->SetAttribute( "cy", s.str() );
237 
238  const cv::Mat& DistorsionCoeffs = m_DistorsionCoeffs;
239  s.str(""); s << DistorsionCoeffs.at<double>(0,0);
240  elem->SetAttribute( "k1", s.str() );
241  s.str(""); s << DistorsionCoeffs.at<double>(0,1);
242  elem->SetAttribute( "k2", s.str() );
243  s.str(""); s << DistorsionCoeffs.at<double>(0,2);
244  elem->SetAttribute( "p1", s.str() );
245  s.str(""); s << DistorsionCoeffs.at<double>(0,3);
246  elem->SetAttribute( "p2", s.str() );
247  elem->SetAttribute("Valid", m_Valid);
248  //s.str(""); s << DistorsionCoeffs.at<double>(4,0);
249  //elem->SetAttribute( "k3", s.str() );
250 }
251 
253 {
254  assert( elem );
255  assert( elem->ValueStr() == "results" );
256  cv::Mat CameraMatrix = cv::Mat::zeros(3, 3, cv::DataType<double>::type);
257  CameraMatrix.at<double>(2,2) = 1.0;
258  cv::Mat DistorsionCoeffs = cv::Mat::zeros(1, 5, cv::DataType<double>::type);
259 
260  TiXmlElement* focus_lenXElem = elem->FirstChildElement("focus_lenX");
261  endoAssert( focus_lenXElem != nullptr );
262  CameraMatrix.at<double>(0,0) = atof( focus_lenXElem->GetText() );
263 
264  TiXmlElement* focus_lenYElem = elem->FirstChildElement("focus_lenY");
265  endoAssert( focus_lenYElem != nullptr );
266  CameraMatrix.at<double>(1,1) = atof( focus_lenYElem->GetText() );
267 
268  TiXmlElement* PrincipalXElem = elem->FirstChildElement("PrincipalX");
269  endoAssert( PrincipalXElem != nullptr );
270  CameraMatrix.at<double>(0,2) = atof( PrincipalXElem->GetText() );
271 
272  TiXmlElement* PrincipalYElem = elem->FirstChildElement("PrincipalY");
273  endoAssert( PrincipalYElem != nullptr );
274  CameraMatrix.at<double>(1,2) = atof( PrincipalYElem->GetText() );
275 
276  // DISTORSION COEFFS
277 
278  TiXmlElement* Dist1Elem = elem->FirstChildElement("Dist1");
279  endoAssert( Dist1Elem != nullptr );
280  DistorsionCoeffs.at<double>(0,0) = atof( Dist1Elem->GetText() );
281 
282  TiXmlElement* Dist2Elem = elem->FirstChildElement("Dist2");
283  endoAssert( Dist2Elem != nullptr );
284  DistorsionCoeffs.at<double>(0,1) = atof( Dist2Elem->GetText() );
285 
286  TiXmlElement* Dist3Elem = elem->FirstChildElement("Dist3");
287  endoAssert( Dist3Elem != nullptr );
288  DistorsionCoeffs.at<double>(0,2) = atof( Dist3Elem->GetText() );
289 
290  TiXmlElement* Dist4Elem = elem->FirstChildElement("Dist4");
291  endoAssert( Dist4Elem != nullptr );
292  DistorsionCoeffs.at<double>(0,3) = atof( Dist4Elem->GetText() );
293 
294  int valid = 0;
295  elem->QueryIntAttribute("Valid", &valid);
296 
297  {
299  m_Valid = static_cast<bool>(valid);
300  m_CameraMatrix = CameraMatrix;
301  m_DistorsionCoeffs = DistorsionCoeffs;
302  }
303 
304  this->Modified();
305 }
306 
307 void mitk::CameraIntrinsics::FromXML(TiXmlElement* elem)
308 {
309  endoAssert ( elem );
310  MITK_DEBUG << elem->Value();
311  std::string filename;
312  if(elem->QueryStringAttribute("file", &filename) == TIXML_SUCCESS)
313  {
314  this->FromXMLFile(filename);
315  return;
316  }
317  else if(strcmp(elem->Value(), "CalibrationProject") == 0)
318  {
319  this->FromGMLCalibrationXML(elem->FirstChildElement("results"));
320  return;
321  }
322 
323  assert ( elem );
324  if(strcmp(elem->Value(), this->GetNameOfClass()) != 0)
325  elem = elem->FirstChildElement(this->GetNameOfClass());
326 
327  std::ostringstream err;
328  // CAMERA MATRIX
329  cv::Mat CameraMatrix = cv::Mat::zeros(3, 3, cv::DataType<double>::type);
330  CameraMatrix.at<double>(2,2) = 1.0;
331  double val = 0.0;
332  if(elem->QueryDoubleAttribute("fx", &val) == TIXML_SUCCESS)
333  CameraMatrix.at<double>(0,0) = val;
334  else
335  err << "fx, ";
336 
337  if(elem->QueryDoubleAttribute("fy", &val) == TIXML_SUCCESS)
338  CameraMatrix.at<double>(1,1) = val;
339  else
340  err << "fy, ";
341 
342  if(elem->QueryDoubleAttribute("cx", &val) == TIXML_SUCCESS)
343  CameraMatrix.at<double>(0,2) = val;
344  else
345  err << "cx, ";
346 
347  if(elem->QueryDoubleAttribute("cy", &val) == TIXML_SUCCESS)
348  CameraMatrix.at<double>(1,2) = val;
349  else
350  err << "cy, ";
351 
352  // DISTORSION COEFFS
353  endodebug( "creating DistorsionCoeffs from XML file")
354  cv::Mat DistorsionCoeffs = cv::Mat::zeros(1, 5, cv::DataType<double>::type);
355  if(elem->QueryDoubleAttribute("k1", &val) == TIXML_SUCCESS)
356  DistorsionCoeffs.at<double>(0,0) = val;
357  else
358  err << "k1, ";
359 
360  if(elem->QueryDoubleAttribute("k2", &val) == TIXML_SUCCESS)
361  DistorsionCoeffs.at<double>(0,1) = val;
362  else
363  err << "k2, ";
364 
365  if(elem->QueryDoubleAttribute("p1", &val) == TIXML_SUCCESS)
366  DistorsionCoeffs.at<double>(0,2) = val;
367  else
368  err << "p1, ";
369 
370  if(elem->QueryDoubleAttribute("p2", &val) == TIXML_SUCCESS)
371  DistorsionCoeffs.at<double>(0,3) = val;
372  else
373  err << "p2, ";
374 
375  DistorsionCoeffs.at<double>(0,4) = 0.0;
376 
377  /*if(elem->QueryDoubleAttribute("k3", &val) == TIXML_SUCCESS)
378  DistorsionCoeffs.at<double>(4,0) = val;
379  else
380  err << "k3, ";*/
381 
382  std::string errorStr = err.str();
383  int errLength = errorStr.length();
384  if(errLength > 0)
385  {
386  errorStr = errorStr.substr(0, errLength-2);
387  errorStr.append(" not found");
388  throw std::invalid_argument(err.str());
389  }
390 
391  int valid = 0;
392  elem->QueryIntAttribute("Valid", &valid);
393 
394  {
396  m_Valid = static_cast<bool>(valid);
397  m_CameraMatrix = CameraMatrix;
398  m_DistorsionCoeffs = DistorsionCoeffs;
399  }
400 
401  this->Modified();
402 }
403 
405 {
407  double FocalLengthX = m_CameraMatrix.at<double>(0,0);
408 
409  return FocalLengthX;
410 }
412 {
414  double FocalLengthY = m_CameraMatrix.at<double>(1,1);;
415  return FocalLengthY;
416 }
418 {
420  double PrincipalPointX = m_CameraMatrix.at<double>(0,2);
421  return PrincipalPointX;
422 }
424 {
426  double PrincipalPointY = m_CameraMatrix.at<double>(1,2);
427  return PrincipalPointY;
428 }
430 {
432  mitk::Point4D coeffs;
433 
434  coeffs[0] = m_DistorsionCoeffs.at<double>(0,0);
435  coeffs[1] = m_DistorsionCoeffs.at<double>(0,1);
436  coeffs[2] = m_DistorsionCoeffs.at<double>(0,2);
437  coeffs[3] = m_DistorsionCoeffs.at<double>(0,3);
438 
439  return coeffs;
440 }
441 
443 {
444  mitk::Point3D p;
445  p[0] = this->GetFocalLengthX();
446  p[1] = this->GetFocalLengthY();
447  p[2] = 0;
448  return p;
449 }
450 
452 {
453  mitk::Point3D p;
454  p[0] = this->GetPrincipalPointX();
455  p[1] = this->GetPrincipalPointY();
456  p[2] = 0;
457  return p;
458 }
459 
460 vnl_vector_fixed<mitk::ScalarType, 2>
462 {
463  vnl_vector_fixed<mitk::ScalarType, 2> vec;
464  vec[0] = this->GetFocalLengthX();
465  vec[1] = this->GetFocalLengthY();
466  return vec;
467 }
468 
469 vnl_vector_fixed<mitk::ScalarType, 2>
471 {
472  vnl_vector_fixed<mitk::ScalarType, 2> vec;
473  vec[0] = this->GetPrincipalPointX();
474  vec[1] = this->GetPrincipalPointY();
475  return vec;
476 }
477 
478 std::ostream& operator<< (std::ostream& os, mitk::CameraIntrinsics::Pointer p)
479 {
480  os << p->ToString();
481  return os;
482 }
483 
485 {
486  return this->ToString();
487 }
488 
490  const std::string& varName)
491 {
492  std::ostringstream s;
493  s << varName << " = [" << this->GetFocalLengthX() << " 0 "
494  << this->GetPrincipalPointX() << "; 0 " <<
495  this->GetFocalLengthY() << " " << this->GetPrincipalPointY() << ";"
496  << " 0 0 1 ];";
497  return s.str();
498 }
499 
501 {
503  m_Valid = valid;
504 }
505 
506 itk::LightObject::Pointer mitk::CameraIntrinsics::InternalClone() const
507 {
508  itk::LightObject::Pointer result(new Self(*this));
509  result->UnRegister();
510  return result;
511 }
itk::SmartPointer< Self > Pointer
void FromXML(TiXmlElement *elem) override
MITKCORE_EXPORT std::ostream & operator<<(std::ostream &o, DataNode::Pointer &dtn)
class representing camera intrinsics and related functions
vnl_matrix_fixed< mitk::ScalarType, 3, 3 > GetVnlCameraMatrix() const
void FromGMLCalibrationXML(TiXmlElement *elem)
std::string ToOctaveString(const std::string &varName="CameraIntrinsics")
std::string ToString() const
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
#define endoAssertMsg(a, msg)
DataCollection - Class to facilitate loading/accessing structured data.
vnl_vector_fixed< mitk::ScalarType, 2 > GetPrincipalPointAsVnlVector() const
void SetFocalLength(double x, double y)
void SetIntrinsics(const cv::Mat &_CameraMatrix, const cv::Mat &_DistorsionCoeffs)
#define endodebug(msg)
mitk::Point4D GetDistorsionCoeffsAsPoint4D() const
static const std::string filename
mitk::Point3D GetPrincipalPoint() const
void SetDistorsionCoeffs(double k1, double k2, double p1, double p2)
bool Equals(const CameraIntrinsics *other) const
vnl_vector_fixed< mitk::ScalarType, 2 > GetFocalPointAsVnlVector() const
void SetPrincipalPoint(double x, double y)
#define endoAssert(a)
interface for all classes able to write themselves to XML files
void Copy(const CameraIntrinsics *other)
void ToXML(TiXmlElement *elem) const override
vnl_matrix_fixed< mitk::ScalarType, 3, 4 > GetVnlCameraMatrix3x4() const
mitk::Point3D GetFocalPoint() const
void SetCameraMatrix(const vnl_matrix_fixed< mitk::ScalarType, 3, 3 > &_CameraMatrix)
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.