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

Generated on 24 Jun 2016 for Hugintrunk by  doxygen 1.4.7