Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
cameraPinhole.hpp
00001 /* $Id$ */
00002 
00003 #ifndef _CAMERA_PINHOLE_HPP
00004 #define _CAMERA_PINHOLE_HPP
00005 
00006 #include <iostream>
00007 
00008 #include "kernel/jafarException.hpp"
00009 #include "kernel/keyValueFile.hpp"
00010 #include "jmath/jblas.hpp"
00011 
00012 namespace jafar {
00013   namespace camera {
00014 
00015     class StereoBench;
00016 
00026     class CameraPinhole : public jafar::kernel::KeyValueFileLoad {
00027 
00028     protected:
00029 
00030       void loadKeyValueFile(jafar::kernel::KeyValueFile const& keyValueFile);
00031 
00032     public :
00033 
00034       static const double epsilon;
00035 
00036       int width;
00037       int height;
00038       double u0;
00039       double v0;
00040       double alphaU;
00041       double alphaV;
00042 
00044       jblas::mat Ph;
00045 
00047       jblas::mat_range P;
00048 
00050       CameraPinhole();
00051 
00053       CameraPinhole(CameraPinhole const& c_);
00054 
00055       ~CameraPinhole();
00056       
00057       double getApertureU() const;
00058       double getApertureV() const;
00059 
00062       void setParameters(int width_, int height_, 
00063        double u0_, double v0_, 
00064        double alphaU_, double alphaV_);
00065 
00068       void applyScale(double scale);
00069 
00076       template<class Vec, class Pix>
00077       bool project(Vec const& v, Pix& pix) const
00078       {
00079   JFR_PRECOND(v.size() == 3,
00080         "CameraPinhole::project: size of v does not match");
00081   JFR_PRECOND(pix.size() == 2,
00082         "CameraPinhole::project: size of pix does not match");
00083   JFR_NUMERIC(fabs(v(2)) > epsilon,
00084            "CameraPinhole::project: 3D point z is too small: " << v);
00085 
00086   // normalized vector
00087   jblas::vec3 v_n;
00088   v_n(0) = v(0)/v(2);
00089   v_n(1) = v(1)/v(2);
00090   v_n(2) = 1.0;
00091   
00092   pix.assign(ublas::prod(P,v_n));
00093 
00094   if ( (v(2)<0.0) ) // the point is behind the camera
00095     return false;
00096   else if ((pix(0) < 0) || (pix(0) > width) || (pix(1) < 0) || (pix(1) > height)) // the point is outside the image
00097     return false;
00098   else 
00099     return true;
00100       }
00101 
00106       template<class Vec, class Pix>
00107       bool projectH(Vec const& v, Pix& pix) const
00108       {
00109   JFR_PRECOND(v.size() == 4,
00110         "CameraPinhole::project: size of v does not match");
00111   JFR_PRECOND(pix.size() == 3,
00112         "CameraPinhole::project: size of pix does not match");
00113   
00114   pix.assign(ublas::prod(Ph,v));
00115 
00116   if ( (v(2)<0.0) ) // the point is behind the camera
00117     return false;
00118   else if ((pix(0) < 0) || (pix(0) > width) || (pix(1) < 0) || (pix(1) > height)) // the point is outside the image
00119     return false;
00120   else 
00121     return true;
00122       }
00123 
00125       template<class Vec, class Mat>
00126       void projectJac(Vec const& v, Mat& J) const
00127       {
00128   JFR_PRECOND(v.size() == 3,
00129         "CameraPinhole::projectJac: size of v does not match");
00130   JFR_PRECOND(J.size1() == 2 && J.size2() == 3,
00131         "CameraPinhole::projectJac: size of J does not match");
00132   JFR_NUMERIC(fabs(v(2)) > epsilon,
00133             "CameraPinhole::projectJac: 3D points z is too small: " << v);
00134 
00135   double t1 = 0.1e1 / v(2);
00136   double t4 = v(2) * v(2);
00137   double t5 = 0.1e1 / t4;
00138   J(0,0) = alphaU * t1;
00139   J(0,1) = 0.0e0;
00140   J(0,2) = -alphaU * v(0) * t5;
00141   J(1,0) = 0.0e0;
00142   J(1,1) = alphaV * t1;
00143   J(1,2) = -alphaV * v(1) * t5;
00144       }
00145 
00147       template<class Vec, class Mat, class Pix>
00148         void projectJac(Vec const& v, Pix& pix, Mat& J) const
00149       {
00150         project(v,pix);
00151         projectJac(v,J);
00152       }
00153 
00155       template<class Pix, class Vec>
00156       void imageToCameraFrame(Pix const& pix, Vec& v) const
00157       {
00158   JFR_PRECOND(pix.size() == 2,
00159         "CameraPinhole::imageToCameraFrame: size of pix does not match");
00160   JFR_PRECOND(v.size() == 3,
00161         "CameraPinhole::imageToCameraFrame: size of v does not match");
00162       
00163   v(0) = (pix(0) - u0) / alphaU;
00164   v(1) = (pix(1) - v0) / alphaV;
00165   v(2) = 1.0;
00166       }
00167 
00169       template<class Pix, class Mat>
00170       void imageToCameraFrameJac(Pix const& pix, Mat& J) const
00171       {
00172   JFR_PRECOND(pix.size() == 2,
00173         "CameraPinhole::imageToCameraFrameJac: size of pix does not match");
00174   JFR_PRECOND(J.size1() == 3 && J.size1() == 2,
00175         "CameraPinhole::imageToCameraFrameJac: size of j does not match");
00176       
00177   J.clear();
00178   J(0,0) = 1/alphaU;
00179   J(1,1) = 1/alphaV;
00180       }
00181 
00183       template<class Pix, class Vec>
00184       void imageToCameraFrameDirection(Pix const& pix_, Vec& v) const
00185       {
00186   JFR_PRECOND(pix_.size() == 2,
00187         "CameraPinhole::imageToCameraFrameDirection: size of pix does not match");
00188   JFR_PRECOND(v.size() == 3,
00189         "CameraPinhole::imageToCameraFrameDirection: size of v does not match");
00190       
00191   imageToCameraFrame(pix_, v);
00192   v /= ublas::norm_2(v);
00193       }
00194 
00196       template<class Pix, class Mat>
00197       void imageToCameraFrameDirectionJac(Pix const& pix, Mat& J) const
00198       {
00199   JFR_PRECOND(pix.size() == 2,
00200         "CameraPinhole::imageToCameraFrameDirectionJac: size of pix does not match");
00201   JFR_PRECOND(J.size1() == 3 && J.size2() == 2,
00202         "CameraPinhole::imageToCameraFrameDirectionJac: size of J does not match");
00203 
00204   double u = pix(0);
00205   double v = pix(1);
00206 
00207   /* begin copy/paste from maple */
00208   double t1 = u - u0;
00209   double t2 = 0.1e1 / alphaU;
00210   double t3 = t1 * t2;
00211   double t4 = fabs(t3);
00212   double t5 = t4 * t4;
00213   double t6 = v - v0;
00214   double t7 = 0.1e1 / alphaV;
00215   double t8 = t6 * t7;
00216   double t9 = fabs(t8);
00217   double t10 = t9 * t9;
00218   double t11 = 0.100e1 + t5 + t10;
00219   double t12 = sqrt(t11);
00220   double t14 = 0.1e1 / t12 / t11;
00221   double t15 = t14 * t1;
00222   double t16 = alphaU * alphaU;
00223   double t19 = fabs(t3) / t3;
00224   double t22 = 0.1e1 / t12;
00225   double t26 = fabs(t8) / t8;
00226   double t30 = t14 * t6;
00227   double t35 = alphaV * alphaV;
00228   J(0,0) = -t15 / t16 * t4 * t19 + t22 * t2;
00229   J(0,1) = -t15 * t2 * t9 * t26 * t7;
00230   J(1,0) = -t30 * t7 * t4 * t19 * t2;
00231   J(1,1) = -t30 / t35 * t9 * t26 + t22 * t7;
00232   J(2,0) = -0.10e1 * t14 * t4 * t19 * t2;
00233   J(2,1) = -0.10e1 * t14 * t9 * t26 * t7;
00234   /* end copy/paste from maple */
00235 
00236       }
00237     
00238     
00241     jblas::vec4 getIntrinsicParams() 
00242       {
00243       jblas::vec4 k;
00244       k(0) = u0;
00245       k(1) = v0;
00246       k(2) = alphaU;
00247       k(3) = alphaV;
00248       
00249       return k;
00250       };
00251     
00252       friend class StereoBench;
00253 
00254     }; // class CameraPinhole
00255 
00256     std::ostream& operator <<(std::ostream& s, const jafar::camera::CameraPinhole& camera_);
00257 
00258 
00266     class StereoBench : public jafar::kernel::KeyValueFileLoad {
00267 
00268     protected:
00269 
00270       void loadKeyValueFile(jafar::kernel::KeyValueFile const& keyValueFile);
00271 
00272     public:
00273 
00274       static const double epsilon;
00275 
00276       CameraPinhole leftCamera;
00277 
00279       double alpha;
00280       
00282       double baseline;
00283 
00284       StereoBench();
00285 
00286       StereoBench(StereoBench const& s);
00287 
00288       ~StereoBench() {};
00289 
00292       void setParameters(int width_, int height_, 
00293        double u0_, double v0_, 
00294        double alphaU_, double alphaV_,
00295        double alpha_);
00296 
00299       void applyScale(double scale);
00300 
00302       template<class Pix, class Vec>
00303       void compute3dPoint(Pix const& pix, double disp, Vec& point) const {
00304   JFR_PRECOND(pix.size() == 2,
00305         "StereoBench::compute3dPoint: pix is a 2-vector (u,v)");
00306   JFR_PRECOND(point.size() == 3,
00307         "StereoBench::compute3dPoint: point is a 3-vector (x,y,z)");
00308 
00309   JFR_NUMERIC(disp > epsilon,
00310         "StereoBench::compute3dPoint: disparity value is too small (disp=" << disp <<")");
00311 
00312   point(2) = alpha / disp;
00313 
00314   double beta  = (pix(0) - leftCamera.u0) / leftCamera.alphaU;
00315   double gamma = (pix(1) - leftCamera.v0) / leftCamera.alphaV;
00316 
00317   point(0) = point(2) * beta;
00318   point(1) = point(2) * gamma;  
00319   
00320       }
00321 
00322       template<class Pix, class Mat>
00323       void compute3dPointJac(Pix const& pix, double disp, Mat& J) const {      
00324   JFR_PRECOND(pix.size() == 2,
00325         "StereoBench::compute3dPointJac: pix is a 2-vector (u,v)");
00326   JFR_PRECOND(J.size1() == 3 && J.size2() == 3,
00327         "StereoBench::compute3dPointJac: invalid size of J (" << J.size1() << "x" << J.size2() << ")");
00328 
00329   JFR_NUMERIC(disp > epsilon,
00330         "StereoBench::compute3dPointJac: disparity value is too small (disp=" << disp << ")");
00331 
00332   double u = pix(0);
00333   double v = pix(1);
00334 
00335   /* begin copy/paste from maple */
00336   double t2 = alpha / disp;
00337   double t3 = 0.1e1 / leftCamera.alphaU;
00338   double t5 = disp * disp;
00339   double t7 = alpha / t5;
00340   double t11 = 0.1e1 / leftCamera.alphaV;
00341   J(0,0) = -t2 * t3;
00342   J(0,1) = 0.0e0;
00343   J(0,2) = t7 * (u - leftCamera.u0) * t3;
00344   J(1,0) = 0.0e0;
00345   J(1,1) = -t2 * t11;
00346   J(1,2) = t7 * (v - leftCamera.v0) * t11;
00347   J(2,0) = 0.0e0;
00348   J(2,1) = 0.0e0;
00349   J(2,2) = -t7;
00350   /* end copy/paste from maple */
00351       }
00352 
00353       template<class Vec, class Pix>
00354       void computePixDisp(Vec const& point, Pix& pix, double& disp) const {
00355   JFR_PRECOND(point.size() == 3,
00356         "StereoBench::computePixDisp: v is a 3-vector (x,y,z)");
00357   JFR_PRECOND(pix.size() == 2,
00358         "StereoBench::computePixDisp: pixDisp is a 2-vector (u,v)");
00359   JFR_NUMERIC(point(2) > epsilon,
00360         "StereoBench::computePixDisp: z value is too small (z=" << point(2) << " > "<< epsilon << ")");
00361 
00362   disp = alpha / point(2);
00363   pix(0) = leftCamera.u0 + leftCamera.alphaU * point(0)/point(2);
00364   pix(1) = leftCamera.v0 + leftCamera.alphaV * point(1)/point(2);
00365       }
00366 
00367       template<class Vec, class Mat>
00368       void computePixDispJac(Vec const& point, Mat& J) const {
00369   JFR_PRECOND(point.size() == 3,
00370         "StereoBench::computePixDispJac: v is a 3-vector (x,y,z)");
00371   JFR_PRECOND(J.size1() == 3 && J.size2() == 3,
00372         "StereoBench::computePixDispJac: invalid size of J (" << J.size1() << "x" << J.size2() << ")");
00373 
00374   JFR_NUMERIC(point(2) > epsilon,
00375         "StereoBench::computePixDispJac: z value is too small (z=" << point(2) << ")");
00376   double x = point(0);
00377   double y = point(1);
00378   double z = point(2);
00379   /* Maple code */
00380   double t1 = 0.1e1 / z;
00381   double t4 = z * z;
00382   double t5 = 0.1e1 / t4;
00383   J(0,0) = leftCamera.alphaU * t1;
00384   J(0,1) = 0.0e0;
00385   J(0,2) = -leftCamera.alphaU * x * t5;
00386   J(1,0) = 0.0e0;
00387   J(1,1) = leftCamera.alphaV * t1;
00388   J(1,2) = -leftCamera.alphaV * y * t5;
00389   J(2,0) = 0.0e0;
00390   J(2,1) = 0.0e0;
00391   J(2,2) = -alpha * t5;
00392       }
00393 
00394     }; // class StereoBench
00395 
00396     std::ostream& operator <<(std::ostream& s, jafar::camera::StereoBench const& stereoBench_);
00397 
00398   } // namespace image
00399 } // namespace jafar
00400 
00401 #endif // IMAGE_CAMERA_PINHOLE_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:17 for Jafar by doxygen 1.7.6.1
LAAS-CNRS