IVT
StereoCalibrationCV.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) 2013 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:  StereoCalibrationCV.cpp
00037 // Author:    Pedram Azad
00038 // Date:      2006
00039 // ****************************************************************************
00040 
00041 
00042 // ****************************************************************************
00043 // Includes
00044 // ****************************************************************************
00045 
00046 #include <new> // for explicitly using correct new/delete operators on VC DSPs
00047 
00048 #include "StereoCalibrationCV.h"
00049 #include "StereoCalibration.h"
00050 #include "Calibration.h"
00051 #include "Math/Math3d.h"
00052 
00053 #include <cvaux.h>
00054 #include <stdio.h>
00055 
00056 
00057 
00058 static void FillMatrix(float *pTargetMatrix, const Mat3d &sourceMatrix)
00059 {
00060         pTargetMatrix[0] = sourceMatrix.r1;
00061         pTargetMatrix[1] = sourceMatrix.r2;
00062         pTargetMatrix[2] = sourceMatrix.r3;
00063         pTargetMatrix[3] = sourceMatrix.r4;
00064         pTargetMatrix[4] = sourceMatrix.r5;
00065         pTargetMatrix[5] = sourceMatrix.r6;
00066         pTargetMatrix[6] = sourceMatrix.r7;
00067         pTargetMatrix[7] = sourceMatrix.r8;
00068         pTargetMatrix[8] = sourceMatrix.r9;
00069 }
00070 
00071 static void FillMatrix(double *pTargetMatrix, const Mat3d &sourceMatrix)
00072 {
00073         pTargetMatrix[0] = sourceMatrix.r1;
00074         pTargetMatrix[1] = sourceMatrix.r2;
00075         pTargetMatrix[2] = sourceMatrix.r3;
00076         pTargetMatrix[3] = sourceMatrix.r4;
00077         pTargetMatrix[4] = sourceMatrix.r5;
00078         pTargetMatrix[5] = sourceMatrix.r6;
00079         pTargetMatrix[6] = sourceMatrix.r7;
00080         pTargetMatrix[7] = sourceMatrix.r8;
00081         pTargetMatrix[8] = sourceMatrix.r9;
00082 }
00083 
00084 static void FillVector(float *pTargetVector, const Vec3d &sourceVector)
00085 {
00086         pTargetVector[0] = (float) sourceVector.x;
00087         pTargetVector[1] = (float) sourceVector.y;
00088         pTargetVector[2] = (float) sourceVector.z;
00089 }
00090 
00091 static void FillCalibrationMatrix(float *pTargetMatrix, const CCalibration::CCameraParameters &cameraParameters)
00092 {
00093         pTargetMatrix[0] = (float) cameraParameters.focalLength.x;
00094         pTargetMatrix[1] = 0;
00095         pTargetMatrix[2] = (float) cameraParameters.principalPoint.x;
00096         pTargetMatrix[3] = 0;
00097         pTargetMatrix[4] = (float) cameraParameters.focalLength.y;
00098         pTargetMatrix[5] = (float) cameraParameters.principalPoint.y;
00099         pTargetMatrix[6] = 0;
00100         pTargetMatrix[7] = 0;
00101         pTargetMatrix[8] = 1;
00102 }
00103 
00104 
00105 void StereoCalibrationCV::CalculateRectificationHomographies(CStereoCalibration *pStereoCalibration)
00106 {
00107         CvStereoCamera stereoParams;
00108         CvCamera leftCamera, rightCamera;
00109         
00110         stereoParams.camera[0] = &leftCamera;
00111         stereoParams.camera[1] = &rightCamera;
00112         
00113         stereoParams.camera[0]->imgSize[0] = (float) pStereoCalibration->width;
00114     stereoParams.camera[0]->imgSize[1] = (float) pStereoCalibration->height;
00115     stereoParams.camera[1]->imgSize[0] = (float) pStereoCalibration->width;
00116     stereoParams.camera[1]->imgSize[1] = (float) pStereoCalibration->height;
00117         
00118         const CCalibration::CCameraParameters &leftCameraParameters = pStereoCalibration->GetLeftCalibration()->GetCameraParameters();
00119         const CCalibration::CCameraParameters &rightCameraParameters = pStereoCalibration->GetRightCalibration()->GetCameraParameters();
00120         
00121         FillMatrix(stereoParams.rotMatrix, pStereoCalibration->GetRightCalibration()->m_rotation_inverse);
00122         FillVector(stereoParams.transVector, pStereoCalibration->GetRightCalibration()->m_translation_inverse);
00123         
00124         int i;
00125         
00126         leftCamera.imgSize[0] = (float) leftCameraParameters.width;
00127         leftCamera.imgSize[1] = (float) leftCameraParameters.height;
00128         FillCalibrationMatrix(leftCamera.matrix, leftCameraParameters);
00129         for (i = 0; i < 4; i++) leftCamera.distortion[i] = (float) leftCameraParameters.distortion[i];
00130         FillMatrix(leftCamera.rotMatr, leftCameraParameters.rotation);
00131         FillVector(leftCamera.transVect, leftCameraParameters.translation);
00132         
00133         rightCamera.imgSize[0] = (float) rightCameraParameters.width;
00134         rightCamera.imgSize[1] = (float) rightCameraParameters.height;
00135         FillCalibrationMatrix(rightCamera.matrix, rightCameraParameters);
00136         for (i = 0; i < 4; i++) rightCamera.distortion[i] = (float) rightCameraParameters.distortion[i];
00137         FillMatrix(rightCamera.rotMatr, rightCameraParameters.rotation);
00138         FillVector(rightCamera.transVect, rightCameraParameters.translation);
00139         
00140         icvComputeRestStereoParams(&stereoParams);
00141         
00142         Math3d::SetMat(pStereoCalibration->rectificationHomographyLeft,
00143                 float(stereoParams.coeffs[0][0][0]),
00144                 float(stereoParams.coeffs[0][0][1]),
00145                 float(stereoParams.coeffs[0][0][2]),
00146                 float(stereoParams.coeffs[0][1][0]),
00147                 float(stereoParams.coeffs[0][1][1]),
00148                 float(stereoParams.coeffs[0][1][2]),
00149                 float(stereoParams.coeffs[0][2][0]),
00150                 float(stereoParams.coeffs[0][2][1]),
00151                 float(stereoParams.coeffs[0][2][2])
00152         );
00153         
00154         Math3d::SetMat(pStereoCalibration->rectificationHomographyRight,
00155                 float(stereoParams.coeffs[1][0][0]),
00156                 float(stereoParams.coeffs[1][0][1]),
00157                 float(stereoParams.coeffs[1][0][2]),
00158                 float(stereoParams.coeffs[1][1][0]),
00159                 float(stereoParams.coeffs[1][1][1]),
00160                 float(stereoParams.coeffs[1][1][2]),
00161                 float(stereoParams.coeffs[1][2][0]),
00162                 float(stereoParams.coeffs[1][2][1]),
00163                 float(stereoParams.coeffs[1][2][2])
00164         );
00165 }
00166 
00167 /*void StereoCalibrationCV::CalculateRectificationHomographiesExperimental(CStereoCalibration *pStereoCalibration)
00168 {
00169         // algorithm by Fusiello et al. from 2000:
00170         // "A compact algorithm for rectification of stereo pairs"
00171         const CCalibration::CCameraParameters &left = pStereoCalibration->GetLeftCalibration()->GetCameraParameters();
00172         const CCalibration::CCameraParameters &right = pStereoCalibration->GetRightCalibration()->GetCameraParameters();
00173         
00174         const Mat3d &R1 = pStereoCalibration->GetLeftCalibration()->m_rotation_inverse;//left.rotation;
00175         const Mat3d &R2 = pStereoCalibration->GetRightCalibration()->m_rotation_inverse;//right.rotation;
00176         
00177         const Vec3d &t1 = pStereoCalibration->GetLeftCalibration()->m_translation_inverse;//left.translation;
00178         const Vec3d &t2 = pStereoCalibration->GetRightCalibration()->m_translation_inverse;//right.translation;
00179         
00180         const Mat3d A1 = { -left.focalLength.x, 0, left.principalPoint.x, 0, -left.focalLength.y, left.principalPoint.y, 0, 0, 1 };
00181         const Mat3d A2 = { -right.focalLength.x, 0, right.principalPoint.x, 0, -right.focalLength.y, right.principalPoint.y, 0, 0, 1 };
00182         
00183         printf("\nA1 = %f %f %f\n%f %f %f\n%f %f %f\n\n", A1.r1, A1.r2, A1.r3, A1.r4, A1.r5, A1.r6, A1.r7, A1.r8, A1.r9);
00184         printf("R1 = %f %f %f\n%f %f %f\n%f %f %f\n\n", R1.r1, R1.r2, R1.r3, R1.r4, R1.r5, R1.r6, R1.r7, R1.r8, R1.r9);
00185         printf("t1 = %f %f %f\n\n\n", t1.x, t1.y, t1.z);
00186         
00187         printf("A2 = %f %f %f\n%f %f %f\n%f %f %f\n\n", A2.r1, A2.r2, A2.r3, A2.r4, A2.r5, A2.r6, A2.r7, A2.r8, A2.r9);
00188         printf("R2 = %f %f %f\n%f %f %f\n%f %f %f\n\n", R2.r1, R2.r2, R2.r3, R2.r4, R2.r5, R2.r6, R2.r7, R2.r8, R2.r9);
00189         printf("t2 = %f %f %f\n\n\n", t2.x, t2.y, t2.z);
00190 
00191         const Vec3d &c1 = pStereoCalibration->GetLeftCalibration()->m_translation_inverse;
00192         const Vec3d &c2 = pStereoCalibration->GetRightCalibration()->m_translation_inverse;
00193         
00194         Vec3d v1, v2, v3, k = { R1.r7, R1.r8, R1.r9 };
00195         
00196         Math3d::SubtractVecVec(c1, c2, v1);
00197         Math3d::CrossProduct(k, v1, v2);
00198         Math3d::CrossProduct(v1, v2, v3);
00199         
00200         Math3d::NormalizeVec(v1);
00201         Math3d::NormalizeVec(v2);
00202         Math3d::NormalizeVec(v3);
00203         
00204         Mat3d R = { v1.x, v1.y, v1.z, v2.x, v2.y, v2.z, v3.x, v3.y, v3.z };
00205         Mat3d A =
00206         {
00207                 0.5f * (left.focalLength.x + right.focalLength.x), 0, 0.5f * (left.principalPoint.x + right.principalPoint.x),
00208                 0, 0.5f * (left.focalLength.y + right.focalLength.y), 0.5f * (left.principalPoint.y + right.principalPoint.y),
00209                 0, 0, 1
00210         };
00211         
00212         Mat3d T1, T2, M;
00213         
00214         Math3d::MulMatMat(A, R, T1);
00215         Math3d::MulMatMat(A1, R1, M);
00216         Math3d::Invert(M, M);
00217         Math3d::MulMatMat(T1, M, T1);
00218         
00219         Math3d::MulMatMat(A, R, T2);
00220         Math3d::MulMatMat(A2, R2, M);
00221         Math3d::Invert(M, M);
00222         Math3d::MulMatMat(T2, M, T2);
00223         
00224         Math3d::SetMat(pStereoCalibration->rectificationHomographyLeft, T1);
00225         Math3d::SetMat(pStereoCalibration->rectificationHomographyRight, T2);
00226 }*/