Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
reprojection.hpp
00001 /* $Id$ */
00002 
00003 #ifndef CAMERA_REPROJECTION_HPP
00004 #define CAMERA_REPROJECTION_HPP
00005 
00006 #include <cmath>
00007 #include <iostream>
00008 
00009 #include "kernel/jafarException.hpp"
00010 #include "kernel/jafarDebug.hpp"
00011 
00012 #include "image/Image.hpp"
00013 
00014 #include "camera/cameraBarreto.hpp"
00015 
00016 namespace jafar {
00017   namespace camera {
00018 
00024     template<typename _channeltype> 
00025     void reprojectionCylindric(CameraParabolicBarreto const& cameraBarreto,
00026              const jafar::image::Image& src_, jafar::image::Image& dst_, int interpolation_)
00027     {
00028       JFR_PRECOND(src_.width() == cameraBarreto.camera.width && src_.height() == cameraBarreto.camera.height,
00029       "reprojectionCylindric: source image size is invalid");
00030       JFR_PRECOND(src_.channels()==1 && dst_.channels()==1,
00031       "reprojectionCylindric: images must be mono channel");  
00032 
00033       // h in pixel
00034       double h = 2*cameraBarreto.p * cameraBarreto.imageRadius / (cameraBarreto.mirrorDiameter/2);
00035       
00036 
00037       double radiusmin = cameraBarreto.maskRadius;
00038       double radiusmax = cameraBarreto.imageRadius;
00039 
00040       int dstNbCol = dst_.width(), dstNbRow = dst_.height();
00041       int nbPixel = 0, i, j; 
00042       
00043       double theta = 0.0, thetaMin = 0.0, thetaMax = 2*M_PI, thetaStep;
00044       double phi = 0.0, phiMin, phiMax, phiStep;
00045       double x, y, radius = 0.0;
00046       
00047       _channeltype imaData; 
00048 
00049       /* Bounds on the angles */
00050       phiMin = atan2 (radiusmin*radiusmin-h*h,2*radiusmin*h);
00051       phiMax = atan2 (radiusmax*radiusmax-h*h,2*radiusmax*h);
00052 
00053       /* Angular discretisation*/
00054       thetaStep = (thetaMax-thetaMin)/dstNbCol;
00055       phiStep   = (phiMax-phiMin)/dstNbRow;
00056       
00057       /* Loop on dst_ pixel */
00058       for (j=0, phi = phiMax ; j<dstNbRow ; j++, phi -= phiStep)
00059   {      
00060     radius = h*(1+sin(phi))/cos(phi);
00061       
00062     for (i=0, theta = thetaMin; i<dstNbCol ; i++, theta += thetaStep, nbPixel++)
00063       {
00064         x = radius*cos(theta) + cameraBarreto.camera.u0;
00065         y = radius*sin(theta) + cameraBarreto.camera.v0;
00066             
00067         /* Grey level in source image */
00068         if (interpolation_)
00069           imaData = (_channeltype)src_.getSubPixelValue<_channeltype>(x,y);       
00070         else
00071           imaData = src_.getPixelValue<_channeltype>((int)x,(int)y);        
00072         
00073         /* Put this value in destination iage */
00074         dst_.setPixelValue<_channeltype>(imaData,i,j); 
00075         
00076       } // end of the loop over theta
00077   }  // end loop over phi
00078       
00079     }; // reprojectionCylindric function
00080 
00081 
00082 
00090     template<typename _channeltype> 
00091     void reprojectionPlane(CameraParabolicBarreto const& cameraBarreto,
00092          const jafar::image::Image& src_, 
00093          jafar::image::Image& dst_, 
00094          double planedist_, double areawidth_, int interpolation_)
00095     {
00096       JFR_PRECOND(src_.width() == cameraBarreto.camera.width && src_.height() == cameraBarreto.camera.height,
00097       "reprojectionPlane: source image size is invalid");
00098       JFR_PRECOND(src_.channels()==1 && dst_.channels()==1,
00099       "reprojectionCylindric: images must be mono channel");  
00100 
00101       // h in pixel
00102       double h = 2*cameraBarreto.p * cameraBarreto.imageRadius / (cameraBarreto.mirrorDiameter/2);
00103 
00104       int dstNbCol = dst_.width(), dstNbRow = dst_.height();  
00105       int i, j;
00106       
00107       double x, xMin, xMax, xStep;
00108       double y, yMin, yMax, yStep;
00109       double xMirror, xImage, yImage, yMirror;
00110       double phi, theta;
00111       double radiusOnPlane, radiusOnMirror;
00112           
00113       _channeltype imaData;
00114       
00115       // Bounds of the plane
00116       xMin = yMin = -areawidth_;
00117       xMax = yMax = areawidth_;
00118       
00119       // Plane discretisation
00120       xStep = 2*areawidth_/dstNbCol;
00121       yStep = 2*areawidth_/dstNbRow;
00122       
00123       // Loop on dst_ pixel 
00124       for (j=0, y = yMin; y<yMax; y+=yStep, j++)    
00125   for (i=0, x = xMin; x<xMax; x+=xStep, i++)
00126     { 
00127       radiusOnPlane = sqrt(x*x+y*y);
00128       
00129       // Angular coordinates
00130       phi = -atan2(planedist_,radiusOnPlane);
00131       theta = atan2(y,x);
00132       
00133       // Coordinates on mirror 
00134       radiusOnMirror = h*(1+sin(phi))/cos(phi); 
00135       xMirror = radiusOnMirror*cos(theta);
00136       yMirror = radiusOnMirror*sin(theta);
00137       
00138       // Coordinates on image plane
00139       xImage = cameraBarreto.camera.u0 + xMirror;
00140       yImage = cameraBarreto.camera.v0 + yMirror;
00141       
00142       // Interpolation and copy
00143       if (interpolation_)       
00144         imaData = (_channeltype)src_.getSubPixelValue<_channeltype>(xImage,yImage);
00145       else
00146         imaData = src_.getPixelValue<_channeltype>((int)xImage,(int)yImage);
00147       
00148       dst_.setPixelValue<_channeltype>(imaData,i,j);  
00149       
00150     } // end of the pixel loop
00151       
00152     }; // reprojectionPlane() funtion
00153 
00163     template<typename _channeltype>
00164     void reprojectionPerspective(CameraParabolicBarreto const& cameraBarreto,
00165          const jafar::image::Image& src_, 
00166          jafar::image::Image& dst_, 
00167          double elev_, double azim_, double vOpen_, int interpolation_)
00168     {
00169       JFR_PRECOND(src_.width() == cameraBarreto.camera.width && src_.height() == cameraBarreto.camera.height,
00170       "reprojectionPerspective: source image size is invalid");
00171       JFR_PRECOND(src_.channels()==1 && dst_.channels()==1,
00172       "reprojectionCylindric: images must be mono channel");  
00173 
00174       // h in pixel
00175       double h = 2*cameraBarreto.p * cameraBarreto.imageRadius / (cameraBarreto.mirrorDiameter/2);
00176       
00177       int dstNbCol = dst_.width(), dstNbRow = dst_.height();
00178       int i,j;
00179 
00180       double focal, u0, v0;
00181       double ur,vr;
00182       double phi, dPhi, theta, dTheta;
00183       double xImage, yImage, radius;
00184       
00185       _channeltype imaData;
00186       
00187       // Intrinsic parameters
00188       u0 = (double)(dstNbCol-1)/2;
00189       v0 = (double)(dstNbRow-1)/2;     
00190       focal = dstNbRow/(2*tan(vOpen_/2));  
00191 
00192       // Loop on dst_pixel
00193       for (j=0;j<dstNbRow;j++)
00194   {
00195     vr = -(double)j+v0;
00196     dPhi = atan2(vr,focal);
00197     phi = elev_+dPhi;
00198     radius = h*(1+sin(phi))/cos(phi); 
00199 
00200     for (i=0;i<dstNbCol;i++)
00201       {
00202         ur = (double)i-u0;
00203         dTheta = atan2(ur,focal);
00204         theta = dTheta + azim_;
00205 
00206         // Coordinates on image plane
00207         xImage = cameraBarreto.camera.u0 + radius*cos(theta);
00208         yImage = cameraBarreto.camera.v0 + radius*sin(theta);
00209                       
00210         // Interpolation and copy
00211         if (interpolation_)       
00212           imaData = (_channeltype)src_.getSubPixelValue<_channeltype>(xImage,yImage);
00213         else
00214           imaData = src_.getPixelValue<_channeltype>((int)xImage,(int)yImage);
00215         
00216         dst_.setPixelValue<_channeltype>(imaData,i,j);  
00217                     
00218       }   // end loop on rows
00219   }   // end loop on lines  
00220     }; // reprojectionPerspective() function
00221 
00222   } // namespace camera
00223 } // namespace jafar
00224 
00225 #endif // CAMERA_REPROJECTION_HPP
00226 
 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