00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #include <new>
00051
00052 #include "Calibration.h"
00053 #include "Math/Matd.h"
00054 #include "Math/Vecd.h"
00055 #include "Image/ByteImage.h"
00056
00057 #include <stdio.h>
00058 #include <stdlib.h>
00059 #include <math.h>
00060
00061
00062
00063
00064
00065
00066
00067
00068 CCalibration::CCalibration()
00069 {
00070 m_cameraParameters.width = 640;
00071 m_cameraParameters.height = 480;
00072
00073 Math2d::SetVec(m_cameraParameters.principalPoint, 320, 240);
00074 Math2d::SetVec(m_cameraParameters.focalLength, 580, 580);
00075 SetRotation(Math3d::unit_mat);
00076 SetTranslation(Math3d::zero_vec);
00077
00078 for (int i = 0; i < 4; i++)
00079 m_cameraParameters.distortion[i] = 0;
00080 }
00081
00082 CCalibration::~CCalibration()
00083 {
00084 }
00085
00086
00087
00088
00089
00090
00091 void CCalibration::GetCalibrationMatrix(Mat3d &K) const
00092 {
00093 Math3d::SetMat(K,
00094 m_cameraParameters.focalLength.x, 0, m_cameraParameters.principalPoint.x,
00095 0, m_cameraParameters.focalLength.y, m_cameraParameters.principalPoint.y,
00096 0, 0, 1);
00097 }
00098
00099 void CCalibration::GetProjectionMatrix(Mat3d &P, Vec3d &p) const
00100 {
00101 Mat3d K;
00102 GetCalibrationMatrix(K);
00103
00104 Math3d::MulMatMat(K, m_cameraParameters.rotation, P);
00105 Math3d::MulMatVec(K, m_cameraParameters.translation, p);
00106 }
00107
00108
00109 void CCalibration::CalculateInverseTransformation()
00110 {
00111 Math3d::Transpose(m_cameraParameters.rotation, m_rotation_inverse);
00112 Math3d::MulMatVec(m_rotation_inverse, m_cameraParameters.translation, m_translation_inverse);
00113 Math3d::MulVecScalar(m_translation_inverse, -1, m_translation_inverse);
00114 }
00115
00116
00117 void CCalibration::SetCameraParameters(float fx, float fy, float cx, float cy,
00118 float d1, float d2, float d3, float d4,
00119 const Mat3d &R, const Vec3d &t, int width, int height)
00120 {
00121 m_cameraParameters.width = width;
00122 m_cameraParameters.height = height;
00123
00124 Math3d::SetMat(m_cameraParameters.rotation, R);
00125 Math3d::SetVec(m_cameraParameters.translation, t);
00126
00127 Math2d::SetVec(m_cameraParameters.focalLength, fx, fy);
00128 Math2d::SetVec(m_cameraParameters.principalPoint, cx, cy);
00129
00130 m_cameraParameters.distortion[0] = d1;
00131 m_cameraParameters.distortion[1] = d2;
00132 m_cameraParameters.distortion[2] = d3;
00133 m_cameraParameters.distortion[3] = d4;
00134
00135 CalculateInverseTransformation();
00136 }
00137
00138 void CCalibration::Set(const CCalibration &calibration)
00139 {
00140 const CCameraParameters &cameraParameters = calibration.GetCameraParameters();
00141
00142 m_cameraParameters.width = cameraParameters.width;
00143 m_cameraParameters.height = cameraParameters.height;
00144
00145 Math3d::SetMat(m_cameraParameters.rotation, cameraParameters.rotation);
00146 Math3d::SetVec(m_cameraParameters.translation, cameraParameters.translation);
00147
00148 Math2d::SetVec(m_cameraParameters.focalLength, cameraParameters.focalLength);
00149 Math2d::SetVec(m_cameraParameters.principalPoint, cameraParameters.principalPoint);
00150
00151 m_cameraParameters.distortion[0] = cameraParameters.distortion[0];
00152 m_cameraParameters.distortion[1] = cameraParameters.distortion[1];
00153 m_cameraParameters.distortion[2] = cameraParameters.distortion[2];
00154 m_cameraParameters.distortion[3] = cameraParameters.distortion[3];
00155
00156 CalculateInverseTransformation();
00157 }
00158
00159 void CCalibration::SetRotation(const Mat3d &rotation)
00160 {
00161 Math3d::SetMat(m_cameraParameters.rotation, rotation);
00162 CalculateInverseTransformation();
00163 }
00164
00165 void CCalibration::SetTranslation(const Vec3d &translation)
00166 {
00167 Math3d::SetVec(m_cameraParameters.translation, translation);
00168 CalculateInverseTransformation();
00169 }
00170
00171 void CCalibration::SetIntrinsicBase(float cx, float cy, float fx, float fy)
00172 {
00173 Math2d::SetVec(m_cameraParameters.principalPoint, cx, cy);
00174 Math2d::SetVec(m_cameraParameters.focalLength, fx, fy);
00175 }
00176
00177 void CCalibration::SetDistortion(float d1, float d2, float d3, float d4)
00178 {
00179 m_cameraParameters.distortion[0] = d1;
00180 m_cameraParameters.distortion[1] = d2;
00181 m_cameraParameters.distortion[2] = d3;
00182 m_cameraParameters.distortion[3] = d4;
00183 }
00184
00185
00186 void CCalibration::WorldToImageCoordinates(const Vec3d &worldPoint, Vec2d &imagePoint, bool bUseDistortionParameters) const
00187 {
00188 Vec3d cameraPoint;
00189 WorldToCameraCoordinates(worldPoint, cameraPoint);
00190 CameraToImageCoordinates(cameraPoint, imagePoint, bUseDistortionParameters);
00191 }
00192
00193 void CCalibration::ImageToWorldCoordinates(const Vec2d &imagePoint, Vec3d &worldPoint, float zc, bool bUseDistortionParameters) const
00194 {
00195 Vec3d cameraPoint;
00196 ImageToCameraCoordinates(imagePoint, cameraPoint, zc, bUseDistortionParameters);
00197 CameraToWorldCoordinates(cameraPoint, worldPoint);
00198 }
00199
00200 void CCalibration::WorldToCameraCoordinates(const Vec3d &worldPoint, Vec3d &cameraPoint) const
00201 {
00202 Math3d::MulMatVec(m_cameraParameters.rotation, worldPoint, m_cameraParameters.translation, cameraPoint);
00203 }
00204
00205 void CCalibration::CameraToWorldCoordinates(const Vec3d &cameraPoint, Vec3d &worldPoint) const
00206 {
00207 Math3d::MulMatVec(m_rotation_inverse, cameraPoint, m_translation_inverse, worldPoint);
00208 }
00209
00210 void CCalibration::CameraToImageCoordinates(const Vec3d &cameraPoint, Vec2d &imagePoint, bool bUseDistortionParameters) const
00211 {
00212 imagePoint.x = m_cameraParameters.principalPoint.x + (cameraPoint.x * m_cameraParameters.focalLength.x) / cameraPoint.z;
00213 imagePoint.y = m_cameraParameters.principalPoint.y + (cameraPoint.y * m_cameraParameters.focalLength.y) / cameraPoint.z;
00214
00215 if (bUseDistortionParameters)
00216 DistortImageCoordinates(imagePoint, imagePoint);
00217 }
00218
00219 void CCalibration::ImageToCameraCoordinates(const Vec2d &imagePoint_, Vec3d &cameraPoint, float zc, bool bUseDistortionParameters) const
00220 {
00221 Vec2d imagePoint;
00222
00223 if (bUseDistortionParameters)
00224 UndistortImageCoordinates(imagePoint_, imagePoint);
00225 else
00226 Math2d::SetVec(imagePoint, imagePoint_);
00227
00228 cameraPoint.x = (imagePoint.x - m_cameraParameters.principalPoint.x) / m_cameraParameters.focalLength.x * zc;
00229 cameraPoint.y = (imagePoint.y - m_cameraParameters.principalPoint.y) / m_cameraParameters.focalLength.y * zc;
00230 cameraPoint.z = zc;
00231 }
00232
00233 void CCalibration::UndistortImageCoordinates(const Vec2d &distortedImagePoint, Vec2d &undistortedImagePoint) const
00234 {
00235
00236 const float d1 = m_cameraParameters.distortion[0];
00237 const float d2 = m_cameraParameters.distortion[1];
00238 const float d3 = m_cameraParameters.distortion[2];
00239 const float d4 = m_cameraParameters.distortion[3];
00240
00241
00242 const float x_const = (distortedImagePoint.x - m_cameraParameters.principalPoint.x) / m_cameraParameters.focalLength.x;
00243 const float y_const = (distortedImagePoint.y - m_cameraParameters.principalPoint.y) / m_cameraParameters.focalLength.y;
00244
00245 float x = x_const;
00246 float y = y_const;
00247
00248 for (int i = 0; i < 10; i++)
00249 {
00250
00251 const float rr = x * x + y * y;
00252 const float factor = 1 + d1 * rr + d2 * rr * rr;
00253
00254
00255 const float dx = d3 * (2 * x * y) + d4 * (rr + 2 * x * x);
00256 const float dy = d3 * (rr + 2 * y * y) + d4 * (2 * x * y);
00257
00258 x = (x_const - dx) / factor;
00259 y = (y_const - dy) / factor;
00260 }
00261
00262 undistortedImagePoint.x = x * m_cameraParameters.focalLength.x + m_cameraParameters.principalPoint.x;
00263 undistortedImagePoint.y = y * m_cameraParameters.focalLength.y + m_cameraParameters.principalPoint.y;
00264 }
00265
00266 void CCalibration::DistortImageCoordinates(const Vec2d &undistortedImagePoint, Vec2d &distortedImagePoint) const
00267 {
00268 const float x = (undistortedImagePoint.x - m_cameraParameters.principalPoint.x) / m_cameraParameters.focalLength.x;
00269 const float y = (undistortedImagePoint.y - m_cameraParameters.principalPoint.y) / m_cameraParameters.focalLength.y;
00270
00271
00272 const float d1 = m_cameraParameters.distortion[0];
00273 const float d2 = m_cameraParameters.distortion[1];
00274 const float d3 = m_cameraParameters.distortion[2];
00275 const float d4 = m_cameraParameters.distortion[3];
00276
00277
00278 const float rr = x * x + y * y;
00279 const float factor = 1 + d1 * rr + d2 * rr * rr;
00280
00281
00282 const float dx = d3 * (2 * x * y) + d4 * (rr + 2 * x * x);
00283 const float dy = d3 * (rr + 2 * y * y) + d4 * (2 * x * y);
00284
00285 distortedImagePoint.x = m_cameraParameters.focalLength.x * (factor * x + dx) + m_cameraParameters.principalPoint.x;
00286 distortedImagePoint.y = m_cameraParameters.focalLength.y * (factor * y + dy) + m_cameraParameters.principalPoint.y;
00287 }
00288
00289
00290 void CCalibration::GetCameraCoordinates(const Vec3d &worldPoint, Vec2d &imagePoint, bool bUseDistortionParameters) const
00291 {
00292 WorldToImageCoordinates(worldPoint, imagePoint, bUseDistortionParameters);
00293 }
00294
00295 void CCalibration::GetWorldCoordinates(const Vec2d &imagePoint, Vec3d &worldPoint, float zc, bool bUseDistortionParameters) const
00296 {
00297 ImageToWorldCoordinates(imagePoint, worldPoint, zc, bUseDistortionParameters);
00298 }
00299
00300 void CCalibration::UndistortCameraCoordinates(const Vec2d &distortedImagePoint, Vec2d &undistortedImagePoint) const
00301 {
00302 UndistortImageCoordinates(distortedImagePoint, undistortedImagePoint);
00303 }
00304
00305 void CCalibration::DistortCameraCoordinates(const Vec2d &undistortedImagePoint, Vec2d &distortedImagePoint) const
00306 {
00307 DistortImageCoordinates(undistortedImagePoint, distortedImagePoint);
00308 }
00309
00310
00311
00312 bool CCalibration::LoadCameraParameters(const char *pCameraParameterFileName, int nCamera, bool bSetExtrinsicToIdentity)
00313 {
00314 int i, nCameraCount = 0;
00315
00316 FILE* f = fopen(pCameraParameterFileName, "r");
00317 if(!f)
00318 return false;
00319
00320 if (fscanf(f, "%d", &nCameraCount) != 1 || nCameraCount < nCamera + 1)
00321 {
00322 fclose(f);
00323 return false;
00324 }
00325
00326 float skip_value, w, h;
00327
00328 for (i = 0; i < nCamera; i++)
00329 for (int j = 0; j < 27; j++)
00330 if (fscanf(f, "%f", &skip_value) != 1)
00331 {
00332 fclose(f);
00333 return false;
00334 }
00335
00336 if (fscanf(f, "%f", &w) != 1) { fclose(f); return false; }
00337 if (fscanf(f, "%f", &h) != 1) { fclose(f); return false; }
00338 if (fscanf(f, "%f", &m_cameraParameters.focalLength.x) != 1) { fclose(f); return false; }
00339 if (fscanf(f, "%f", &skip_value) != 1) { fclose(f); return false; }
00340 if (fscanf(f, "%f", &m_cameraParameters.principalPoint.x) != 1) { fclose(f); return false; }
00341 if (fscanf(f, "%f", &skip_value) != 1) { fclose(f); return false; }
00342 if (fscanf(f, "%f", &m_cameraParameters.focalLength.y) != 1) { fclose(f); return false; }
00343 if (fscanf(f, "%f", &m_cameraParameters.principalPoint.y) != 1) { fclose(f); return false; }
00344 if (fscanf(f, "%f", &skip_value) != 1) { fclose(f); return false; }
00345 if (fscanf(f, "%f", &skip_value) != 1) { fclose(f); return false; }
00346 if (fscanf(f, "%f", &skip_value) != 1) { fclose(f); return false; }
00347 for (i = 0; i < 4; i++)
00348 if (fscanf(f, "%f", &m_cameraParameters.distortion[i]) != 1) { fclose(f); return false; }
00349 if (fscanf(f, "%f", &m_cameraParameters.rotation.r1) != 1) { fclose(f); return false; }
00350 if (fscanf(f, "%f", &m_cameraParameters.rotation.r2) != 1) { fclose(f); return false; }
00351 if (fscanf(f, "%f", &m_cameraParameters.rotation.r3) != 1) { fclose(f); return false; }
00352 if (fscanf(f, "%f", &m_cameraParameters.rotation.r4) != 1) { fclose(f); return false; }
00353 if (fscanf(f, "%f", &m_cameraParameters.rotation.r5) != 1) { fclose(f); return false; }
00354 if (fscanf(f, "%f", &m_cameraParameters.rotation.r6) != 1) { fclose(f); return false; }
00355 if (fscanf(f, "%f", &m_cameraParameters.rotation.r7) != 1) { fclose(f); return false; }
00356 if (fscanf(f, "%f", &m_cameraParameters.rotation.r8) != 1) { fclose(f); return false; }
00357 if (fscanf(f, "%f", &m_cameraParameters.rotation.r9) != 1) { fclose(f); return false; }
00358 if (fscanf(f, "%f", &m_cameraParameters.translation.x) != 1) { fclose(f); return false; }
00359 if (fscanf(f, "%f", &m_cameraParameters.translation.y) != 1) { fclose(f); return false; }
00360 if (fscanf(f, "%f", &m_cameraParameters.translation.z) != 1) { fclose(f); return false; }
00361
00362 m_cameraParameters.width = int(w + 0.5f);
00363 m_cameraParameters.height = int(h + 0.5f);
00364
00365 fclose(f);
00366
00367 if (bSetExtrinsicToIdentity)
00368 {
00369 SetRotation(Math3d::unit_mat);
00370 SetTranslation(Math3d::zero_vec);
00371 }
00372 else
00373 {
00374 CalculateInverseTransformation();
00375 }
00376
00377 return true;
00378 }
00379
00380 bool CCalibration::SaveCameraParameters(const char *pFileName) const
00381 {
00382 const Mat3d &rotation = m_cameraParameters.rotation;
00383 const Vec3d &translation = m_cameraParameters.translation;
00384
00385 const float cx = m_cameraParameters.principalPoint.x;
00386 const float cy = m_cameraParameters.principalPoint.y;
00387 const float fx = m_cameraParameters.focalLength.x;
00388 const float fy = m_cameraParameters.focalLength.y;
00389
00390 const float d1 = m_cameraParameters.distortion[0];
00391 const float d2 = m_cameraParameters.distortion[1];
00392 const float d3 = m_cameraParameters.distortion[2];
00393 const float d4 = m_cameraParameters.distortion[3];
00394
00395 FILE *f = fopen(pFileName, "w");
00396 if (!f)
00397 return false;
00398
00399 fprintf(f, "1\n\n");
00400 fprintf(f, "%i %i %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f ", m_cameraParameters.width, m_cameraParameters.height, fx, 0.0, cx, 0.0, fy, cy, 0.0, 0.0, 1.0);
00401 fprintf(f, "%.10f %.10f %.10f %.10f ", d1, d2, d3, d4);
00402 fprintf(f, "%.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f ", rotation.r1, rotation.r2, rotation.r3, rotation.r4, rotation.r5, rotation.r6, rotation.r7, rotation.r8, rotation.r9);
00403 fprintf(f, "%.10f %.10f %.10f\n", translation.x, translation.y, translation.z);
00404
00405 fclose(f);
00406
00407 return true;
00408 }
00409
00410 void CCalibration::PrintCameraParameters() const
00411 {
00412 printf("cx/cy = %.10f / %.10f\nfx/fy = %.10f / %.10f\nt = %.10f %.10f %.10f\nR = %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f %.10f\nd1/d2/d3/d4 = %.10f %.10f %.10f %.10f\n\n",
00413 m_cameraParameters.principalPoint.x,
00414 m_cameraParameters.principalPoint.y,
00415 m_cameraParameters.focalLength.x,
00416 m_cameraParameters.focalLength.y,
00417 m_cameraParameters.translation.x,
00418 m_cameraParameters.translation.y,
00419 m_cameraParameters.translation.z,
00420 m_cameraParameters.rotation.r1,
00421 m_cameraParameters.rotation.r2,
00422 m_cameraParameters.rotation.r3,
00423 m_cameraParameters.rotation.r4,
00424 m_cameraParameters.rotation.r5,
00425 m_cameraParameters.rotation.r6,
00426 m_cameraParameters.rotation.r7,
00427 m_cameraParameters.rotation.r8,
00428 m_cameraParameters.rotation.r9,
00429 m_cameraParameters.distortion[0],
00430 m_cameraParameters.distortion[1],
00431 m_cameraParameters.distortion[2],
00432 m_cameraParameters.distortion[3]
00433 );
00434 }