VLFeat.org

API docs

  • Home
    • Download and Install
    • API docs
    • Matlab docs
    • About VLFeat
  • Tutorials
    • SIFT
    • MSER
    • IKM
    • HIKM
    • AIB
    • Utils
  • Main Page
  • Related Pages
  • Data Structures
  • Files
  • Examples

imop.tc

Go to the documentation of this file.
00001 
00006 /* AUTORIGHTS
00007 Copyright 2007 (c) Andrea Vedaldi and Brian Fulkerson
00008 
00009 This file is part of VLFeat, available in the terms of the GNU
00010 General Public License version 2.
00011 */
00012 
00013 #include "mathop.h"
00014 
00015 #include <math.h>
00016 #include <stdlib.h>
00017 
00018 #undef VL_IMSMOOTH
00019 #undef VL_IMSMOOTH_
00020 #undef VL_CONVTRANSP
00021 #undef VL_CONVTRANSP_
00022 
00023 #define VL_IMSMOOTH(SFX)    vl_imsmooth_ ## SFX
00024 #define VL_IMSMOOTH_(SFX)   VL_IMSMOOTH(SFX)
00025 #define VL_CONVTRANSP(SFX)  vl_convtransp_ ## SFX
00026 #define VL_CONVTRANSP_(SFX) VL_CONVTRANSP(SFX)
00027 
00028 VL_EXPORT
00029 void
00030 VL_CONVTRANSP_(SFX) (PIX       *dst,
00031                      PIX const *src,
00032                      PIX const *filt,
00033                      int width, int height, int filt_width,
00034                      int mode)
00035 {
00036   int i, j ;
00037 
00038   /* Convolve along the first dimension. Also, circularly swap     */
00039   /* dimension in the output, making the first dimension the last  */
00040   /*                                                               */
00041   /* src  is width x height                                        */
00042   /* dst  is height x width                                        */
00043   /* filt is 2 * filt_width + 1                                    */
00044   /*                                                               */
00045 
00046   switch (mode) {
00047   case VL_CONV_CONT :
00048     for(j = 0 ; j < height ; ++j) {
00049       for(i = 0 ; i < width ; ++i) {
00050         PIX        acc   = 0.0 ;
00051         PIX const *g     = filt ;
00052         PIX const *start = src + (i - filt_width) ;
00053         PIX const *stop ;
00054         PIX        x ;
00055 
00056         /* beginning */
00057         stop = src + VL_MAX(0, i - filt_width) ;
00058         x    = *stop ;
00059         while (start <= stop) { acc += (*g++) * x ; start++ ; }
00060 
00061         /* middle */
00062         stop =  src + VL_MIN(width - 1, i + filt_width) ;
00063         while (start <  stop) acc += (*g++) * (*start++) ;
00064 
00065         /* end */
00066         x  = *start ;
00067         stop = src + (i + filt_width) ;
00068         while (start <= stop) { acc += (*g++) * x ; start++ ; }
00069 
00070         /* save */
00071         *dst = acc ;
00072         dst += height ;
00073 
00074         assert (g - filt == 2 * filt_width +1) ;
00075       }
00076       /* next column */
00077       src += width ;
00078       dst -= width*height - 1 ;
00079     }
00080     break ;
00081 
00082   default:
00083     assert (0) ;
00084   }
00085 }
00086 
00087 VL_EXPORT
00088 void
00089 VL_IMSMOOTH_(SFX)(PIX        *dst,
00090                   PIX        *temp,
00091                   PIX  const *src,
00092                   int width, int height, double sigma)
00093 {
00094   /* We use either a static buffer or, if the variance is very big, a
00095    * new buffer. This is efficient and robust to buffer stealing. */
00096   static PIX   *filt       = 0 ;
00097   static int    filt_width = -1 ;
00098   static double filt_static_sigma = -1.0 ;  
00099   enum          { filt_static_res = 1024 } ;
00100   static PIX    filt_static [2 * filt_static_res + 1] ;
00101 
00102   int j ;
00103 
00104   if (sigma < (PIX)(1e-5)) {
00105     dst = memcpy(dst,src,width*height*sizeof(PIX)) ;
00106     return ;
00107   }                       
00108 
00109   /* window width */
00110   filt_width = ceil (4.0 * sigma) ;
00111 
00112   /* setup filter only if not available from previous iteration*/
00113   if (filt_static_sigma != sigma) {
00114     PIX acc = 0.0 ;
00115 
00116     if (filt_width <= filt_static_res) {
00117       /* use static buffer */
00118       filt = filt_static ;
00119       filt_static_sigma = sigma ;
00120     } else {
00121       /* dynamically allocate a larger buffer */
00122       filt = vl_malloc  (sizeof(PIX) * (2*filt_width+1)) ;
00123     }
00124     
00125     for (j = 0 ; j < 2 * filt_width + 1 ; ++j) {
00126       PIX  d = (PIX)(j - filt_width) / (PIX)(sigma) ;
00127       filt [j] = exp (- 0.5 * d * d) ;
00128       acc += filt [j] ;
00129     }
00130     
00131     /* normalize */
00132     for (j = 0 ; j < 2 * filt_width + 1 ; ++j) {
00133       filt [j] /= acc ;
00134     }
00135   }
00136   
00137   /* convolve */
00138   VL_CONVTRANSP_(SFX) (temp, src, filt,
00139                        width, height, filt_width,
00140                        VL_CONV_CONT) ;
00141   VL_CONVTRANSP_(SFX) (dst, temp, filt,
00142                        height, width, filt_width,
00143                        VL_CONV_CONT) ;
00144 
00145   /* free buffer? */
00146   if (filt_static_sigma != sigma) {
00147     vl_free (filt) ;
00148   }
00149 }
00150 
00151 /* 
00152  * Local Variables: *
00153  * mode: C *
00154  * End: *
00155  */
Copyright © 2008 Andrea Vedaldi and Brian Fulkerson