ImageTransforms.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00027 #ifndef _VIGRA_EXT_IMAGETRANSFORMS_H
00028 #define _VIGRA_EXT_IMAGETRANSFORMS_H
00029 
00030 #include <fstream>
00031 
00032 #include <vigra/basicimage.hxx>
00033 #include <vigra_ext/ROIImage.h>
00034 #include <vigra_ext/Interpolators.h>
00035 
00036 #include <hugin_math/hugin_math.h>
00037 #include <hugin_utils/utils.h>
00038 #include <appbase/ProgressDisplay.h>
00039 #include <hugin_config.h>
00040 #ifdef HAVE_OPENMP
00041 #include <omp.h>
00042 #endif
00043 
00044 namespace vigra_ext
00045 {
00046 
00048 template <class T>
00049 T zeroNegative(T p)
00050 {
00051     if (p < 0) {
00052         return vigra::NumericTraits<T>::zero();
00053     } else {
00054         return p;
00055     }
00056 }
00057 
00059 template <class T>
00060 vigra::RGBValue<T> zeroNegative(vigra::RGBValue<T> p)
00061 {
00062     if (p.red() < 0) p.setRed(vigra::NumericTraits<T>::zero());
00063     if (p.green() < 0) p.setGreen(vigra::NumericTraits<T>::zero());
00064     if (p.blue() < 0) p.setBlue(vigra::NumericTraits<T>::zero());
00065     return p;
00066 }
00067 
00068 
00094 template <class SrcImageIterator, class SrcAccessor,
00095           class DestImageIterator, class DestAccessor,
00096           class TRANSFORM,
00097           class PixelTransform,
00098           class AlphaImageIterator, class AlphaAccessor,
00099           class Interpolator>
00100 void transformImageIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00101                           vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00102                           std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00103                           TRANSFORM & transform,
00104                           PixelTransform & pixelTransform,
00105                           vigra::Diff2D destUL,
00106                           Interpolator interp,
00107                           bool warparound,
00108                           AppBase::ProgressDisplay* progress,
00109                           bool singleThreaded)
00110 {
00111     const vigra::Diff2D destSize = dest.second - dest.first;
00112 
00113     const int xstart = destUL.x;
00114     const int xend = destUL.x + destSize.x;
00115     const int ystart = destUL.y;
00116     const int yend = destUL.y + destSize.y;
00117 
00118     vigra_ext::ImageInterpolator<SrcImageIterator, SrcAccessor, Interpolator>
00119         interpol(src, interp, warparound);
00120 
00121     // loop over the image and transform
00122 #pragma omp parallel for if(!singleThreaded) schedule(dynamic) 
00123     for (int y = ystart; y < yend; ++y)
00124     {
00125         // create x iterators
00126         DestImageIterator xd(dest.first);
00127         xd.y += y - ystart;
00128         AlphaImageIterator xdm(alpha.first);
00129         xdm.y += y - ystart;
00130         typename SrcAccessor::value_type tempval;
00131         for (int x = xstart; x < xend; ++x, ++xd.x, ++xdm.x)
00132         {
00133             double sx, sy;
00134             if (transform.transformImgCoord(sx, sy, x, y)) {
00135                 if (interpol.operator()(sx, sy, tempval)){
00136                     // apply pixel transform and write to output
00137                     dest.third.set(zeroNegative(pixelTransform(tempval, hugin_utils::FDiff2D(sx, sy))), xd);
00138                     alpha.second.set(pixelTransform.hdrWeight(tempval, vigra::UInt8(255)), xdm);
00139                 }
00140                 else {
00141                     alpha.second.set(0, xdm);
00142                 }
00143             }
00144             else {
00145                 alpha.second.set(0, xdm);
00146             }
00147         }
00148     }
00149 }
00150 
00152 template <class SrcImageIterator, class SrcAccessor,
00153           class SrcAlphaIterator, class SrcAlphaAccessor,
00154           class DestImageIterator, class DestAccessor,
00155           class TRANSFORM,
00156           class PixelTransform,
00157           class AlphaImageIterator, class AlphaAccessor,
00158           class Interpolator>
00159 void transformImageAlphaIntern(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00160                                std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
00161                                vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00162                                std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00163                                TRANSFORM & transform,
00164                                PixelTransform & pixelTransform,
00165                                vigra::Diff2D destUL,
00166                                Interpolator interp,
00167                                bool warparound,
00168                                AppBase::ProgressDisplay* progress,
00169                                bool singleThreaded)
00170 {
00171     const vigra::Diff2D destSize = dest.second - dest.first;
00172 
00173     const int xstart = destUL.x;
00174     const int xend   = destUL.x + destSize.x;
00175     const int ystart = destUL.y;
00176     const int yend   = destUL.y + destSize.y;
00177 
00178     vigra_ext::ImageMaskInterpolator<SrcImageIterator, SrcAccessor, SrcAlphaIterator,
00179                                      SrcAlphaAccessor, Interpolator>
00180                                     interpol (src, srcAlpha, interp, warparound);
00181 
00182     // loop over the image and transform
00183 #pragma omp parallel for if(!singleThreaded) schedule(dynamic)
00184     for(int y=ystart; y < yend; ++y)
00185     {
00186         // create x iterators
00187         DestImageIterator xd(dest.first);
00188         xd.y += y - ystart;
00189         AlphaImageIterator xdist(alpha.first);
00190         xdist.y += y - ystart;
00191         typename SrcAccessor::value_type tempval;
00192         typename SrcAlphaAccessor::value_type alphaval;
00193         for (int x = xstart; x < xend; ++x, ++xd.x, ++xdist.x)
00194         {
00195             double sx,sy;
00196             if (transform.transformImgCoord(sx,sy,x,y)) {
00197                 // try to interpolate.
00198                 if (interpol(sx, sy, tempval, alphaval)) {
00199                     dest.third.set(zeroNegative(pixelTransform(tempval, hugin_utils::FDiff2D(sx, sy))), xd);
00200                     alpha.second.set(pixelTransform.hdrWeight(tempval, alphaval), xdist);
00201                 } else {
00202                     // point outside of image or mask
00203                     alpha.second.set(0, xdist);
00204                 }
00205             } else {
00206                 alpha.second.set(0, xdist);
00207             }
00208         }
00209     }
00210 };
00211 
00236 template <class SrcImageIterator, class SrcAccessor,
00237           class DestImageIterator, class DestAccessor,
00238           class AlphaImageIterator, class AlphaAccessor,
00239           class TRANSFORM,
00240           class PixelTransform>
00241 void transformImage(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00242                     vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00243                     std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00244                     vigra::Diff2D destUL,
00245                     TRANSFORM & transform,
00246                     PixelTransform & pixelTransform,
00247                     bool warparound,
00248                     Interpolator interpol,
00249                     AppBase::ProgressDisplay* progress, bool singleThreaded = false)
00250 {
00251     switch (interpol) {
00252     case INTERP_CUBIC:
00253         DEBUG_DEBUG("using cubic interpolator");
00254     transformImageIntern(src, dest, alpha, transform, pixelTransform, destUL,
00255                                  vigra_ext::interp_cubic(), warparound,
00256                                  progress, singleThreaded);
00257         break;
00258     case INTERP_SPLINE_16:
00259         DEBUG_DEBUG("interpolator: spline16");
00260     transformImageIntern(src, dest, alpha, transform, pixelTransform, destUL,
00261                                  vigra_ext::interp_spline16(), warparound,
00262                                  progress, singleThreaded);
00263         break;
00264     case INTERP_SPLINE_36:
00265         DEBUG_DEBUG("interpolator: spline36");
00266     transformImageIntern(src, dest, alpha, transform, pixelTransform, destUL,
00267                                  vigra_ext::interp_spline36(), warparound,
00268                                  progress, singleThreaded);
00269         break;
00270     case INTERP_SPLINE_64:
00271         DEBUG_DEBUG("interpolator: spline64");
00272     transformImageIntern(src, dest, alpha, transform, pixelTransform, destUL,
00273                                  vigra_ext::interp_spline64(), warparound,
00274                                  progress, singleThreaded);
00275         break;
00276     case INTERP_SINC_256:
00277         DEBUG_DEBUG("interpolator: sinc 256");
00278     transformImageIntern(src, dest, alpha, transform, pixelTransform, destUL,
00279                                  vigra_ext::interp_sinc<8>(), warparound,
00280                                  progress, singleThreaded);
00281         break;
00282     case INTERP_BILINEAR:
00283         transformImageIntern(src, dest, alpha, transform, pixelTransform, destUL,
00284                                  vigra_ext::interp_bilin(), warparound,
00285                                  progress, singleThreaded);
00286         break;
00287     case INTERP_NEAREST_NEIGHBOUR:
00288         transformImageIntern(src, dest, alpha, transform, pixelTransform, destUL,
00289                                  vigra_ext::interp_nearest(), warparound,
00290                                  progress, singleThreaded);
00291         break;
00292     case INTERP_SINC_1024:
00293         transformImageIntern(src, dest, alpha, transform, pixelTransform, destUL,
00294                                  vigra_ext::interp_sinc<32>(), warparound,
00295                                  progress, singleThreaded);
00296         break;
00297     }
00298 }
00299 
00301 template <class SrcImageIterator, class SrcAccessor,
00302           class SrcAlphaIterator, class SrcAlphaAccessor,
00303           class DestImageIterator, class DestAccessor,
00304           class AlphaImageIterator, class AlphaAccessor,
00305           class TRANSFORM, class PixelTransform>
00306 void transformImageAlpha(vigra::triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
00307                          std::pair<SrcAlphaIterator, SrcAlphaAccessor> srcAlpha,
00308                          vigra::triple<DestImageIterator, DestImageIterator, DestAccessor> dest,
00309                          std::pair<AlphaImageIterator, AlphaAccessor> alpha,
00310                          vigra::Diff2D destUL,
00311                          TRANSFORM & transform,
00312                          PixelTransform & pixelTransform,
00313                          bool warparound,
00314                          Interpolator interpol,
00315                          AppBase::ProgressDisplay* progress, bool singleThreaded = false)
00316 {
00317     switch (interpol) {
00318     case INTERP_CUBIC:
00319         DEBUG_DEBUG("using cubic interpolator");
00320         transformImageAlphaIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00321                                               vigra_ext::interp_cubic(), warparound,
00322                               progress, singleThreaded);
00323         break;
00324     case INTERP_SPLINE_16:
00325         DEBUG_DEBUG("interpolator: spline16");
00326     transformImageAlphaIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00327                               vigra_ext::interp_spline16(), warparound,
00328                               progress, singleThreaded);
00329         break;
00330     case INTERP_SPLINE_36:
00331         DEBUG_DEBUG("interpolator: spline36");
00332     transformImageAlphaIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00333                               vigra_ext::interp_spline36(),  warparound,
00334                               progress, singleThreaded);
00335         break;
00336     case INTERP_SPLINE_64:
00337         DEBUG_DEBUG("interpolator: spline64");
00338     transformImageAlphaIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00339                               vigra_ext::interp_spline64(),  warparound,
00340                               progress, singleThreaded);
00341         break;
00342     case INTERP_SINC_256:
00343         DEBUG_DEBUG("interpolator: sinc 256");
00344     transformImageAlphaIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00345                               vigra_ext::interp_sinc<8>(), warparound,
00346                               progress, singleThreaded);
00347         break;
00348     case INTERP_BILINEAR:
00349         transformImageAlphaIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00350                               vigra_ext::interp_bilin(), warparound,
00351                               progress, singleThreaded);
00352         break;
00353     case INTERP_NEAREST_NEIGHBOUR:
00354         transformImageAlphaIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00355                               vigra_ext::interp_nearest(), warparound,
00356                               progress, singleThreaded);
00357         break;
00358     case INTERP_SINC_1024:
00359         transformImageAlphaIntern(src,srcAlpha, dest, alpha, transform, pixelTransform, destUL,
00360                               vigra_ext::interp_sinc<32>(), warparound,
00361                               progress, singleThreaded);
00362         break;
00363     }
00364 }
00365 
00366 }; // namespace
00367 
00368 #endif // _VIGRA_EXT_IMAGETRANSFORMS_H

Generated on 4 Sep 2015 for Hugintrunk by  doxygen 1.4.7