POSIT.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:  Posit.cpp
00037 // Author:    Pedram Azad
00038 // Date:      23.01.2008
00039 // ****************************************************************************
00040 
00041 
00042 // ****************************************************************************
00043 // Includes
00044 // ****************************************************************************
00045 
00046 #include <new> // for explicitly using correct new/delete operators on VC DSPs
00047 
00048 #include "POSIT.h"
00049 
00050 #include "Math/Math2d.h"
00051 #include "Math/Math3d.h"
00052 #include "Math/DoubleMatrix.h"
00053 #include "Math/DoubleVector.h"
00054 #include "Math/LinearAlgebra.h"
00055 #include "Calibration/Calibration.h"
00056 
00057 #include <stdio.h>
00058 
00059 
00060 // ****************************************************************************
00061 // This is an implementation of the algorithm described in:
00062 // D. F. DeMenthon and L. S. Davis, "Model-based Object Pose in 25 Lines of Code",
00063 // in Proc. of European Conference on Computer Vision (ECCV), pages 335-343, 1992.
00064 // respectively
00065 // in International Journal of Computer Vision (IJCV), vol. 15, 1995.
00066 // ****************************************************************************
00067 
00068 
00069 
00070 // ****************************************************************************
00071 // Functions
00072 // ****************************************************************************
00073 
00074 bool POSIT::POSIT(const Vec3d *pPoints3D, const Vec2d *pPoints2D, int nPoints, Mat3d &R, Vec3d &t, const CCalibration *pCalibration, int nIterations)
00075 {
00076         const int N = nPoints;
00077         const Vec3d *M = pPoints3D;
00078         const Vec2d *m = pPoints2D;
00079         
00080         if (N < 4)
00081         {
00082                 printf("error: too few points for POSIT\n");
00083                 return false;
00084         }
00085         
00086         const float f = 0.5f * (pCalibration->GetCameraParameters().focalLength.x + pCalibration->GetCameraParameters().focalLength.y);
00087         const float cx = pCalibration->GetCameraParameters().principalPoint.x;
00088         const float cy = pCalibration->GetCameraParameters().principalPoint.y;
00089         
00090         const int N_ = N - 1;
00091         int l;
00092                 
00093         // build matrix A and B (pseudoinverse of A)
00094         CDoubleMatrix A(3, N_);
00095         for (l = 0; l < N_; l++)
00096         {
00097                 A(0, l) = M[l + 1].x - M[0].x;
00098                 A(1, l) = M[l + 1].y - M[0].y;
00099                 A(2, l) = M[l + 1].z - M[0].z;
00100         }
00101         
00102         // calculate pseudoinverse
00103         CDoubleMatrix B(N_, 3);
00104         LinearAlgebra::CalculatePseudoInverseSVD(&A, &B);
00105         
00106         CDoubleVector x_(N_);
00107         CDoubleVector y_(N_);
00108         
00109         // Step 1: initialize epsilons
00110         float *e = new float[N_];
00111         for (l = 0; l < N_; l++)
00112                 e[l] = 0.0f;
00113                 
00114         Vec3d i, j, k;
00115         float s;
00116         
00117         // loop
00118         for (int n = 0; n < nIterations; n++)
00119         {               
00120                 // Step 2
00121                 for (l = 0; l < N_; l++)
00122                 {
00123                         x_.data[l] = (m[l + 1].x - cx) * (1.0f + e[l]) - (m[0].x - cx);
00124                         y_.data[l] = (m[l + 1].y - cy) * (1.0f + e[l]) - (m[0].y - cy);
00125                 }
00126                 
00127                 CDoubleVector I(3), J(3);
00128                 LinearAlgebra::MulMatVec(&B, &x_, &I);
00129                 LinearAlgebra::MulMatVec(&B, &y_, &J);
00130                 
00131                 Math3d::SetVec(i, float(I.data[0]), float(I.data[1]), float(I.data[2]));
00132                 Math3d::SetVec(j, float(J.data[0]), float(J.data[1]), float(J.data[2]));
00133                 
00134                 const float s1 = Math3d::Length(i);
00135                 const float s2 = Math3d::Length(j);
00136                 s = 0.5f * (s1 + s2);
00137                 
00138                 Math3d::NormalizeVec(i);
00139                 Math3d::NormalizeVec(j);
00140                 
00141                 // Step 3
00142                 Math3d::CrossProduct(i, j, k);
00143                 Math3d::NormalizeVec(k);
00144                 
00145                 const float Z0 = f / s;
00146                 
00147                 for (l = 0; l < N_; l++)
00148                 {
00149                         Vec3d M0Mi = { float(A(0, l)), float(A(1, l)), float(A(2, l)) };
00150                         e[l] = Math3d::ScalarProduct(M0Mi, k) / Z0;
00151                 }
00152         }
00153         
00154         delete [] e;
00155         
00156         // Step 4 (checking differences between epsilons as termination condition)
00157         // is skipped and a fixed number of iterations is used
00158         
00159         // Step 5
00160         Math3d::SetVec(t, m[0].x - cx, m[0].y - cy, f);
00161         Math3d::MulVecScalar(t, 1.0f / s, t);
00162                 
00163         Vec3d j_;
00164         Math3d::CrossProduct(k, i, j_);
00165         Math3d::NormalizeVec(j_);
00166         
00167         Math3d::SetMat(R, i.x, i.y, i.z, j_.x, j_.y, j_.z, k.x, k.y, k.z);
00168 
00169         // handle cases in which M[0] is not the zero vector
00170         Vec3d temp;
00171         Math3d::MulMatVec(R, M[0], temp);
00172         Math3d::SubtractFromVec(t, temp);
00173         
00174         // take into account extrinsic calibration
00175         const Mat3d &Rc = pCalibration->m_rotation_inverse;
00176         const Vec3d &tc = pCalibration->m_translation_inverse;
00177         
00178         Math3d::MulMatMat(Rc, R, R);
00179         Math3d::MulMatVec(Rc, t, tc, t);
00180         
00181         return true;
00182 }


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