contrib/tbl/vipl/vipl_moment.txx
Go to the documentation of this file.
00001 #ifndef vipl_moment_txx_
00002 #define vipl_moment_txx_
00003 
00004 #include "vipl_moment.h"
00005 
00006 // "integer power" function, used in the filter.
00007 // Note that the input and return types are double: we could have made this
00008 // templated on the "DataIn" type, but it makes no sense to do arithmetic
00009 // on say a ubyte value in ubyte, as we don't want a "modulo 256" result!
00010 // (Actually the return type should be vnl_numeric_traits<T>::real_t
00011 // but only for T=complex this makes a difference, and we don't want to
00012 // depend on vnl just for this alone.)
00013 
00014 #if !(defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
00015 // template code cannot see file statics.
00016 static
00017 #endif
00018 double power(double x, int y)
00019 {
00020   if (y == 0)
00021     return 1.0;
00022   double r = 1.0;
00023   if (y < 0)
00024   {
00025     y = -y;
00026     x = 1/x;
00027   }
00028   while (true)
00029   {
00030     if (y & 1)
00031       r *= x;
00032     if (y >>= 1)
00033       x *= x;
00034     else
00035       break;
00036   }
00037   return r;
00038 }
00039 
00040 
00041 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00042 bool vipl_moment <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: section_applyop()
00043 {
00044   const ImgIn &in = this->in_data(0);
00045   ImgOut &out = *this->out_data_ptr();
00046 
00047   // We create a (double) float buffer to hold the computed values.
00048 
00049   int startx = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::start(this->X_Axis());
00050   int starty = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::start(this->Y_Axis());
00051   int stopx  = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::stop(this->X_Axis());
00052   int stopy  = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::stop(this->Y_Axis());
00053 
00054   int sizex = stopx-startx+1;
00055   int sizey = stopy-starty+1;
00056 
00057   double* tempbuf = new double[sizex*sizey];
00058 
00059   int size = width_*height_; // size of the mask
00060 
00061   int x1 = width_%2 ? width_/2 : width_/2-1;
00062   int x2 = width_/2;
00063   int y1 = height_%2 ? height_/2 : height_/2-1;
00064   int y2 = height_/2;
00065 
00066   double d = 0.0;
00067 
00068   // First we create the outvalue for the first element
00069 
00070   for (int i=startx-x1;i<=(startx+x2);++i)
00071     for (int j=starty-y1;j<=(starty+y2);++j)
00072     {
00073       DataIn w = getpixel(in,i,j,DataIn(0));
00074       d += power(double(w),order_);
00075     }
00076   tempbuf[0] = d;
00077   d/=size;
00078   fsetpixel(out,startx,starty,DataOut(d));
00079 
00080   // Now we create the outvalue for the first row
00081 
00082   for (int i = startx+1; i < stopx; ++i)
00083   {
00084     d = tempbuf[i-startx-1];
00085     for (int j = starty-y1;j<=starty+y2;++j)
00086     {
00087       DataIn
00088       w  = getpixel(in,i-1-x1,j,DataIn(0));
00089       d -= power(double(w),order_);
00090       w  = getpixel(in,i+x2,j,DataIn(0));
00091       d += power(double(w),order_);
00092     }
00093     tempbuf[i-startx] = d;
00094     d /= size;
00095     fsetpixel(out,i,starty,DataOut(d));
00096   }
00097 
00098   // Now we create the outvalue for the first column
00099 
00100   for (int j = starty+1; j < stopy; ++j)
00101   {
00102     d = tempbuf[(j-starty-1)*sizex];
00103     for (int i = startx-x1;i<=startx+x2;++i)
00104     {
00105       DataIn
00106       w  = getpixel(in,i,j-1-y1,DataIn(0));
00107       d -= power(double(w),order_);
00108       w  = getpixel(in,i,j+y2,DataIn(0));
00109       d += power(double(w),order_);
00110     }
00111     tempbuf[(j-starty)*sizex] = d;
00112     d /= size;
00113     fsetpixel(out,startx,j,DataOut(d));
00114   }
00115 
00116   // Now we can go for the rest of the section:
00117 
00118   for (int i = startx+1; i < stopx; ++i)
00119     for (int j = starty+1; j < stopy; ++j)
00120     {
00121       int i1 = i-startx;
00122       int j1 = j-starty;
00123       d = tempbuf[i1-1 + j1*sizex] + tempbuf[i1+(j1-1)*sizex] - tempbuf[(i1-1) + (j1-1)*sizex];
00124       DataIn
00125       w = getpixel(in,i-x1-1,j-y1-1,DataIn(0));  d += power(double(w),order_);
00126       w = getpixel(in,i-x1-1,j+y2,DataIn(0));    d -= power(double(w),order_);
00127       w = getpixel(in,i+x2,j-y1-1,DataIn(0));    d -= power(double(w),order_);
00128       w = getpixel(in,i+x2,j+y2,DataIn(0));      d += power(double(w),order_);
00129       tempbuf[i1+j1*sizex] = d;
00130       d /= size;
00131       fsetpixel(out,i,j,DataOut(d));
00132     }
00133 
00134   delete[] tempbuf;
00135 
00136   return true;
00137 }
00138 
00139 #endif // vipl_moment_txx_