DLTCalibration.cpp
Go to the documentation of this file.
1 // ****************************************************************************
2 // This file is part of the Integrating Vision Toolkit (IVT).
3 //
4 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
5 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
6 //
7 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
8 // All rights reserved.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are met:
12 //
13 // 1. Redistributions of source code must retain the above copyright
14 // notice, this list of conditions and the following disclaimer.
15 //
16 // 2. Redistributions in binary form must reproduce the above copyright
17 // notice, this list of conditions and the following disclaimer in the
18 // documentation and/or other materials provided with the distribution.
19 //
20 // 3. Neither the name of the KIT nor the names of its contributors may be
21 // used to endorse or promote products derived from this software
22 // without specific prior written permission.
23 //
24 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
25 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
28 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // ****************************************************************************
35 // ****************************************************************************
36 // Filename: DLTCalibration.cpp
37 // Author: Pedram Azad
38 // Date: 04.12.2009
39 // ****************************************************************************
40 
41 
42 // ****************************************************************************
43 // Includes
44 // ****************************************************************************
45 
46 #include "Math/Math3d.h"
47 #include "Math/Math2d.h"
48 #include "Math/FloatMatrix.h"
49 #include "Math/FloatVector.h"
50 #include "Math/LinearAlgebra.h"
52 
53 #include "DLTCalibration.h"
54 
55 #include <stdio.h>
56 #include <math.h>
57 
58 
59 
60 // ****************************************************************************
61 // Constructor / Destructor
62 // ****************************************************************************
63 
65 {
66  m_pPairElements = 0;
67  m_nPairElements = 0;
68 
69  L1 = L6 = 1;
70  L2 = L3 = L4 = L5 = L7 = L8 = L9 = L10 = L11 = 0;
71 }
72 
74 {
75 }
76 
77 
78 // ****************************************************************************
79 // Methods
80 // ****************************************************************************
81 
82 float CDLTCalibration::Calibrate(const CDLTCalibration::PairElement *pPairElements, int nPairElements, CCalibration &resultCalibration, DistortionType eCalculateDistortionParameters, int nIterations)
83 {
84  m_pPairElements = pPairElements;
85  m_nPairElements = nPairElements;
86 
87  resultCalibration.SetDistortion(0, 0, 0, 0);
88 
89  if (eCalculateDistortionParameters == eNoDistortion)
90  {
91  CalculateDLT(resultCalibration, true);
92  ExtractFromDLT(resultCalibration);
93  }
94  else
95  {
96  for (int i = 0; i < nIterations; i++)
97  {
98  CalculateDLT(resultCalibration, i == 0);
99  ExtractFromDLT(resultCalibration);
100 
101  if (eCalculateDistortionParameters == eRadialDistortion)
102  CalculateRadialLensDistortion(resultCalibration);
103  else if (eCalculateDistortionParameters == eRadialAndTangentialDistortion)
105  }
106  }
107 
108  return CheckCalibration(resultCalibration);
109 }
110 
111 
112 void CDLTCalibration::GetImageCoordinatesDLT(const Vec3d &worldPoint, Vec2d &imagePoint)
113 {
114  const float x = worldPoint.x;
115  const float y = worldPoint.y;
116  const float z = worldPoint.z;
117 
118  imagePoint.x = (L1 * x + L2 * y + L3 * z + L4) / (L9 * x + L10 * y + L11 * z + 1);
119  imagePoint.y = (L5 * x + L6 * y + L7 * z + L8) / (L9 * x + L10 * y + L11 * z + 1);
120 }
121 
122 
124 {
125  float error = 0.0f;
126  float max = 0.0f;
127 
128  for (int i = 0; i < m_nPairElements; i++)
129  {
130  Vec2d imagePoint;
131  calibration.WorldToImageCoordinates(m_pPairElements[i].worldPoint, imagePoint);
132 
133  const float distance = Math2d::Distance(m_pPairElements[i].imagePoint, imagePoint);
134 
135  if (distance > max)
136  max = distance;
137 
138  error += distance;
139  }
140 
141  return error / m_nPairElements;
142 }
143 
144 
146 {
147  float error = 0.0f;
148 
149  for (int i = 0; i < m_nPairElements; i++)
150  {
151  Vec2d imagePoint;
152  GetImageCoordinatesDLT(m_pPairElements[i].worldPoint, imagePoint);
153 
154  error += Math2d::Distance(m_pPairElements[i].imagePoint, imagePoint);
155  }
156 
157  return error / m_nPairElements;
158 }
159 
160 
162 {
163  CFloatMatrix A(2, 2 * m_nPairElements);
165 
166  const float cx = calibration.GetCameraParameters().principalPoint.x;
167  const float cy = calibration.GetCameraParameters().principalPoint.y;
168  const float fx = calibration.GetCameraParameters().focalLength.x;
169  const float fy = calibration.GetCameraParameters().focalLength.y;
170 
171  for (int i = 0; i < m_nPairElements; i++)
172  {
173  const int ii = 2 * i;
174 
175  Vec2d undistorted_point;
176  calibration.WorldToImageCoordinates(m_pPairElements[i].worldPoint, undistorted_point, false);
177 
178  const float u = undistorted_point.x;
179  const float v = undistorted_point.y;
180  const float ud = m_pPairElements[i].imagePoint.x;
181  const float vd = m_pPairElements[i].imagePoint.y;
182 
183  const float x = (u - cx) / fx;
184  const float y = (v - cy) / fy;
185 
186  const float rr = x * x + y * y;
187 
188  A(0, ii) = (u - cx) * rr;
189  A(1, ii) = (u - cx) * rr * rr;
190  A(0, ii + 1) = (v - cy) * rr;
191  A(1, ii + 1) = (v - cy) * rr * rr;
192 
193  b[ii] = ud - u;
194  b[ii + 1] = vd - v;
195  }
196 
197  CFloatVector result(2);
199 
200  calibration.SetDistortion((float) result[0], (float) result[1], 0, 0);
201 }
202 
203 
205 {
206  CFloatMatrix A(4, 2 * m_nPairElements);
208 
209  const float cx = calibration.GetCameraParameters().principalPoint.x;
210  const float cy = calibration.GetCameraParameters().principalPoint.y;
211  const float fx = calibration.GetCameraParameters().focalLength.x;
212  const float fy = calibration.GetCameraParameters().focalLength.y;
213 
214  for (int i = 0; i < m_nPairElements; i++)
215  {
216  const int ii = 2 * i;
217 
218  Vec2d undistorted_point;
219  calibration.WorldToImageCoordinates(m_pPairElements[i].worldPoint, undistorted_point, false);
220 
221  const float u = undistorted_point.x;
222  const float v = undistorted_point.y;
223  const float ud = m_pPairElements[i].imagePoint.x;
224  const float vd = m_pPairElements[i].imagePoint.y;
225 
226  const float x = (u - cx) / fx;
227  const float y = (v - cy) / fy;
228 
229  const float rr = x * x + y * y;
230 
231  A(0, ii) = (u - cx) * rr;
232  A(1, ii) = (u - cx) * rr * rr;
233  A(2, ii) = 2 * x * y * fx;
234  A(3, ii) = (rr + 2 * x * x) * fx;
235  A(0, ii + 1) = (v - cy) * rr;
236  A(1, ii + 1) = (v - cy) * rr * rr;
237  A(2, ii + 1) = (rr + 2 * y * y) * fy;
238  A(3, ii + 1) = 2 * x * y * fy;
239 
240  b[ii] = ud - u;
241  b[ii + 1] = vd - v;
242  }
243 
244  CFloatVector result(4);
246 
247  calibration.SetDistortion((float) result[0], (float) result[1], (float) result[2], (float) result[3]);
248 }
249 
250 
252 {
253  const float LL = L9 * L9 + L10 * L10 + L11 * L11;
254  const float L = sqrt(LL);
255  const float atc = L1 * L9 + L2 * L10 + L3 * L11;
256  const float btc = L5 * L9 + L6 * L10 + L7 * L11;
257  const float atb = L1 * L5 * L2 * L6 + L3 * L7;
258  const float ata = L1 * L1 + L2 * L2 + L3 * L3;
259  const float btb = L5 * L5 + L6 * L6 + L7 * L7;
260 
261  const float cx = atc / LL;
262  const float cy = btc / LL;
263  const float fx = sqrt(ata / LL - cx * cx);
264  const float fy = sqrt(btb / LL - cy * cy);
265 
266  const float r31 = L9 / L;
267  const float r32 = L10 / L;
268  const float r33 = L11 / L;
269  const float r11 = (L1 / L - cx * r31) / fx;
270  const float r12 = (L2 / L - cx * r32) / fx;
271  const float r13 = (L3 / L - cx * r33) / fx;
272  const float r21 = (L5 / L - cy * r31) / fy;
273  const float r22 = (L6 / L - cy * r32) / fy;
274  const float r23 = (L7 / L - cy * r33) / fy;
275 
276  const Mat3d rotation = { r11, r12, r13, r21, r22, r23, r31, r32, r33 };
277  Vec3d translation;
278 
279  Mat3d abc = { L1, L2, L3, L5, L6, L7, L9, L10, L11 };
280  Math3d::Invert(abc, abc);
281 
282  const Vec3d x = { L4, L8, 1 };
283  Math3d::MulMatVec(abc, x, translation);
284  Math3d::MulMatVec(rotation, translation, translation);
285 
286  calibration.SetIntrinsicBase(cx, cy, fx, fy);
287  calibration.SetRotation(rotation);
288  calibration.SetTranslation(translation);
289 }
290 
291 
292 void CDLTCalibration::CalculateDLT(const CCalibration &calibration, bool bFirstCall)
293 {
294  CFloatMatrix A(11, 2 * m_nPairElements);
296 
297  for (int i = 0; i < m_nPairElements; i++)
298  {
299  const float x = m_pPairElements[i].worldPoint.x;
300  const float y = m_pPairElements[i].worldPoint.y;
301  const float z = m_pPairElements[i].worldPoint.z;
302 
303  float u = m_pPairElements[i].imagePoint.x;
304  float v = m_pPairElements[i].imagePoint.y;
305 
306  if (!bFirstCall)
307  {
308  const Vec2d distortedPoint = { u, v };
309  Vec2d undistortedPoint;
310 
311  calibration.UndistortImageCoordinates(distortedPoint, undistortedPoint);
312 
313  u = undistortedPoint.x;
314  v = undistortedPoint.y;
315  }
316 
317  const int ii = 2 * i;
318 
319  A(0, ii) = x;
320  A(1, ii) = y;
321  A(2, ii) = z;
322  A(3, ii) = 1;
323  A(4, ii) = 0;
324  A(5, ii) = 0;
325  A(6, ii) = 0;
326  A(7, ii) = 0;
327  A(8, ii) = -u * x;
328  A(9, ii) = -u * y;
329  A(10, ii) = -u * z;
330 
331  A(0, ii + 1) = 0;
332  A(1, ii + 1) = 0;
333  A(2, ii + 1) = 0;
334  A(3, ii + 1) = 0;
335  A(4, ii + 1) = x;
336  A(5, ii + 1) = y;
337  A(6, ii + 1) = z;
338  A(7, ii + 1) = 1;
339  A(8, ii + 1) = -v * x;
340  A(9, ii + 1) = -v * y;
341  A(10, ii + 1) = -v * z;
342 
343  b[ii] = u;
344  b[ii + 1] = v;
345  }
346 
347  CFloatVector result(11);
349 
350  L1 = (float) result[0];
351  L2 = (float) result[1];
352  L3 = (float) result[2];
353  L4 = (float) result[3];
354  L5 = (float) result[4];
355  L6 = (float) result[5];
356  L7 = (float) result[6];
357  L8 = (float) result[7];
358  L9 = (float) result[8];
359  L10 = (float) result[9];
360  L11 = (float) result[10];
361 }
void CalculateDLT(const CCalibration &calibration, bool bFirstCall)
void SetDistortion(float d1, float d2, float d3, float d4)
Sets the distortion parameters of the distortion model.
GLdouble GLdouble z
Definition: glext.h:3343
float y
Definition: Math2d.h:84
void UndistortImageCoordinates(const Vec2d &distortedImagePoint, Vec2d &undistortedImagePoint) const
Transforms 2D distorted image coordinates to 2D undistorted image coordinates.
Data structure for the representation of a 3D vector.
Definition: Math3d.h:73
float x
Definition: Math3d.h:75
float z
Definition: Math3d.h:75
void CalculateRadialLensDistortion(CCalibration &calibration)
GLenum GLint x
Definition: glext.h:3125
const CCameraParameters & GetCameraParameters() const
Gives access to the camera parameters.
Definition: Calibration.h:268
float Distance(const Vec2d &vector1, const Vec2d &vector2)
Definition: Math2d.cpp:181
float x
Definition: Math2d.h:84
const PairElement * m_pPairElements
float CheckCalibration(const CCalibration &calibration)
float y
Definition: Math3d.h:75
Data structure for the representation of a matrix of values of the data type float.
Definition: FloatMatrix.h:56
void SetIntrinsicBase(float cx, float cy, float fx, float fy)
Sets the principal point and the focal lengths.
void Invert(const Mat3d &matrix, Mat3d &result)
Definition: Math3d.cpp:657
void MulMatVec(const Mat3d &matrix, const Vec3d &vec, Vec3d &result)
Definition: Math3d.cpp:422
void ExtractFromDLT(CCalibration &calibration)
void CalculateRadialAndTangentialLensDistortion(CCalibration &calibration)
GLubyte GLubyte b
Definition: glext.h:5166
void GetImageCoordinatesDLT(const Vec3d &worldPoint, Vec2d &imagePoint)
Data structure for the representation of a vector of values of the data type float.
Definition: FloatVector.h:53
bool SolveLinearLeastSquaresSimple(const CFloatMatrix *A, const CFloatVector *b, CFloatVector *x)
float Calibrate(const PairElement *pPairElements, int nPairElements, CCalibration &resultCalibration, DistortionType eCalculateDistortionParameters=eNoDistortion, int nIterations=1000)
GLenum GLint GLint y
Definition: glext.h:3125
const GLdouble * v
Definition: glext.h:3212
Data structure for the representation of a 2D vector.
Definition: Math2d.h:82
void SetTranslation(const Vec3d &t)
Sets the extrinsic parameter t (translation vector).
void SetRotation(const Mat3d &R)
Sets the extrinsic parameter R (rotation matrix).
Data structure for the representation of a 3x3 matrix.
Definition: Math3d.h:93
Camera model parameters and functions for a single camera.
Definition: Calibration.h:125
void WorldToImageCoordinates(const Vec3d &worldPoint, Vec2d &imagePoint, bool bUseDistortionParameters=true) const
Transforms 3D world coordinates to 2D image coordinates.


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Mon Dec 2 2019 03:47:27