Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
univReprojection.hpp
00001 
00002 #ifndef CAMERA_UNIVREPROJECTION_HPP
00003 #define CAMERA_UNIVREPROJECTION_HPP
00004 
00005 #include <cmath>
00006 #include <iostream>
00007 
00008 #include "kernel/jafarException.hpp"
00009 #include "kernel/jafarDebug.hpp"
00010 
00011 #include "image/Image.hpp"
00012 
00013 #include "camera/cameraPinhole.hpp"
00014 #include "camera/cameraBarreto.hpp"
00015 
00016 #include "geom/t3dEuler.hpp"
00017 
00018 namespace jafar {
00019   namespace camera {
00020 
00032     template<typename _channeltype> 
00033     void univReprojectionCylindric(CameraBarreto const& cameraBarreto,
00034           const jafar::image::Image& src_, jafar::image::Image& dst_, int interpolation_)
00035     {
00036       JFR_PRECOND(src_.width() == cameraBarreto.camera.width && src_.height() == cameraBarreto.camera.height,
00037       "reprojectionCylindric: source image size is invalid");
00038       JFR_PRECOND(src_.channels() == dst_.channels(),
00039       "reprojectionCylindric: images must have the same number of channel");       
00040       
00041       double phi, phiInt, phiExt, phiMin, phiMax, theta, thetaMin, thetaMax, phiStep, thetaStep;     
00042       double r=0.0;
00043 
00044       int nbPixel = 0,i,j;
00045       int dstNbCol = dst_.width(), dstNbRow = dst_.height();
00046       int ichannel, nbchannel = dst_.channels();
00047       
00048       
00049       jblas::vec3 direction, point3D;
00050       jblas::vec2 pixel, tmp;    
00051 
00052       _channeltype imaData; 
00053 
00054       /* Output image initialization */
00055       /* --------------------------- */
00056       //      cvSetZero(dst_);
00057       (cv::Mat)dst_ = cv::Mat::zeros(dst_.size(), dst_.type());
00058       
00059       /* Elevation angle bounds */
00060       /* ---------------------- */
00061       /* In first : elevation for inner circle */
00062       pixel(1) = cameraBarreto.mirrorCenterV;
00063       pixel(0) = cameraBarreto.mirrorCenterU+cameraBarreto.maskRadius;
00064       cameraBarreto.imageToCameraFrameDirection<jblas::vec2,jblas::vec3>(pixel, direction);
00065       tmp(0) = direction(0); tmp(1) = direction(1);
00066       r = ublas::norm_2(tmp);
00067       
00068       if (r<=1e-4)
00069   phiInt = (direction(2)>0.0)?0.5*M_PI:-0.5*M_PI;
00070       else
00071   phiInt = atan(direction(2)/r);
00072 
00073       /* In second : elevation for outer circle */
00074       pixel(1) = cameraBarreto.mirrorCenterV;
00075       pixel(0) = cameraBarreto.imageRadius + cameraBarreto.mirrorCenterU;
00076       cameraBarreto.imageToCameraFrameDirection<jblas::vec2,jblas::vec3>(pixel, direction);
00077       tmp(0) = direction(0); tmp(1) = direction(1);
00078       r = ublas::norm_2(tmp);
00079       
00080       phiExt = atan(direction(2)/r);     
00081 
00082       /* Angle discretization */
00083       /* -------------------- */
00084       thetaMax = M_PI/2.0;thetaMin = -3.0*M_PI/2.0;
00085       phiMin = (phiExt>phiInt)?phiInt:phiExt;
00086       phiMax = (phiExt>phiInt)?phiExt:phiInt;
00087       
00088       thetaStep = (thetaMax-thetaMin)/dstNbCol;
00089       phiStep   = (phiMax-phiMin)/dstNbRow;
00090       
00091       /* Loop on dst_ pixel */
00092       /* ------------------ */
00093       for (j=0, phi = phiMax ; j<dstNbRow ; j++, phi -= phiStep)  
00094   for (i=0, theta = thetaMin; i<dstNbCol ; i++, theta -= thetaStep, nbPixel++)
00095     {
00096       point3D(0) = cos(phi)*cos(theta);
00097       point3D(1) = cos(phi)*sin(theta);
00098       point3D(2) = sin(phi);
00099       
00100       if ( cameraBarreto.project<jblas::vec3,jblas::vec2>(point3D,pixel) )
00101         for (ichannel = 0; ichannel < nbchannel; ichannel++) 
00102     {
00103       /* Grey level in source image */
00104       if (interpolation_)
00105         imaData = (_channeltype)src_.getSubPixelValue<_channeltype>(pixel(0),pixel(1),ichannel);        
00106       else
00107         imaData = src_.getPixelValue<_channeltype>((int)pixel(0),(int)pixel(1),ichannel);       
00108       
00109       /* Put this value in destination iage */
00110       dst_.setPixelValue<_channeltype>(imaData,i,j,ichannel); 
00111     }  
00112       
00113     } // end of the loop on dst_ image     
00114       
00115     }; // reprojectionCylindric function
00116 
00117 
00125     bool pixelCyl2pixelPano (CameraBarreto const& cameraBarreto, 
00126            const jafar::image::Image& cylIma, 
00127            const jblas::vec2& pixelCyl,
00128            jblas::vec2& pixelPano)      
00129     {      
00130       JFR_PRECOND(pixelCyl(0)>=0 && pixelCyl(1)<cylIma.width() && pixelCyl(1)>=0 && pixelCyl(1)<cylIma.height(),      
00131       "pixelCyl2pixelPano : specified pixel is out of cylindrical image");
00132 
00133       double phi, phiInt, phiExt, phiMin, phiMax, theta, thetaMin, thetaMax, phiStep, thetaStep;     
00134       double r=0.0;
00135       int dstNbCol = cylIma.width(), dstNbRow = cylIma.height();
00136       
00137       jblas::vec2 pixel;
00138       jblas::vec3 direction, point3D;    
00139       
00140       /* Elevation angle bounds */
00141       /* ---------------------- */
00142       /* In first : elevation for inner circle */
00143       pixel(1) = cameraBarreto.mirrorCenterV;
00144       pixel(0) = cameraBarreto.mirrorCenterU+cameraBarreto.maskRadius;
00145       cameraBarreto.imageToCameraFrameDirection<jblas::vec2,jblas::vec3>(pixel, direction);
00146       pixel(0) = direction(0); pixel(1) = direction(1);
00147       r = ublas::norm_2(pixel);
00148       
00149       if (r<=1e-4)
00150   phiInt = (direction(2)>0.0)?0.5*M_PI:-0.5*M_PI;
00151       else
00152   phiInt = atan(direction(2)/r);
00153 
00154       /* In second : elevation for outer circle */
00155       pixel(1) = cameraBarreto.mirrorCenterV;
00156       pixel(0) = cameraBarreto.imageRadius + cameraBarreto.mirrorCenterU;
00157       cameraBarreto.imageToCameraFrameDirection<jblas::vec2,jblas::vec3>(pixel, direction);
00158       pixel(0) = direction(0); pixel(1) = direction(1);
00159       r = ublas::norm_2(pixel);
00160       
00161       phiExt = atan(direction(2)/r);     
00162 
00163       /* Angle discretization */
00164       /* -------------------- */
00165       thetaMax = M_PI/2.0;thetaMin = -3.0*M_PI/2.0;
00166       phiMin = (phiExt>phiInt)?phiInt:phiExt;
00167       phiMax = (phiExt>phiInt)?phiExt:phiInt;
00168       
00169       thetaStep = (thetaMax-thetaMin)/dstNbCol;
00170       phiStep   = (phiMax-phiMin)/dstNbRow;
00171       
00172 
00173       /* Pixel reprojection */
00174       /* ------------------ */
00175       theta  = thetaMin - pixelCyl(0)*thetaStep;
00176       phi = phiMax - pixelCyl(1)*phiStep;
00177       
00178       point3D(0) = cos(phi)*cos(theta);
00179       point3D(1) = cos(phi)*sin(theta);
00180       point3D(2) = sin(phi);
00181       
00182       return cameraBarreto.project<jblas::vec3,jblas::vec2>(point3D,pixelPano); 
00183       
00184     }; // pixelCyl2pixelPano
00185 
00201     template<typename _channeltype>
00202     void univReprojectionPerspective(CameraParabolicBarreto const& cameraBarreto,
00203               const jafar::image::Image& src_, 
00204               jafar::image::Image& dst_, 
00205              double elev_, double azim_, double roll_, double vOpen_, int interpolation_)
00206     {
00207       JFR_PRECOND(src_.width() == cameraBarreto.camera.width && src_.height() == cameraBarreto.camera.height,
00208       "reprojectionPerspective: confllict between source image size and calibration parameters.");
00209       JFR_PRECOND(src_.channels() == dst_.channels(),
00210       "reprojectionPerspective: images must have the same number of channel.");       
00211 
00212       double u0out, v0out, fu, fv, hOpen;
00213       int i=3, j, ichannel, nbchannel = dst_.channels();
00214       int dstNbCol = dst_.width(), dstNbRow = dst_.height();
00215 
00216       jblas::vec4 pth, ptest;
00217       jblas::vec3 direction, point3D, pt;
00218       jblas::vec2 pixel, pixelp, tmp;        
00219       jblas::mat44 matM;
00220       jblas::mat33 matR, tmatR, matR1, matR2;
00221 
00222       _channeltype imaData;
00223 
00224       jafar::geom::T3DEuler maT3DEuler;
00225       jafar::camera::CameraPinhole vCam;       
00226             
00227       /* Virtual camera initialization */
00228       /* ----------------------------- */
00229       hOpen = dstNbCol*vOpen_/dstNbRow;
00230       u0out = (double)(dstNbCol-1)/2.0;
00231       v0out = (double)(dstNbRow-1)/2.0;     
00232       fv = dstNbRow/(2.0*tan(vOpen_/2.0));  
00233       fu = dstNbCol/(2.0*tan(hOpen/2.0));    
00234       vCam.setParameters(dstNbCol, dstNbRow, u0out, v0out, fu, fv);
00235 
00236       /* Initialization T3D */
00237       /* ------------------ */      
00238 
00239       /* !  \internal Here we generate the rotation matrix describing
00240    how to pass from the mirror framework to the virtual
00241    perspective camera framework. We proceed in two steps.
00242 
00243    In the first step, we align mirror framework with this of the
00244    virtual perspective camera. Orientation of this camera is
00245    defined by two angles : elev_ and azim_. Be R1 this matrix
00246 
00247    In the second step,we applied a rotation around the optical axis
00248    (oZ). Be R2 the corresponding rotation matrix
00249 
00250    Our transform is formally R = R2*R1 and X|mirror =
00251    transpose(R)*X|cam. This transposition is unneccessary
00252    because of T3D class specifications.
00253 
00254        */
00255       
00256       maT3DEuler.setValue(0,0,0,roll_,0,0);
00257       matM = maT3DEuler.getM();
00258       for (i=0;i<3;i++)
00259   for (j=0;j<3;j++)
00260     matR2(i,j) = matM(i,j);         
00261         
00262       maT3DEuler.setValue(0,0,0,M_PI+azim_,0,-elev_ - M_PI/2.0);
00263       matM = maT3DEuler.getM();     
00264       for (i=0;i<3;i++)
00265   for (j=0;j<3;j++)
00266     matR1(i,j) = matM(i,j);
00267 
00268       matR = ublas::prod(matR1,matR2);
00269     
00270       /* Output image initialization */
00271       /* --------------------------- */
00272       //      cvSetZero(dst_);
00273       (cv::Mat)dst_ = cv::Mat::zeros(dst_.size(), dst_.type());
00274       /* Loop on dst_pixel */
00275       /* ----------------- */
00276       for (j=0;j<dstNbRow;j++)  
00277   {
00278     pixelp(1) = j;
00279     for (i=0;i<dstNbCol;i++)
00280       {       
00281         pixelp(0) = i;      
00282         vCam.imageToCameraFrame<jblas::vec2,jblas::vec3>(pixelp,pt);
00283         
00284         point3D = ublas::prod(matR,pt);
00285 
00286         if (cameraBarreto.project<jblas::vec3,jblas::vec2>(point3D,pixel) ) 
00287     for (ichannel = 0; ichannel < nbchannel; ichannel++) 
00288       {
00289         
00290         /* Grey level in source image */
00291         if (interpolation_)
00292           imaData = (_channeltype)src_.getSubPixelValue<_channeltype>(pixel(0),pixel(1),ichannel);        
00293         else
00294           imaData = src_.getPixelValue<_channeltype>((int)pixel(0),(int)pixel(1),ichannel);       
00295         
00296         /* Put this value in destination iage */
00297         dst_.setPixelValue<_channeltype>(imaData,i,j,ichannel); 
00298 
00299       }  // End of Channel loop
00300 
00301         
00302       } // End of Column loop
00303 
00304   } // End of Row loop
00305 
00306       
00307     }; // univReprojectionPerspective() function       
00308     
00309   } // namespace camera
00310 
00311 } // namespace jafar
00312 
00313 #endif // CAMERA_GENREPROJ_HPP
00314 
 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