00001 #ifndef vipl_moment_txx_
00002 #define vipl_moment_txx_
00003
00004 #include "vipl_moment.h"
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #if !(defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500))
00015
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
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_;
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
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
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
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
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_