00001 #ifndef vipl_median_txx_
00002 #define vipl_median_txx_
00003
00004 #include "vipl_median.h"
00005
00006 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00007 bool vipl_median <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: section_applyop()
00008 {
00009 const ImgIn &in = this->in_data(0);
00010 ImgOut &out = *this->out_data_ptr();
00011 int size = (radius() < 0) ? 0 : int(radius());
00012
00013
00014
00015
00016 DataIn* v = new DataIn[(2*size+1)*(2*size+1)];
00017 int startx = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::start(this->X_Axis());
00018 int starty = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::start(this->Y_Axis());
00019 int stopx = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::stop(this->X_Axis());
00020 int stopy = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::stop(this->Y_Axis());
00021 for (int j = starty; j < stopy; ++j)
00022 for (int i = startx; i < stopx; ++i) {
00023 register unsigned int count = 0;
00024 v[count++] = fgetpixel(in, i, j, DataIn(0));
00025 for (int x=0; x<=size; ++x) for (int y=0; y<=size; ++y) if (mask()[x][y]) {
00026 v[count++] = getpixel(in, i+x, j+y, DataIn(0));
00027 v[count++] = getpixel(in, i-x, j+y, DataIn(0));
00028 v[count++] = getpixel(in, i+x, j-y, DataIn(0));
00029 v[count++] = getpixel(in, i-x, j-y, DataIn(0));
00030 }
00031
00032 for (unsigned int d=count/2; d>0; d/=2)
00033 for (unsigned int ii=d; ii<count; ++ii)
00034 for (int jj=ii-d; jj>=0 && v[jj]>v[jj+d]; jj-=d) {
00035 DataIn t = v[jj]; v[jj] = v[jj+d]; v[jj+d] = t;
00036 }
00037
00038 fsetpixel(out, i, j, DataOut(v[count/2]));
00039 }
00040 delete[] v;
00041 return true;
00042 }
00043
00044
00045
00046 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00047 bool vipl_median <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: preop()
00048 {
00049
00050 int size = (radius() < 0) ? 0 : int(radius());
00051 float rs = (radius() < 0) ? 0 : radius() * radius();
00052 typedef bool* boolptr;
00053 if (mask() == 0)
00054 ref_mask() = new boolptr[1+size];
00055 else {
00056 for (int x=0; x<=size; ++x)
00057 if (mask()[x]) delete[] ref_mask()[x];
00058 delete[] ref_mask();
00059 ref_mask() = new boolptr[1+size];
00060 }
00061 for (int x=0; x<=size; ++x) {
00062 ref_mask()[x] = new bool[size+1];
00063 for (int y=0; y<=size; ++y)
00064 ref_mask()[x][y] = (x*x + y*y <= rs);
00065 }
00066 return true;
00067 }
00068
00069
00070
00071 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00072 bool vipl_median <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: postop()
00073 {
00074 int size = (radius() < 0) ? 0 : int(radius());
00075 if (mask()) {
00076 for (int x=0; x<=size; ++x)
00077 if (mask()[x]) delete[] ref_mask()[x];
00078 delete[] ref_mask();
00079 ref_mask()=0;
00080 }
00081 return true;
00082 }
00083
00084 #endif // vipl_median_txx_