Calibration.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // This file is part of the Integrating Vision Toolkit (IVT).
00003 //
00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
00006 //
00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
00008 // All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are met:
00012 //
00013 // 1. Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 // 2. Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the distribution.
00019 //
00020 // 3. Neither the name of the KIT nor the names of its contributors may be
00021 //    used to endorse or promote products derived from this software
00022 //    without specific prior written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 // ****************************************************************************
00035 // ****************************************************************************
00036 // Filename:  Calibration.cpp
00037 // Author:    Pedram Azad
00038 // Date:      2004
00039 // ****************************************************************************
00040 // Changes:   17.11.2006, Stefanie Speidel
00041 //            * improved calculations for radial lens distortion
00042 //            * added calculations for tangential lens distortion
00043 // ****************************************************************************
00044 
00045 
00046 // ****************************************************************************
00047 // Includes
00048 // ****************************************************************************
00049 
00050 #include <new> // for explicitly using correct new/delete operators on VC DSPs
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 // Constructor / Destructor
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 // Methods
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         // distortion parameters
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         // undistort
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                 // radial distortion
00251                 const float rr = x * x + y * y;
00252                 const float factor = 1 + d1 * rr + d2 * rr * rr;
00253                 
00254                 // tangential distortion
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         // distortion parameters
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         // radial distortion
00278         const float rr = x * x + y * y;
00279         const float factor = 1 + d1 * rr + d2 * rr * rr;
00280         
00281         // tangential distortion
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 // <obsolete names>
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 // </obsolete names>
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 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:57