cvd/camera.h

00001 /*                       
00002     This file is part of the CVD Library.
00003 
00004     Copyright (C) 2005 The Authors
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Lesser General Public
00008     License as published by the Free Software Foundation; either
00009     version 2.1 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Lesser General Public License for more details.
00015 
00016     You should have received a copy of the GNU Lesser General Public
00017     License along with this library; if not, write to the Free Software
00018     Foundation, Inc., 
00019     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 */
00021 //-*- c++ -*-
00022 
00023 #ifndef __CAMERA_H
00024 #define __CAMERA_H
00025 
00026 #include <cmath>
00027 #include <TooN/TooN.h>
00028 #include <TooN/helpers.h>
00029 
00030 template<class T>
00031 inline T SAT(T x){return (x<-1.0/3?-1e9:x);}
00032 
00035 namespace Camera {
00036 
00039   class Linear {
00040   public:
00042     static const int num_parameters=4;
00043 
00046     inline void load(std::istream& is); 
00049     inline void save(std::ostream& os); 
00050 
00052     inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const;
00054     inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const;
00056     inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const;
00057     
00060     inline TooN::Matrix<2,2> get_derivative() const;
00061 
00063     inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const ;
00064 
00068     inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const ;
00069 
00073     inline void update(const TooN::Vector<num_parameters>& updates);
00074 
00077     inline TooN::Vector<num_parameters>& get_parameters() {return my_camera_parameters;}
00078     inline const TooN::Vector<num_parameters>& get_parameters() const {return my_camera_parameters;}
00079 
00080   private:
00081     TooN::Vector<num_parameters> my_camera_parameters; 
00082     mutable TooN::Vector<2> my_last_camframe;
00083   };
00084 
00085 
00088   class Cubic {
00089   public:
00091     static const int num_parameters=5;
00092     
00095     inline void load(std::istream& is);
00098     inline void save(std::ostream& os);
00099 
00101     inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1); 
00103     inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const; 
00105     inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe); 
00106     
00109     inline TooN::Matrix<2,2> get_derivative();
00110 
00112     inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const ;
00113 
00117     inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const ;
00118 
00122     inline void update(const TooN::Vector<num_parameters>& updates);
00123 
00126     inline TooN::Vector<num_parameters>& get_parameters() {return my_camera_parameters;}
00127 
00128   private:
00129     TooN::Vector<num_parameters> my_camera_parameters; // f_u, f_v, u_0, v_0
00130     mutable TooN::Vector<2> my_last_camframe;
00131   };
00132 
00133 
00136   class Quintic {
00137   public:
00139     static const int num_parameters=6;
00140     
00143     inline void load(std::istream& is);
00146     inline void save(std::ostream& os);
00147 
00149     inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const ;
00151 
00152     inline TooN::Vector<2> project_vector(const TooN::Vector<2>& x, const TooN::Vector<2>& d) const {
00153         const double xsq = x*x;
00154         const double& a = my_camera_parameters[4];
00155         const double& b = my_camera_parameters[5];
00156         return (2 * (a + 2*b*xsq) * (x*d) * TooN::diagmult(my_camera_parameters.slice<0,2>(), x) +
00157             (1 + a*xsq + b*xsq*xsq)*TooN::diagmult(my_camera_parameters.slice<0,2>(), d));
00158     }
00159 
00160     inline TooN::Vector<2> project_vector(const TooN::Vector<2>& d) const {
00161         return diagmult(my_camera_parameters.slice<0,2>(), d);
00162     }
00163     inline TooN::Vector<2> unproject_vector(const TooN::Vector<2>& d) const {
00164         TooN::Vector<2> v;
00165         v[0] = d[0]/my_camera_parameters[0];
00166         v[1] = d[1]/my_camera_parameters[1];
00167         return v;
00168     }
00169     inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const; 
00170     inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > project(const TooN::Vector<2>& camframe, const TooN::Matrix<2>& R) const;
00171 
00173     inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe) const;
00174 
00175     inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > unproject(const TooN::Vector<2>& imframe, const TooN::Matrix<2>& R) const;
00176     
00179     inline TooN::Matrix<2,2> get_derivative() const;
00180     inline TooN::Matrix<2,2> get_derivative(const TooN::Vector<2>& x) const;
00181 
00182     inline TooN::Matrix<2,2> get_inv_derivative() const;
00183     inline TooN::Matrix<2,2> get_inv_derivative(const TooN::Vector<2>& x) const;
00184 
00186     inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const ;
00187 
00191     inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const ;
00192 
00196     inline void update(const TooN::Vector<num_parameters>& updates);
00197 
00200     inline const TooN::Vector<num_parameters>& get_parameters() const {return my_camera_parameters;}
00203     inline TooN::Vector<num_parameters>& get_parameters() {return my_camera_parameters;}
00204 
00205   private:
00206     TooN::Vector<num_parameters> my_camera_parameters; // f_u, f_v, u_0, v_0
00207     mutable TooN::Vector<2> my_last_camframe;
00208 
00209     inline double sat(double x)
00210     {
00211         double a;
00212         a = (-3*my_camera_parameters[4] - sqrt(9*my_camera_parameters[4]*my_camera_parameters[4] - 20 * my_camera_parameters[5]))/(10*my_camera_parameters[5]);
00213 
00214         if(x < a)
00215             return x;
00216         else
00217             return 1e9; //(inf)
00218     }
00219   };
00220 
00231     class Harris{
00232 
00233         private:
00234             TooN::Vector<2> radial_distort(const TooN::Vector<2>& camframe) const
00235             {
00236                 double r2 = camframe*camframe;
00237                 return camframe / sqrt(1 + my_camera_parameters[4] * r2);
00238             }
00239             
00240 
00241         public:
00243             static const int num_parameters=5;
00244     
00247             inline void load(std::istream& is);
00248 
00251             inline void save(std::ostream& os)
00252             {
00253                 os << my_camera_parameters;
00254             }
00255 
00256 
00258             inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const
00259             {
00260                 return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00261             }
00262 
00264             inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const 
00265             {
00266                 my_last_camframe = camframe;
00267                 return linearproject(radial_distort(camframe));
00268             }
00269 
00271             inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe)
00272             {
00273                 //Undo the focal length and optic axis.
00274                 TooN::Vector<2> mod_camframe;
00275                 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00276                 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00277                 double rprime2 = mod_camframe*mod_camframe;
00278                 my_last_camframe =  mod_camframe / sqrt(1 - my_camera_parameters[4] * rprime2);
00279                 return my_last_camframe;
00280             }
00281             
00284             inline TooN::Matrix<2,2> get_derivative() const
00285             {
00286                 TooN::Matrix<2,2> J;
00287 
00288                 double xc = my_last_camframe[0];
00289                 double yc = my_last_camframe[1];
00290 
00291                 double fu= my_camera_parameters[0];
00292                 double fv= my_camera_parameters[1];
00293                 double a = my_camera_parameters[4];
00294 
00295                 double g = 1/sqrt(1 + a * (xc*xc + yc*yc));
00296                 double g3= g*g*g;
00297                 
00298                 J[0][0] = fu * (g - 2 * a * xc*xc*g3);
00299                 J[0][1] = -2 * fu * a * xc * yc * g3;
00300                 J[1][0] = -2 * fv * a * xc * yc * g3;
00301                 J[1][1] = fv * (g - 2 * a * yc*yc*g3);
00302 
00303                 return J;
00304             }
00305 
00307             inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const 
00308             {
00309                 TooN::Vector<2> mod_camframe = radial_distort(my_last_camframe);
00310 
00311                 TooN::Matrix<5, 2> result;
00312 
00313                 double xc = my_last_camframe[0];
00314                 double yc = my_last_camframe[1];
00315                 double r2 = xc*xc + yc*yc;
00316 
00317                 double fu= my_camera_parameters[0];
00318                 double fv= my_camera_parameters[1];
00319                 double a = my_camera_parameters[4];
00320 
00321                 double g = 1/sqrt(1 + a * r2);
00322                 double g3= g*g*g;
00323 
00324                 //Derivatives of x_image:
00325                 result[0][0] = mod_camframe[0];
00326                 result[1][0] = 0;
00327                 result[2][0] = 1;
00328                 result[3][0] = 0;
00329                 result[4][0] = - fu * xc * r2 / 2 * g3;
00330 
00331 
00332 
00333                 //Derivatives of y_image:
00334                 result[0][1] = 0;
00335                 result[1][1] = mod_camframe[1];
00336                 result[2][1] = 0;
00337                 result[3][1] = 1;
00338                 result[4][1] = - fv * yc * r2 / 2 * g3;
00339 
00340                 return result;
00341             }
00342 
00346             inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const
00347             {
00348                 return get_parameter_derivs() * direction;
00349             }   
00350 
00354             //inline void update(const TooN::Vector<num_parameters>& updates);
00355 
00358             inline TooN::Vector<num_parameters>& get_parameters() 
00359             {
00360                 return my_camera_parameters;
00361             }
00362 
00363           private:
00364             TooN::Vector<num_parameters> my_camera_parameters; // f_u, f_v, u_0, v_0, alpha
00365             mutable TooN::Vector<2> my_last_camframe;
00366     };
00367 
00370     class SquareHarris{
00371 
00372         private:
00373             TooN::Vector<2> radial_distort(const TooN::Vector<2>& camframe) const
00374             {
00375                 double r2 = camframe*camframe;
00376                 return camframe / sqrt(1 + my_camera_parameters[4] * r2);
00377             }
00378             
00379 
00380         public:
00382             static const int num_parameters=5;
00383     
00386             inline void load(std::istream& is);
00387 
00390             inline void save(std::ostream& os)
00391             {
00392                 os << my_camera_parameters;
00393             }
00394 
00395 
00397             inline TooN::Vector<2> linearproject(const TooN::Vector<2>& camframe, double scale=1) const
00398             {
00399                 return TooN::Vector<2>(scale * (camframe* my_camera_parameters[0]) + my_camera_parameters.slice<2,2>());
00400             }
00401 
00403             inline TooN::Vector<2> project(const TooN::Vector<2>& camframe) const 
00404             {
00405                 my_last_camframe = camframe;
00406                 return linearproject(radial_distort(camframe));
00407             }
00408 
00410             inline TooN::Vector<2> unproject(const TooN::Vector<2>& imframe)
00411             {
00412                 //Undo the focal length and optic axis.
00413                 TooN::Vector<2> mod_camframe;
00414                 mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00415                 mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[0];
00416                 double rprime2 = mod_camframe*mod_camframe;
00417                 my_last_camframe =  mod_camframe / sqrt(1 - my_camera_parameters[4] * rprime2);
00418                 return my_last_camframe;
00419             }
00420             
00423             inline TooN::Matrix<2,2> get_derivative() const
00424             {
00425                 TooN::Matrix<2,2> J;
00426 
00427                 double xc = my_last_camframe[0];
00428                 double yc = my_last_camframe[1];
00429 
00430                 double f= my_camera_parameters[0];
00431                 double a = my_camera_parameters[4];
00432 
00433                 double g = 1/sqrt(1 + a * (xc*xc + yc*yc));
00434                 double g3= g*g*g;
00435                 
00436                 J[0][0] = f * (g - 2 * a * xc*xc*g3);
00437                 J[0][1] = -2 * f * a * xc * yc * g3;
00438                 J[1][0] = -2 * f * a * xc * yc * g3;
00439                 J[1][1] = f * (g - 2 * a * yc*yc*g3);
00440 
00441                 return J;
00442             }
00443 
00445             inline TooN::Matrix<num_parameters,2> get_parameter_derivs() const 
00446             {
00447                 TooN::Vector<2> mod_camframe = radial_distort(my_last_camframe);
00448 
00449                 TooN::Matrix<5, 2> result;
00450 
00451                 double xc = my_last_camframe[0];
00452                 double yc = my_last_camframe[1];
00453                 double r2 = xc*xc + yc*yc;
00454 
00455                 double f= my_camera_parameters[0];
00456                 double a = my_camera_parameters[4];
00457 
00458                 double g = 1/sqrt(1 + a * r2);
00459                 double g3= g*g*g;
00460 
00461                 //Derivatives of x_image:
00462                 result[0][0] = mod_camframe[0];
00463                 result[1][0] = 0;
00464                 result[2][0] = 1;
00465                 result[3][0] = 0;
00466                 result[4][0] = - f * xc * r2 / 2 * g3;
00467 
00468 
00469 
00470                 //Derivatives of y_image:
00471                 result[0][1] = mod_camframe[1];
00472                 result[1][1] = 0;
00473                 result[2][1] = 0;
00474                 result[3][1] = 1;
00475                 result[4][1] = - f * yc * r2 / 2 * g3;
00476 
00477                 return result;
00478             }
00479 
00483             inline TooN::Vector<num_parameters> get_parameter_derivs(const TooN::Vector<2>& direction) const
00484             {
00485                 return get_parameter_derivs() * direction;
00486             }   
00487 
00491             //inline void update(const TooN::Vector<num_parameters>& updates);
00492 
00495             inline TooN::Vector<num_parameters>& get_parameters() 
00496             {
00497                 my_camera_parameters[1] = 0;
00498                 return my_camera_parameters;
00499             }
00500 
00501           private:
00502             TooN::Vector<num_parameters> my_camera_parameters; // f_u, f_v, u_0, v_0, alpha
00503             mutable TooN::Vector<2> my_last_camframe;
00504     };
00505 
00506 
00507 
00508 }
00509 
00510 
00511 
00512 
00514 // Camera::Linear inline functions //
00516 
00517 void Camera::Linear::load(std::istream& is) {
00518   is >> my_camera_parameters;
00519 }
00520 
00521 void Camera::Linear::save(std::ostream& os){
00522   os << my_camera_parameters;
00523 }
00524 
00525 inline TooN::Vector<2> Camera::Linear::linearproject(const TooN::Vector<2>& camframe, double scale) const {
00526   return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00527 }
00528 
00529 inline TooN::Vector<2> Camera::Linear::project(const TooN::Vector<2>& camframe) const {
00530   my_last_camframe = camframe;
00531   return TooN::Vector<2>(diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00532 }
00533 
00534 inline TooN::Vector<2> Camera::Linear::unproject(const TooN::Vector<2>& imframe) const {
00535   my_last_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00536   my_last_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00537   return my_last_camframe;
00538 }
00539 
00540 TooN::Matrix<2,2> Camera::Linear::get_derivative() const {
00541   TooN::Matrix<2,2> result;
00542   result(0,0) = my_camera_parameters[0];
00543   result(1,1) = my_camera_parameters[1];
00544   result(0,1) = result(1,0) = 0;
00545   return result;
00546 }
00547 
00548 TooN::Matrix<Camera::Linear::num_parameters,2> Camera::Linear::get_parameter_derivs() const {
00549   TooN::Matrix<num_parameters,2> result;
00550   result(0,0) = my_last_camframe[0];
00551   result(0,1) = 0;
00552   result(1,0) = 0;
00553   result(1,1) = my_last_camframe[1];
00554   result(2,0) = 1;
00555   result(2,1) = 0;
00556   result(3,0) = 0;
00557   result(3,1) = 1;
00558   return result;
00559 }
00560 
00561 TooN::Vector<Camera::Linear::num_parameters> Camera::Linear::get_parameter_derivs(const TooN::Vector<2>& direction) const {
00562   TooN::Vector<num_parameters> result;
00563   result[0] = my_last_camframe[0] * direction[0];
00564   result[1] = my_last_camframe[1] * direction[1];
00565   result[2] = direction[0];
00566   result[3] = direction[1];
00567 
00568   return result;
00569 }
00570 
00571 void Camera::Linear::update(const TooN::Vector<num_parameters>& updates){
00572   my_camera_parameters+=updates;
00573 }
00574 
00575 
00577 // Camera::Cubic inline functions //
00579 
00580 void Camera::Cubic::load(std::istream& is) {
00581   is >> my_camera_parameters;
00582 }
00583 
00584 void Camera::Cubic::save(std::ostream& os){
00585   os << my_camera_parameters;
00586 }
00587 
00588 inline TooN::Vector<2> Camera::Cubic::linearproject(const TooN::Vector<2>& camframe, double scale){
00589   return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00590 }
00591 
00592 inline TooN::Vector<2> Camera::Cubic::project(const TooN::Vector<2>& camframe) const{
00593   my_last_camframe = camframe;
00594   TooN::Vector<2> mod_camframe = camframe * (1+SAT(my_camera_parameters[4]*(camframe*camframe)));
00595   return TooN::Vector<2>(diagmult(mod_camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00596 }
00597 
00598 inline TooN::Vector<2> Camera::Cubic::unproject(const TooN::Vector<2>& imframe){
00599   TooN::Vector<2> mod_camframe;
00600   mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00601   mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00602 
00603   // first guess
00604   double scale = 1+my_camera_parameters[4]*(mod_camframe*mod_camframe);
00605 
00606   // 3 iterations of Newton-Rapheson
00607   for(int i=0; i<3; i++){
00608     double error = my_camera_parameters[4]*(mod_camframe*mod_camframe) - scale*scale*(scale-1);
00609     double deriv = (3*scale -2)*scale;
00610     scale += error/deriv;
00611   }  
00612   my_last_camframe = mod_camframe/scale;
00613 
00614   return my_last_camframe;
00615 }
00616 
00617 TooN::Matrix<2,2> Camera::Cubic::get_derivative(){
00618   TooN::Matrix<2,2> result;
00619   Identity(result,1+my_camera_parameters[4]*(my_last_camframe*my_last_camframe));
00620   result += (2*my_camera_parameters[4]*my_last_camframe.as_col()) * my_last_camframe.as_row();
00621   result[0] *= my_camera_parameters[0];
00622   result[1] *= my_camera_parameters[1];
00623   return result;
00624 }
00625 
00626 TooN::Matrix<Camera::Cubic::num_parameters,2> Camera::Cubic::get_parameter_derivs() const {
00627   TooN::Vector<2> mod_camframe = my_last_camframe * (1+my_camera_parameters[4]*(my_last_camframe*my_last_camframe));
00628   TooN::Matrix<num_parameters,2> result;
00629   result(0,0) = mod_camframe[0]*my_camera_parameters[0];
00630   result(0,1) = 0;
00631   result(1,0) = 0;
00632   result(1,1) = mod_camframe[1]*my_camera_parameters[1];
00633   result(2,0) = 1*my_camera_parameters[0];
00634   result(2,1) = 0;
00635   result(3,0) = 0;
00636   result(3,1) = 1*my_camera_parameters[1];
00637   result[4] = diagmult(my_last_camframe,my_camera_parameters.slice<0,2>())*(my_last_camframe*my_last_camframe);
00638   return result;
00639 }
00640 
00641 TooN::Vector<Camera::Cubic::num_parameters> Camera::Cubic::get_parameter_derivs(const TooN::Vector<2>& direction) const {
00642   TooN::Vector<2> mod_camframe = my_last_camframe * (1+my_camera_parameters[4]*(my_last_camframe*my_last_camframe));
00643   TooN::Vector<num_parameters> result;
00644   result[0] = mod_camframe[0] * direction[0] *my_camera_parameters[0];
00645   result[1] = mod_camframe[1] * direction[1] *my_camera_parameters[1];
00646   result[2] = direction[0] *my_camera_parameters[0];
00647   result[3] = direction[1] *my_camera_parameters[1];
00648   result[4] = (diagmult(my_last_camframe,my_camera_parameters.slice<0,2>())*direction)*(my_last_camframe*my_last_camframe);
00649   return result;
00650 }
00651 
00652 void Camera::Cubic::update(const TooN::Vector<num_parameters>& updates){
00653   double fu=my_camera_parameters[0];
00654   double fv=my_camera_parameters[1];
00655   my_camera_parameters[0]+=fu*updates[0];
00656   my_camera_parameters[1]+=fv*updates[1];
00657   my_camera_parameters[2]+=fu*updates[2];
00658   my_camera_parameters[3]+=fv*updates[3];
00659   my_camera_parameters[4]+=updates[4];
00660   //my_camera_parameters+=updates;
00661 }
00662 
00664 // Camera::Quintic inline functions //
00666 
00667 void Camera::Quintic::load(std::istream& is) {
00668   is >> my_camera_parameters;
00669 }
00670 
00671 void Camera::Quintic::save(std::ostream& os){
00672   os << my_camera_parameters;
00673 }
00674 
00675 inline TooN::Vector<2> Camera::Quintic::linearproject(const TooN::Vector<2>& camframe, double scale) const {
00676   return TooN::Vector<2>(scale * diagmult(camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00677 }
00678 
00679 inline TooN::Vector<2> Camera::Quintic::project(const TooN::Vector<2>& camframe) const {
00680   my_last_camframe = camframe;
00681   double sc = /*sat*/(camframe*camframe);
00682   TooN::Vector<2> mod_camframe = camframe * (1 + sc*(my_camera_parameters[4] + sc*my_camera_parameters[5]));
00683   return TooN::Vector<2>(diagmult(mod_camframe, my_camera_parameters.slice<0,2>()) + my_camera_parameters.slice<2,2>());
00684 }
00685 
00686 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > Camera::Quintic::project(const TooN::Vector<2>& camframe, const TooN::Matrix<2>& R) const
00687 {
00688     std::pair<TooN::Vector<2>, TooN::Matrix<2> > result;
00689     result.first = this->project(camframe);
00690     const TooN::Matrix<2> J = this->get_derivative();
00691     result.second = J * R * J.T();
00692     return result;
00693 }
00694 
00695 inline TooN::Vector<2> Camera::Quintic::unproject(const TooN::Vector<2>& imframe) const {
00696   TooN::Vector<2> mod_camframe;
00697   mod_camframe[0] = (imframe[0]-my_camera_parameters[2])/my_camera_parameters[0];
00698   mod_camframe[1] = (imframe[1]-my_camera_parameters[3])/my_camera_parameters[1];
00699 
00700   // first guess
00701   double scale = mod_camframe*mod_camframe;
00702 
00703   // 3 iterations of Newton-Rapheson
00704   for(int i=0; i<3; i++){
00705     double temp=1+scale*(my_camera_parameters[4]+my_camera_parameters[5]*scale);
00706     double error = mod_camframe*mod_camframe - scale*temp*temp;
00707     double deriv = temp*(temp+2*scale*(my_camera_parameters[4]+2*my_camera_parameters[5]*scale));
00708     scale += error/deriv;
00709   }  
00710   my_last_camframe = mod_camframe/(1+scale*(my_camera_parameters[4]+my_camera_parameters[5]*scale));
00711 
00712   //std::cout<<"Done inverse on "<<imframe<<" - when reprojected get "<<project(my_last_camframe)<<std::endl;
00713 
00714   return my_last_camframe;
00715 }
00716 
00717 inline std::pair<TooN::Vector<2>, TooN::Matrix<2> > Camera::Quintic::unproject(const TooN::Vector<2>& imframe, const TooN::Matrix<2>& R) const
00718 {
00719     std::pair<TooN::Vector<2>, TooN::Matrix<2> > result;
00720     result.first = this->unproject(imframe);
00721     TooN::Matrix<2> J = get_derivative();
00722     double rdet = 1.0/ (J[0][0] * J[1][1] - J[0][1] * J[1][0]);
00723     TooN::Matrix<2> Jinv;
00724     Jinv[0][0] = rdet * J[1][1];
00725     Jinv[1][1] = rdet * J[0][0];
00726     Jinv[0][1] = -rdet * J[0][1];
00727     Jinv[1][0] = -rdet * J[1][0];    
00728     result.second = Jinv * R * Jinv.T();
00729     return result;
00730 }
00731 
00732 
00733 TooN::Matrix<2,2> Camera::Quintic::get_derivative() const {
00734   TooN::Matrix<2,2> result;
00735   double temp1=my_last_camframe*my_last_camframe;
00736   double temp2=my_camera_parameters[5]*temp1;
00737   Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
00738   result += (2*(my_camera_parameters[4]+2*temp2)*my_last_camframe.as_col()) * my_last_camframe.as_row();
00739   result[0] *= my_camera_parameters[0];
00740   result[1] *= my_camera_parameters[1];
00741   return result;
00742 }
00743 
00744 
00745 
00746 TooN::Matrix<2,2> Camera::Quintic::get_inv_derivative() const {
00747   TooN::Matrix<2,2> result;
00748   double temp1=my_last_camframe*my_last_camframe;
00749   double temp2=my_camera_parameters[5]*temp1;
00750   double temp3=2.0*(my_camera_parameters[4]+2.0*temp2);
00751    
00752   Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
00753 
00754   result[0][0] +=  my_last_camframe[1]*my_last_camframe[1]*temp3;
00755   result[0][1]  =-(temp3*my_last_camframe[0]*my_last_camframe[1]);
00756   
00757   result[1][1] +=  my_last_camframe[0]*my_last_camframe[0]*temp3;
00758   result[1][0]  =-(temp3*my_last_camframe[0]*my_last_camframe[1]);
00759   
00760   (result.T())[0] *= my_camera_parameters[1];
00761   (result.T())[1] *= my_camera_parameters[0];
00762 
00763   result /= (result[0][0]*result[1][1] - result[1][0]*result[0][1]);
00764   
00765   return result;
00766 }
00767 
00768 TooN::Matrix<2,2> Camera::Quintic::get_inv_derivative(const TooN::Vector<2>& x) const
00769 {
00770 
00771   TooN::Matrix<2,2> result;
00772   double temp1=x*x;
00773   double temp2=my_camera_parameters[5]*temp1;
00774   double temp3=2.0*(my_camera_parameters[4]+2.0*temp2);
00775 
00776   Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
00777 
00778   result[0][0] +=  x[1]*x[1]*temp3;
00779   result[0][1]  =-(temp3*x[0]*x[1]);
00780   
00781   result[1][1] +=  x[0]*x[0]*temp3;
00782   result[1][0]  =-(temp3*x[0]*x[1]);
00783   
00784   (result.T())[0] *= my_camera_parameters[1];
00785   (result.T())[1] *= my_camera_parameters[0];
00786 
00787   result /= (result[0][0]*result[1][1] - result[1][0]*result[0][1]);
00788   
00789   return result;
00790 
00791 }
00792 
00793 TooN::Matrix<2,2> Camera::Quintic::get_derivative(const TooN::Vector<2>& x) const {
00794     TooN::Matrix<2,2> result;
00795     double temp1=x*x;
00796     double temp2=my_camera_parameters[5]*temp1;
00797     Identity(result,1+temp1*(my_camera_parameters[4]+temp2));
00798     result += (2*(my_camera_parameters[4]+2*temp2)*x.as_col()) * x.as_row();
00799     result[0] *= my_camera_parameters[0];
00800     result[1] *= my_camera_parameters[1];
00801     return result;
00802 }
00803 
00804 TooN::Matrix<Camera::Quintic::num_parameters,2> Camera::Quintic::get_parameter_derivs() const {
00805   TooN::Matrix<num_parameters,2> result;
00806   double r2 = my_last_camframe * my_last_camframe;
00807   double r4 = r2 * r2;
00808   TooN::Vector<2> mod_camframe = my_last_camframe * (1+ r2 * (my_camera_parameters[4] + r2 * my_camera_parameters[5]));
00809 
00810   result(0,0) = mod_camframe[0];
00811   result(1,0) = 0;
00812   result(2,0) = 1;
00813   result(3,0) = 0;
00814   result(4,0) = my_camera_parameters[0]*my_last_camframe[0]*r2;
00815   result(5,0) = my_camera_parameters[0]*my_last_camframe[0]*r4;
00816 
00817   result(0,1) = 0;
00818   result(1,1) = mod_camframe[1];
00819   result(2,1) = 0;
00820   result(3,1) = 1;
00821   result(4,1) = my_camera_parameters[1]*my_last_camframe[1]*r2;
00822   result(5,1) = my_camera_parameters[1]*my_last_camframe[1]*r4;
00823   
00824   //cout<<"Finish me!\n";                        
00825   return result;
00826 }
00827 
00828 TooN::Vector<Camera::Quintic::num_parameters> Camera::Quintic::get_parameter_derivs(const TooN::Vector<2>& direction) const {
00829   //TooN::Vector<num_parameters> result;
00830   //cout<<"Finish me!\n";                        
00831   //FIXME improve this somewhat
00832   return get_parameter_derivs() * direction;
00833 }
00834 
00835 void Camera::Quintic::update(const TooN::Vector<num_parameters>& updates){
00836   double fu = my_camera_parameters[0];
00837   double fv = my_camera_parameters[1];
00838 
00839   my_camera_parameters[0]+=updates[0]*fu;
00840   my_camera_parameters[1]+=updates[1]*fv;
00841   my_camera_parameters[2]+=updates[2]*fu;
00842   my_camera_parameters[3]+=updates[3]*fv;
00843   my_camera_parameters[4]+=updates[4];
00844   my_camera_parameters[5]+=updates[5];
00845 }
00846 
00847 #endif

Generated on Wed Feb 18 10:23:00 2009 for CVD by  doxygen 1.5.3