SpaceTransform.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00013 /*
00014 *  This program is free software; you can redistribute it and/or
00015 *  modify it under the terms of the GNU General Public
00016 *  License as published by the Free Software Foundation; either
00017 *  version 2 of the License, or (at your option) any later version.
00018 *
00019 *  This software is distributed in the hope that it will be useful,
00020 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00022 *  General Public License for more details.
00023 *
00024 *  You should have received a copy of the GNU General Public
00025 *  License along with this software; if not, write to the Free Software
00026 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027 *
00028 */
00029     
00030 #ifndef _NONA_SPACETRANSFORM_H
00031 #define _NONA_SPACETRANSFORM_H
00032     
00033 #include <vigra/diff2d.hxx>
00034 #include <hugin_math/Matrix3.h>
00035 
00036 #include <panodata/PanoramaData.h>
00037 
00038 
00039 namespace HuginBase {
00040 namespace Nona {
00041         
00042     
00046 struct _FuncParams
00047 {
00048     union {
00049         double var0;
00050         double distance;
00051         double shift;
00052     };
00053     double      var1;
00054     double      var2;
00055     double      var3;
00056     double      var4;
00057     double      var5;
00058     double  var6;
00059     double  var7;
00060     Matrix3     mt;
00061 };
00062 
00063 
00067 typedef void (*trfn)( double x_dest, double y_dest, double* x_src, double* y_src, const _FuncParams &params );
00068 
00069 
00073 typedef struct _fDesc
00074 {
00075     trfn                func;   // function to be called
00076     _FuncParams param;  // parameters to be used
00077 } fDescription;
00078 
00079 
00080 
00084 class IMPEX SpaceTransform
00085 {
00086             
00087     public:
00090         SpaceTransform();
00091 
00094         ~SpaceTransform();
00095 
00099         void Init(  const SrcPanoImage & img,
00100                     const vigra::Diff2D & destSize,
00101                     PanoramaOptions::ProjectionFormat destProj,
00102                     double destHFOV );
00103 
00107         void InitInv(   const SrcPanoImage & img,
00108                         const vigra::Diff2D & destSize,
00109                         PanoramaOptions::ProjectionFormat destProj,
00110                         double destHFOV );
00111 
00112         
00113         // Different ways to create the transform
00114         
00115     public:
00118         void InitRadialCorrect(const vigra::Size2D & sz, const std::vector<double> & radDist, 
00119                                const hugin_utils::FDiff2D & centerShift);
00120 
00124         void InitRadialCorrect(const SrcPanoImage & src, int channel=1);
00125 
00126         void InitInvRadialCorrect(const SrcPanoImage & src, int channel=1);
00127 
00128         void createTransform(const SrcPanoImage & src, const PanoramaOptions & dest);
00129         
00130         void createInvTransform(const SrcPanoImage & src, const PanoramaOptions & dest);
00131 
00132         // create pano -> img transform
00133         void createTransform(const PanoramaData & pano, unsigned int imgNr,
00134                              const PanoramaOptions & dest,
00135                              vigra::Diff2D srcSize=vigra::Diff2D(0,0));
00136 
00137         // create image->pano transformation
00138         void createInvTransform(const PanoramaData & pano, unsigned int imgNr,
00139                                 const PanoramaOptions & dest,
00140                                 vigra::Diff2D srcSize=vigra::Diff2D(0,0));
00141         
00142         void createTransform(const vigra::Diff2D & srcSize,
00143                          const VariableMap & srcVars,
00144                          Lens::LensProjectionFormat srcProj,
00145                          const vigra::Diff2D &destSize,
00146                          PanoramaOptions::ProjectionFormat destProj,
00147                              double destHFOV);
00148         
00149         // create image->pano transformation
00150         void createInvTransform(const vigra::Diff2D & srcSize,
00151                                 const VariableMap & srcVars,
00152                                 Lens::LensProjectionFormat srcProj,
00153                                 const vigra::Diff2D & destSize,
00154                                 PanoramaOptions::ProjectionFormat destProj,
00155                                 double destHFOV);
00156         
00157         
00158     public:
00162         bool transform(hugin_utils::FDiff2D& dest, const hugin_utils::FDiff2D & src) const;
00163 
00167         bool transformImgCoord(double & x_dest, double & y_dest, double x_src, double y_src) const;
00168 
00169         bool transformImgCoord(hugin_utils::FDiff2D & dest, const hugin_utils::FDiff2D &src) const
00170         {
00171             return transformImgCoord(dest.x, dest.y, src.x, src.y);
00172         }
00173         
00174         
00175     public:
00177         bool isIdentity()
00178         {
00179             return m_Stack.size() == 0;
00180         }
00181 
00182         
00183     private:
00185         void AddTransform( trfn function_name, double var0, double var1 = 0.0f, double var2 = 0.0f, double var3 = 0.0f, double var4=0.0f, double var5=0.0f, double var6=0.0f, double var7=0.0f );
00186         void AddTransform( trfn function_name, Matrix3 m, double var0, double var1=0.0f, double var2=0.0f, double var3=0.0f);
00187         
00188         
00189     private:
00191         bool m_Initialized;
00192 
00194         double m_srcTX, m_srcTY;
00195         double m_destTX, m_destTY;
00196 
00198         std::vector<fDescription>       m_Stack;
00199 
00200 };
00201 
00202 
00203 
00204 
00212 template <class VECTOR>
00213 void combinePolynom4(const VECTOR & p,
00214                      const VECTOR & q,
00215                      VECTOR & c);
00216 
00217 
00221 template <class TRANSFORM>
00222 void traceImageOutline(vigra::Size2D sz,
00223                        TRANSFORM & transf,
00224                        vigra::Rect2D & inside,
00225                        vigra::Rect2D & boundingBox);
00226 
00227 
00230 IMPEX double estScaleFactorForFullFrame(const SrcPanoImage & src);
00231 
00232 
00248 double estRadialScaleCrop(const std::vector<double> & coeff, int width, int height);
00249 
00250 
00251 
00252 
00253 
00254 //==============================================================================
00255 // template implementations
00256 
00257 template <class VECTOR>
00258 void combinePolynom4(const VECTOR & p, const VECTOR & q, VECTOR & c)
00259 {
00260     double d3 = p[3]*p[3]*p[3];
00261     c[0] = (3*q[1]*p[3]*p[3]*p[2]+q[3]*p[0]+q[2]*(2*p[3]*p[1]+p[2]*p[2])+q[0]*d3*p[3]);
00262     c[1] = (2*q[2]*p[3]*p[2]+q[1]*d3+q[3]*p[1]);
00263     c[2] = (q[3]*p[2]+q[2]*p[3]*p[3]);
00264     c[3] = q[3]*p[3];
00265 
00266     /*
00267     old code for polynoms of up to x^3
00268     c[0] = q[0]*(p[2]*(2*p[3]*p[1]+p[2]*p[2])+p[3]*(2*p[3]*p[0]+2*p[2]*p[1])+p[0]*p[3]*p[3]+2*p[1]*p[3]*p[2])
00269            +q[1]*(2*p[3]*p[0]+2*p[2]*p[1])+q[2]*p[0];
00270 
00271     c[1] = q[0]*(p[3]*(2*p[3]*p[1]+p[2]*p[2])+2*p[2]*p[2]*p[3]+p[1]*p[3]*p[3])
00272             +q[2]*p[1]+q[1]*(2*p[3]*p[1]+p[2]*p[2]);
00273 
00274     c[2] = 3*q[0]*p[3]*p[3]*p[2]+2*q[1]*p[3]*p[2]+q[2]*p[2];
00275     c[3] = q[0]*p[3]*p[3]*p[3]+q[1]*p[3]*p[3]+q[2]*p[3]+q[3];
00276     */
00277 }
00278 
00279 
00280 template <class TRANSFORM>
00281 void traceImageOutline(vigra::Size2D sz, TRANSFORM & transf, vigra::Rect2D & inside, vigra::Rect2D & boundingBox)
00282 {
00283     boundingBox = vigra::Rect2D();
00284     inside = vigra::Rect2D();
00285     int x=0;
00286     int y=0;
00287     double xd;
00288     double yd;
00289     transf.transformImgCoord(xd,yd, x,y);
00290     // calculate scaling factor that would be required to avoid black borders
00291 //    double scale = std::max((-sz.x/2)/(xd-sz.x/2), (-sz.y/2)/(yd-sz.y/2));
00292     int left = 0;
00293     int right = sz.x;
00294     int top = 0;
00295     int bottom = sz.y;
00296     // left
00297     for (y=0; y < sz.y; y++) {
00298         transf.transformImgCoord(xd,yd, x,y);
00299         boundingBox |= vigra::Point2D(hugin_utils::roundi(xd), hugin_utils::roundi(yd));
00300         left = std::max(hugin_utils::roundi(xd), left);
00301     }
00302     // right
00303     x = sz.x-1;
00304     for (y=0; y < sz.y; y++) {
00305         transf.transformImgCoord(xd,yd, x,y);
00306         boundingBox |= vigra::Point2D(hugin_utils::roundi(xd), hugin_utils::roundi(yd));
00307         right = std::min(hugin_utils::roundi(xd), right);
00308     }
00309     // bottom
00310     y=sz.y-1;
00311     for (x=0; x < sz.x; x++) {
00312         transf.transformImgCoord(xd,yd, x,y);
00313         boundingBox |= vigra::Point2D(hugin_utils::roundi(xd), hugin_utils::roundi(yd));
00314         bottom = std::min(hugin_utils::roundi(yd), bottom);
00315     }
00316     // top
00317     y=0;
00318     for (x=0; x < sz.x; x++) {
00319         transf.transformImgCoord(xd,yd, x,y);
00320         boundingBox |= vigra::Point2D(hugin_utils::roundi(xd), hugin_utils::roundi(yd));
00321         top = std::max(hugin_utils::roundi(yd), top);
00322     }
00323     inside.setUpperLeft(vigra::Point2D(left, top));
00324     inside.setLowerRight(vigra::Point2D(right, bottom));
00325 }
00326 
00327 
00328 
00329 } // namespace
00330 } // namespace
00331 
00332 #endif

Generated on 30 Oct 2014 for Hugintrunk by  doxygen 1.4.7