MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkCameraIntrinsics.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
14#include <mitkEndoMacros.h>
15#include <mitkEndoDebug.h>
16#include <tinyxml2.h>
17
19 : m_Valid(false)
20{
21 m_CameraMatrix = cv::Mat::zeros(3, 3, cv::DataType<double>::type);
22 m_CameraMatrix.at<double>(2,2) = 1.0;
23 m_DistorsionCoeffs = cv::Mat::zeros(1, 5, cv::DataType<double>::type);
24}
25
27 : itk::Object()
29 , m_Valid(false)
30{
31 this->Copy(&other);
32}
33
38
40{
41 return other->GetDistorsionCoeffsAsPoint4D()==
42 this->GetDistorsionCoeffsAsPoint4D() &&
43 other->GetFocalPoint()==
44 this->GetFocalPoint() &&
45 other->GetPrincipalPoint()
46 == this->GetPrincipalPoint();
47}
48
50{
51 this->SetIntrinsics( other->GetCameraMatrix().clone()
52 , other->GetDistorsionCoeffs().clone() );
53 this->SetValid(other->m_Valid);
54}
55
57{
58 std::lock_guard<std::mutex> lock(m_Mutex);
59 return m_Valid;
60}
61
62vnl_matrix_fixed<mitk::ScalarType, 3, 3>
64{
65 vnl_matrix_fixed<mitk::ScalarType, 3, 3> mat;
66 mat.set_identity();
67
68 {
69 std::lock_guard<std::mutex> lock(m_Mutex);
70 mat(0,0) = m_CameraMatrix.at<double>(0,0);
71 mat(1,1) = m_CameraMatrix.at<double>(1,1);
72
73 mat(0,2) = m_CameraMatrix.at<double>(0,2);
74 mat(1,2) = m_CameraMatrix.at<double>(1,2);
75 }
76
77 return mat;
78}
79
81 const vnl_matrix_fixed<mitk::ScalarType, 3, 3>& _CameraMatrix )
82{
83 std::lock_guard<std::mutex> lock(m_Mutex);
84 m_CameraMatrix.at<double>(0,0) = _CameraMatrix(0,0);
85 m_CameraMatrix.at<double>(1,1) = _CameraMatrix(1,1);
86
87 m_CameraMatrix.at<double>(0,2) = _CameraMatrix(0,2);
88 m_CameraMatrix.at<double>(1,2) = _CameraMatrix(1,2);
89}
90
91vnl_matrix_fixed<mitk::ScalarType, 3, 4>
93{
94 vnl_matrix_fixed<mitk::ScalarType, 3, 4> mat;
95 mat.fill(0);
96 mat.update( this->GetVnlCameraMatrix().as_matrix() );
97
98 return mat;
99}
100
101void mitk::CameraIntrinsics::SetIntrinsics( const cv::Mat& _CameraMatrix
102 , const cv::Mat& _DistorsionCoeffs)
103{
104 {
105 std::lock_guard<std::mutex> lock(m_Mutex);
106 if( _CameraMatrix.cols != 3 || _CameraMatrix.rows != 3)
107 throw std::invalid_argument("Wrong format of camera matrix. Should be 3x3"
108 " double.");
109
110 endoAssertMsg( (_DistorsionCoeffs.cols == 5) &&
111 _DistorsionCoeffs.rows == 1, "Wrong format of distorsion coefficients"
112 " vector. Should be 5x1 double.");
113
114 m_CameraMatrix = _CameraMatrix.clone();
115 m_DistorsionCoeffs = _DistorsionCoeffs.clone();
116
117 m_Valid = true;
118 }
119 this->Modified();
120}
121
122void mitk::CameraIntrinsics::SetIntrinsics( const mitk::Point3D& focalPoint,
123 const mitk::Point3D& principalPoint,
124 const mitk::Point4D& distortionCoefficients)
125
126{
127 {
128 std::lock_guard<std::mutex> lock(m_Mutex);
129 m_CameraMatrix.at<double>(0,0) = focalPoint[0];
130 m_CameraMatrix.at<double>(1,1) = focalPoint[1];
131
132 m_CameraMatrix.at<double>(0,2) = principalPoint[0];
133 m_CameraMatrix.at<double>(1,2) = principalPoint[1];
134
135 m_DistorsionCoeffs.at<double>(0,0) = distortionCoefficients[0];
136 m_DistorsionCoeffs.at<double>(0,1) = distortionCoefficients[1];
137 m_DistorsionCoeffs.at<double>(0,2) = distortionCoefficients[2];
138 m_DistorsionCoeffs.at<double>(0,3) = distortionCoefficients[3];
139 }
140 this->Modified();
141}
142
144{
145 {
146 std::lock_guard<std::mutex> lock(m_Mutex);
147 m_CameraMatrix.at<double>(0,0) = x;
148 m_CameraMatrix.at<double>(1,1) = y;
149 }
150 this->Modified();
151}
152
154{
155 {
156 std::lock_guard<std::mutex> lock(m_Mutex);
157 m_CameraMatrix.at<double>(0,2) = x;
158 m_CameraMatrix.at<double>(1,2) = y;
159 }
160 this->Modified();
161}
162
164 double p1, double p2 )
165{
166
167 {
168 std::lock_guard<std::mutex> lock(m_Mutex);
169
170 m_DistorsionCoeffs.at<double>(0,0) = k1;
171 m_DistorsionCoeffs.at<double>(0,1) = k2;
172 m_DistorsionCoeffs.at<double>(0,2) = p1;
173 m_DistorsionCoeffs.at<double>(0,3) = p2;
174 }
175 this->Modified();
176}
177
179{
180 std::lock_guard<std::mutex> lock(m_Mutex);
181 return m_CameraMatrix.clone(); // return a copy of this small matrix
182}
183
185{
186 std::lock_guard<std::mutex> lock(m_Mutex);
187 return m_DistorsionCoeffs.clone(); // return a copy of this small matrix
188}
189
191{
192 const CameraIntrinsics* intrinsics = this;
193 return intrinsics->GetDistorsionCoeffs();
194}
195
197{
198 std::lock_guard<std::mutex> lock(m_Mutex);
199 std::ostringstream s; s.precision(12);
200 const cv::Mat& CameraMatrix = m_CameraMatrix;
201 const cv::Mat& DistorsionCoeffs = m_DistorsionCoeffs;
202
203 s.str(""); s << this->GetNameOfClass() << ": ";
204 s << "fx = " << CameraMatrix.at<double>(0,0);
205 s << ", fy = " << CameraMatrix.at<double>(1,1);
206 s << ", cx = " << CameraMatrix.at<double>(0,2);
207 s << ", cy = " << CameraMatrix.at<double>(1,2);
208
209 s << ", k1 = " << DistorsionCoeffs.at<double>(0,0);
210 s << ", k2 = " << DistorsionCoeffs.at<double>(0,1);
211 s << ", p1 = " << DistorsionCoeffs.at<double>(0,2);
212 s << ", p2 = " << DistorsionCoeffs.at<double>(0,3);
213 //s << ", k3 = " << DistorsionCoeffs.at<double>(0,4);
214
215 return s.str();
216}
217
218void mitk::CameraIntrinsics::ToXML(tinyxml2::XMLElement* elem) const
219{
220 std::lock_guard<std::mutex> lock(m_Mutex);
221 elem->SetValue(this->GetNameOfClass());
222 std::ostringstream s; s.precision(12);
223 const cv::Mat& CameraMatrix = m_CameraMatrix;
224 s.str(""); s << CameraMatrix.at<double>(0,0);
225 elem->SetAttribute( "fx", s.str().c_str() );
226 s.str(""); s << CameraMatrix.at<double>(1,1);
227 elem->SetAttribute( "fy", s.str().c_str());
228 s.str(""); s << CameraMatrix.at<double>(0,2);
229 elem->SetAttribute( "cx", s.str().c_str());
230 s.str(""); s << CameraMatrix.at<double>(1,2);
231 elem->SetAttribute( "cy", s.str().c_str());
232
233 const cv::Mat& DistorsionCoeffs = m_DistorsionCoeffs;
234 s.str(""); s << DistorsionCoeffs.at<double>(0,0);
235 elem->SetAttribute( "k1", s.str().c_str());
236 s.str(""); s << DistorsionCoeffs.at<double>(0,1);
237 elem->SetAttribute( "k2", s.str().c_str());
238 s.str(""); s << DistorsionCoeffs.at<double>(0,2);
239 elem->SetAttribute( "p1", s.str().c_str());
240 s.str(""); s << DistorsionCoeffs.at<double>(0,3);
241 elem->SetAttribute( "p2", s.str().c_str());
242 elem->SetAttribute("Valid", static_cast<int>(m_Valid));
243 //s.str(""); s << DistorsionCoeffs.at<double>(4,0);
244 //elem->SetAttribute( "k3", s.str().c_str() );
245}
246
247void mitk::CameraIntrinsics::FromGMLCalibrationXML(const tinyxml2::XMLElement* elem)
248{
249 assert( elem );
250 assert( std::string(elem->Value()) == "results" );
251 cv::Mat CameraMatrix = cv::Mat::zeros(3, 3, cv::DataType<double>::type);
252 CameraMatrix.at<double>(2,2) = 1.0;
253 cv::Mat DistorsionCoeffs = cv::Mat::zeros(1, 5, cv::DataType<double>::type);
254
255 const auto* focus_lenXElem = elem->FirstChildElement("focus_lenX");
256 endoAssert( focus_lenXElem != nullptr );
257 CameraMatrix.at<double>(0,0) = atof( focus_lenXElem->GetText() );
258
259 const auto* focus_lenYElem = elem->FirstChildElement("focus_lenY");
260 endoAssert( focus_lenYElem != nullptr );
261 CameraMatrix.at<double>(1,1) = atof( focus_lenYElem->GetText() );
262
263 const auto* PrincipalXElem = elem->FirstChildElement("PrincipalX");
264 endoAssert( PrincipalXElem != nullptr );
265 CameraMatrix.at<double>(0,2) = atof( PrincipalXElem->GetText() );
266
267 const auto* PrincipalYElem = elem->FirstChildElement("PrincipalY");
268 endoAssert( PrincipalYElem != nullptr );
269 CameraMatrix.at<double>(1,2) = atof( PrincipalYElem->GetText() );
270
271 // DISTORSION COEFFS
272
273 const auto* Dist1Elem = elem->FirstChildElement("Dist1");
274 endoAssert( Dist1Elem != nullptr );
275 DistorsionCoeffs.at<double>(0,0) = atof( Dist1Elem->GetText() );
276
277 const auto* Dist2Elem = elem->FirstChildElement("Dist2");
278 endoAssert( Dist2Elem != nullptr );
279 DistorsionCoeffs.at<double>(0,1) = atof( Dist2Elem->GetText() );
280
281 const auto* Dist3Elem = elem->FirstChildElement("Dist3");
282 endoAssert( Dist3Elem != nullptr );
283 DistorsionCoeffs.at<double>(0,2) = atof( Dist3Elem->GetText() );
284
285 const auto* Dist4Elem = elem->FirstChildElement("Dist4");
286 endoAssert( Dist4Elem != nullptr );
287 DistorsionCoeffs.at<double>(0,3) = atof( Dist4Elem->GetText() );
288
289 int valid = 0;
290 elem->QueryIntAttribute("Valid", &valid);
291
292 {
293 std::lock_guard<std::mutex> lock(m_Mutex);
294 m_Valid = static_cast<bool>(valid);
295 m_CameraMatrix = CameraMatrix;
296 m_DistorsionCoeffs = DistorsionCoeffs;
297 }
298
299 this->Modified();
300}
301
302void mitk::CameraIntrinsics::FromXML(const tinyxml2::XMLElement* elem)
303{
304 endoAssert ( elem );
305 MITK_DEBUG << elem->Value();
306 const char* filename = elem->Attribute("file");
307 if(nullptr != filename)
308 {
309 this->FromXMLFile(filename);
310 return;
311 }
312 else if(strcmp(elem->Value(), "CalibrationProject") == 0)
313 {
314 this->FromGMLCalibrationXML(elem->FirstChildElement("results"));
315 return;
316 }
317
318 assert ( elem );
319 if(strcmp(elem->Value(), this->GetNameOfClass()) != 0)
320 elem = elem->FirstChildElement(this->GetNameOfClass());
321
322 std::ostringstream err;
323 // CAMERA MATRIX
324 cv::Mat CameraMatrix = cv::Mat::zeros(3, 3, cv::DataType<double>::type);
325 CameraMatrix.at<double>(2,2) = 1.0;
326 double val = 0.0;
327 if(elem->QueryDoubleAttribute("fx", &val) == tinyxml2::XML_SUCCESS)
328 CameraMatrix.at<double>(0,0) = val;
329 else
330 err << "fx, ";
331
332 if(elem->QueryDoubleAttribute("fy", &val) == tinyxml2::XML_SUCCESS)
333 CameraMatrix.at<double>(1,1) = val;
334 else
335 err << "fy, ";
336
337 if(elem->QueryDoubleAttribute("cx", &val) == tinyxml2::XML_SUCCESS)
338 CameraMatrix.at<double>(0,2) = val;
339 else
340 err << "cx, ";
341
342 if(elem->QueryDoubleAttribute("cy", &val) == tinyxml2::XML_SUCCESS)
343 CameraMatrix.at<double>(1,2) = val;
344 else
345 err << "cy, ";
346
347 // DISTORSION COEFFS
348 endodebug( "creating DistorsionCoeffs from XML file")
349 cv::Mat DistorsionCoeffs = cv::Mat::zeros(1, 5, cv::DataType<double>::type);
350 if(elem->QueryDoubleAttribute("k1", &val) == tinyxml2::XML_SUCCESS)
351 DistorsionCoeffs.at<double>(0,0) = val;
352 else
353 err << "k1, ";
354
355 if(elem->QueryDoubleAttribute("k2", &val) == tinyxml2::XML_SUCCESS)
356 DistorsionCoeffs.at<double>(0,1) = val;
357 else
358 err << "k2, ";
359
360 if(elem->QueryDoubleAttribute("p1", &val) == tinyxml2::XML_SUCCESS)
361 DistorsionCoeffs.at<double>(0,2) = val;
362 else
363 err << "p1, ";
364
365 if(elem->QueryDoubleAttribute("p2", &val) == tinyxml2::XML_SUCCESS)
366 DistorsionCoeffs.at<double>(0,3) = val;
367 else
368 err << "p2, ";
369
370 DistorsionCoeffs.at<double>(0,4) = 0.0;
371
372 /*if(elem->QueryDoubleAttribute("k3", &val) == tinyxml2::XML_SUCCESS)
373 DistorsionCoeffs.at<double>(4,0) = val;
374 else
375 err << "k3, ";*/
376
377 std::string errorStr = err.str();
378 int errLength = errorStr.length();
379 if(errLength > 0)
380 {
381 errorStr = errorStr.substr(0, errLength-2);
382 errorStr.append(" not found");
383 throw std::invalid_argument(err.str());
384 }
385
386 int valid = 0;
387 elem->QueryIntAttribute("Valid", &valid);
388
389 {
390 std::lock_guard<std::mutex> lock(m_Mutex);
391 m_Valid = static_cast<bool>(valid);
392 m_CameraMatrix = CameraMatrix;
393 m_DistorsionCoeffs = DistorsionCoeffs;
394 }
395
396 this->Modified();
397}
398
400{
401 std::lock_guard<std::mutex> lock(m_Mutex);
402 double FocalLengthX = m_CameraMatrix.at<double>(0,0);
403
404 return FocalLengthX;
405}
407{
408 std::lock_guard<std::mutex> lock(m_Mutex);
409 double FocalLengthY = m_CameraMatrix.at<double>(1,1);;
410 return FocalLengthY;
411}
413{
414 std::lock_guard<std::mutex> lock(m_Mutex);
415 double PrincipalPointX = m_CameraMatrix.at<double>(0,2);
416 return PrincipalPointX;
417}
419{
420 std::lock_guard<std::mutex> lock(m_Mutex);
421 double PrincipalPointY = m_CameraMatrix.at<double>(1,2);
422 return PrincipalPointY;
423}
425{
426 std::lock_guard<std::mutex> lock(m_Mutex);
427 mitk::Point4D coeffs;
428
429 coeffs[0] = m_DistorsionCoeffs.at<double>(0,0);
430 coeffs[1] = m_DistorsionCoeffs.at<double>(0,1);
431 coeffs[2] = m_DistorsionCoeffs.at<double>(0,2);
432 coeffs[3] = m_DistorsionCoeffs.at<double>(0,3);
433
434 return coeffs;
435}
436
438{
439 mitk::Point3D p;
440 p[0] = this->GetFocalLengthX();
441 p[1] = this->GetFocalLengthY();
442 p[2] = 0;
443 return p;
444}
445
447{
448 mitk::Point3D p;
449 p[0] = this->GetPrincipalPointX();
450 p[1] = this->GetPrincipalPointY();
451 p[2] = 0;
452 return p;
453}
454
455vnl_vector_fixed<mitk::ScalarType, 2>
457{
458 vnl_vector_fixed<mitk::ScalarType, 2> vec;
459 vec[0] = this->GetFocalLengthX();
460 vec[1] = this->GetFocalLengthY();
461 return vec;
462}
463
464vnl_vector_fixed<mitk::ScalarType, 2>
466{
467 vnl_vector_fixed<mitk::ScalarType, 2> vec;
468 vec[0] = this->GetPrincipalPointX();
469 vec[1] = this->GetPrincipalPointY();
470 return vec;
471}
472
473std::ostream& operator<< (std::ostream& os, mitk::CameraIntrinsics::Pointer p)
474{
475 os << p->ToString();
476 return os;
477}
478
480{
481 return this->ToString();
482}
483
485 const std::string& varName)
486{
487 std::ostringstream s;
488 s << varName << " = [" << this->GetFocalLengthX() << " 0 "
489 << this->GetPrincipalPointX() << "; 0 " <<
490 this->GetFocalLengthY() << " " << this->GetPrincipalPointY() << ";"
491 << " 0 0 1 ];";
492 return s.str();
493}
494
496{
497 std::lock_guard<std::mutex> lock(m_Mutex);
498 m_Valid = valid;
499}
500
501itk::LightObject::Pointer mitk::CameraIntrinsics::InternalClone() const
502{
503 itk::LightObject::Pointer result(new Self(*this));
504 result->UnRegister();
505 return result;
506}
class representing camera intrinsics and related functions
std::string ToOctaveString(const std::string &varName="CameraIntrinsics")
void SetFocalLength(double x, double y)
void SetDistorsionCoeffs(double k1, double k2, double p1, double p2)
void ToXML(tinyxml2::XMLElement *elem) const override
void SetCameraMatrix(const vnl_matrix_fixed< mitk::ScalarType, 3, 3 > &_CameraMatrix)
mitk::Point3D GetPrincipalPoint() const
mitk::Point3D GetFocalPoint() const
void SetIntrinsics(const cv::Mat &_CameraMatrix, const cv::Mat &_DistorsionCoeffs)
void SetPrincipalPoint(double x, double y)
vnl_matrix_fixed< mitk::ScalarType, 3, 4 > GetVnlCameraMatrix3x4() const
bool Equals(const CameraIntrinsics *other) const
void FromXML(const tinyxml2::XMLElement *elem) override
void FromGMLCalibrationXML(const tinyxml2::XMLElement *elem)
vnl_vector_fixed< mitk::ScalarType, 2 > GetFocalPointAsVnlVector() const
void Copy(const CameraIntrinsics *other)
mitk::Point4D GetDistorsionCoeffsAsPoint4D() const
vnl_matrix_fixed< mitk::ScalarType, 3, 3 > GetVnlCameraMatrix() const
vnl_vector_fixed< mitk::ScalarType, 2 > GetPrincipalPointAsVnlVector() const
interface for all classes able to write themselves to XML files
std::ostream & operator<<(std::ostream &os, mitk::CameraIntrinsics::Pointer p)
#define endoAssertMsg(a, msg)
#define endoAssert(a)
#define endodebug(msg)
IGT Exceptions.
int strcmp(const String &s1, const String &s2)
Definition relates.cpp:14