[an error occurred while processing this directive]
Main Page | Modules | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

hugin_base/vigra_ext/Pyramid.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00024 #ifndef VIGRA_EXT_PYRAMID_H
00025 #define VIGRA_EXT_PYRAMID_H
00026 
00027 #include <vigra/separableconvolution.hxx>
00028 
00029 #include <hugin_utils/utils.h>
00030 
00031 
00032 // TODO: use fast version from enblend 3.0
00033 #include <vigra_ext/pyramid2.h>
00034 
00035 
00036 namespace vigra_ext {
00037 
00038 template <class ImageIn, class Image>
00039 void reduceNTimes(ImageIn & in, Image & out, int n)
00040 {
00041     typedef typename Image::value_type vt;
00042     typedef typename vigra::NumericTraits<vt>::RealPromote SKIPSMType;
00043     if (n <= 0) {
00044         out = in;
00045         return;
00046     }
00047 
00048     size_t w = in.width();
00049     size_t h = in.height();
00050     // Size of next level
00051     w = (w + 1) >> 1;
00052     h = (h + 1) >> 1;
00053 
00054     Image temp;
00055     Image * curr = &temp;
00056     Image * next = &out;
00057     if( (n % 2) == 1)
00058     {
00059         // even number of reduce operations, first reduce into output image
00060         curr = &out;
00061         next = &temp;
00062     }
00063     curr->resize(w,h);
00064     enblend::reduce<SKIPSMType>(false, srcImageRange(in), destImageRange(*curr));
00065     n--;
00066     w = (w + 1) >> 1;
00067     h = (h + 1) >> 1;
00068     for( ; n > 0 ; --n) {
00069         next->resize(w,h);
00070         enblend::reduce<SKIPSMType>(false, srcImageRange(*curr), destImageRange(*next));
00071         w = (w + 1) >> 1;
00072         h = (h + 1) >> 1;
00073         Image * t = curr;
00074         curr = next;
00075         next = t;
00076     }
00077 }
00078 
00079 template <class Image, class ImageMask>
00080 void reduceNTimes(Image & in, ImageMask & inMask, Image & out, ImageMask & outMask, int n)
00081 {
00082     typedef typename Image::value_type vt;
00083     typedef typename vigra::NumericTraits<vt>::RealPromote SKIPSMType;
00084     typedef typename ImageMask::value_type mt;
00085 //    typedef typename vigra::NumericTraits<mt>::Promote SKIPSMAlphaType;
00086     typedef double SKIPSMAlphaType;
00087 
00088     if (n <= 0) {
00089         out = in;
00090         outMask = inMask;
00091         return;
00092     }
00093 
00094     size_t w = in.width();
00095     size_t h = in.height();
00096     // Size of next level
00097     w = (w + 1) >> 1;
00098     h = (h + 1) >> 1;
00099 
00100     Image temp;
00101     ImageMask tempMask;
00102     Image * curr = &temp;
00103     ImageMask * currMask = &tempMask;
00104     Image * next = &out;
00105     ImageMask * nextMask = &outMask;
00106     if( (n % 2) == 1)
00107     {
00108         // even number of reduce operations, first reduce into output image
00109         curr = &out;
00110         currMask = &outMask;
00111         next = &temp;
00112         nextMask = &tempMask;
00113     }
00114     curr->resize(w,h);
00115     currMask->resize(w,h);
00116     enblend::reduce<SKIPSMType, SKIPSMAlphaType>(false, srcImageRange(in), srcImage(inMask), 
00117                                 destImageRange(*curr), destImageRange(*currMask));
00118     n--;
00119     w = (w + 1) >> 1;
00120     h = (h + 1) >> 1;
00121     for( ; n > 0 ; --n) {
00122         next->resize(w,h);
00123         nextMask->resize(w,h);
00124         enblend::reduce<SKIPSMType, SKIPSMAlphaType>(false, srcImageRange(*curr), srcImage(*currMask),
00125                                     destImageRange(*next), destImageRange(*nextMask));
00126         w = (w + 1) >> 1;
00127         h = (h + 1) >> 1;
00128         Image * t = curr;
00129         ImageMask * tm = currMask;
00130         curr = next;
00131         currMask = nextMask;
00132         next = t;
00133         nextMask = tm;
00134     }
00135 }
00136 
00137 template <class ImageIn, class ImageOut>
00138 void reduceToNextLevel(ImageIn & in, ImageOut & out)
00139 {
00140     typedef typename ImageOut::value_type vt;
00141     typedef typename vigra::NumericTraits<vt>::RealPromote SKIPSMType;
00142 
00143     size_t w = in.width();
00144     size_t h = in.height();
00145     // Size of next level
00146     w = (w + 1) >> 1;
00147     h = (h + 1) >> 1;
00148     out.resize(w,h);
00149     enblend::reduce<SKIPSMType>(false, srcImageRange(in), destImageRange(out));
00150 }
00151 
00152 template <class ImageIn, class ImageInMask, class ImageOut, class ImageOutMask>
00153 void reduceToNextLevel(ImageIn & in, ImageInMask & inMask, ImageOut & out, ImageOutMask & outMask)
00154 {
00155     typedef typename ImageOut::value_type vt;
00156     typedef typename vigra::NumericTraits<vt>::RealPromote SKIPSMType;
00157     //typedef typename vigra::NumericTraits<typename ImageOutMask::value_type>::Promote SKIPSMAlphaType;
00158     typedef double SKIPSMAlphaType;
00159 
00160     size_t w = in.width();
00161     size_t h = in.height();
00162     // Size of next level
00163     w = (w + 1) >> 1;
00164     h = (h + 1) >> 1;
00165     out.resize(w,h);
00166     enblend::reduce<SKIPSMType, SKIPSMAlphaType>(false, srcImageRange(in), srcImage(inMask),
00167                                 destImageRange(out), destImageRange(outMask));
00168 }
00169 
00170 
00171 static const double AA = 0.4;
00172 static const double W[] = {0.25 - AA / 2.0, 0.25, AA, 0.25, 0.25 - AA / 2.0};
00173 
00178 template <class Image>
00179 void reduceToNextLevelOld(Image & in, Image & out)
00180 {
00181     DEBUG_TRACE("");
00182     // image size at current level
00183     int width = in.width();
00184     int height = in.height();
00185 
00186     // image size at next smaller level
00187     int newwidth = (width + 1) / 2;
00188     int newheight = (height + 1) / 2;
00189 
00190     // resize result image to appropriate size
00191     out.resize(newwidth, newheight);
00192 
00193     // define a Gaussian kernel (size 5x1)
00194     // with sigma = 1
00195     vigra::Kernel1D<double> filter;
00196     filter.initExplicitly(-2, 2) = W[0], W[1], W[2], W[3], W[4];
00197 
00198     vigra::BasicImage<typename Image::value_type> tmpimage1(width, height);
00199     vigra::BasicImage<typename Image::value_type> tmpimage2(width, height);
00200 
00201     // smooth (band limit) input image
00202     separableConvolveX(srcImageRange(in),
00203                        destImage(tmpimage1), kernel1d(filter));
00204     separableConvolveY(srcImageRange(tmpimage1),
00205                        destImage(tmpimage2), kernel1d(filter));
00206 
00207     // downsample smoothed image
00208     resizeImageNoInterpolation(srcImageRange(tmpimage2), destImageRange(out));
00209 
00210 }
00211 
00212 } // namespace
00213 
00214 
00215 #endif // VIGRA_EXT_PYRAMID_H

Generated on Mon Sep 20 01:01:27 2010 for Hugintrunk by doxygen 1.3.9.1