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 double SKIPSMAlphaType;
00085 
00086     if (n <= 0) {
00087         out = in;
00088         outMask = inMask;
00089         return;
00090     }
00091 
00092     size_t w = in.width();
00093     size_t h = in.height();
00094     // Size of next level
00095     w = (w + 1) >> 1;
00096     h = (h + 1) >> 1;
00097 
00098     Image temp;
00099     ImageMask tempMask;
00100     Image * curr = &temp;
00101     ImageMask * currMask = &tempMask;
00102     Image * next = &out;
00103     ImageMask * nextMask = &outMask;
00104     if( (n % 2) == 1)
00105     {
00106         // even number of reduce operations, first reduce into output image
00107         curr = &out;
00108         currMask = &outMask;
00109         next = &temp;
00110         nextMask = &tempMask;
00111     }
00112     curr->resize(w,h);
00113     currMask->resize(w,h);
00114     enblend::reduce<SKIPSMType, SKIPSMAlphaType>(false, srcImageRange(in), srcImage(inMask), 
00115                                 destImageRange(*curr), destImageRange(*currMask));
00116     n--;
00117     w = (w + 1) >> 1;
00118     h = (h + 1) >> 1;
00119     for( ; n > 0 ; --n) {
00120         next->resize(w,h);
00121         nextMask->resize(w,h);
00122         enblend::reduce<SKIPSMType, SKIPSMAlphaType>(false, srcImageRange(*curr), srcImage(*currMask),
00123                                     destImageRange(*next), destImageRange(*nextMask));
00124         w = (w + 1) >> 1;
00125         h = (h + 1) >> 1;
00126         Image * t = curr;
00127         ImageMask * tm = currMask;
00128         curr = next;
00129         currMask = nextMask;
00130         next = t;
00131         nextMask = tm;
00132     }
00133 }
00134 
00135 template <class ImageIn, class ImageOut>
00136 void reduceToNextLevel(ImageIn & in, ImageOut & out)
00137 {
00138     typedef typename ImageOut::value_type vt;
00139     typedef typename vigra::NumericTraits<vt>::RealPromote SKIPSMType;
00140 
00141     size_t w = in.width();
00142     size_t h = in.height();
00143     // Size of next level
00144     w = (w + 1) >> 1;
00145     h = (h + 1) >> 1;
00146     out.resize(w,h);
00147     enblend::reduce<SKIPSMType>(false, srcImageRange(in), destImageRange(out));
00148 }
00149 
00150 template <class ImageIn, class ImageInMask, class ImageOut, class ImageOutMask>
00151 void reduceToNextLevel(ImageIn & in, ImageInMask & inMask, ImageOut & out, ImageOutMask & outMask)
00152 {
00153     typedef typename ImageOut::value_type vt;
00154     typedef typename vigra::NumericTraits<vt>::RealPromote SKIPSMType;
00155     //typedef typename vigra::NumericTraits<typename ImageOutMask::value_type>::Promote SKIPSMAlphaType;
00156     typedef double SKIPSMAlphaType;
00157 
00158     size_t w = in.width();
00159     size_t h = in.height();
00160     // Size of next level
00161     w = (w + 1) >> 1;
00162     h = (h + 1) >> 1;
00163     out.resize(w,h);
00164     enblend::reduce<SKIPSMType, SKIPSMAlphaType>(false, srcImageRange(in), srcImage(inMask),
00165                                 destImageRange(out), destImageRange(outMask));
00166 }
00167 
00168 
00169 static const double AA = 0.4;
00170 static const double W[] = {0.25 - AA / 2.0, 0.25, AA, 0.25, 0.25 - AA / 2.0};
00171 
00176 template <class Image>
00177 void reduceToNextLevelOld(Image & in, Image & out)
00178 {
00179     DEBUG_TRACE("");
00180     // image size at current level
00181     int width = in.width();
00182     int height = in.height();
00183 
00184     // image size at next smaller level
00185     int newwidth = (width + 1) / 2;
00186     int newheight = (height + 1) / 2;
00187 
00188     // resize result image to appropriate size
00189     out.resize(newwidth, newheight);
00190 
00191     // define a Gaussian kernel (size 5x1)
00192     // with sigma = 1
00193     vigra::Kernel1D<double> filter;
00194     filter.initExplicitly(-2, 2) = W[0], W[1], W[2], W[3], W[4];
00195 
00196     vigra::BasicImage<typename Image::value_type> tmpimage1(width, height);
00197     vigra::BasicImage<typename Image::value_type> tmpimage2(width, height);
00198 
00199     // smooth (band limit) input image
00200     separableConvolveX(srcImageRange(in),
00201                        destImage(tmpimage1), kernel1d(filter));
00202     separableConvolveY(srcImageRange(tmpimage1),
00203                        destImage(tmpimage2), kernel1d(filter));
00204 
00205     // downsample smoothed image
00206     resizeImageNoInterpolation(srcImageRange(tmpimage2), destImageRange(out));
00207 
00208 }
00209 
00210 } // namespace
00211 
00212 
00213 #endif // VIGRA_EXT_PYRAMID_H

Generated on 28 Sep 2016 for Hugintrunk by  doxygen 1.4.7