00001 #ifndef vipl_erode_disk_txx_
00002 #define vipl_erode_disk_txx_
00003
00004 #include "vipl_erode_disk.h"
00005 #include <vcl_algorithm.h>
00006 #include <vcl_iostream.h>
00007
00008 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00009 bool vipl_erode_disk <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: section_applyop()
00010 {
00011 #ifdef DEBUG
00012 vcl_cout << "Starting vipl_erode_disk::section_applyop() ...";
00013 #endif
00014 const ImgIn &in = this->in_data(0);
00015 ImgOut &out = *this->out_data_ptr();
00016 int size = (radius() < 0) ? 0 : int(radius());
00017
00018
00019
00020
00021 #ifdef DEBUG
00022 vcl_cout << " set start & stop ...";
00023 #endif
00024 int startx = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::start(this->X_Axis());
00025 int starty = 0;
00026 int stopx = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::stop(this->X_Axis());
00027 int stopy = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::stop(this->Y_Axis());
00028 #ifdef DEBUG
00029 vcl_cout << " (" << startx << ':' << stopx << ',' << starty << ':' << stopy << ')';
00030 vcl_cout << " run over image ...";
00031 #endif
00032 for (register int j = starty; j < stopy; ++j)
00033 for (register int i = startx; i < stopx; ++i)
00034 {
00035 DataIn v = fgetpixel(in, i, j, DataIn(0));
00036 for (register int x=0; x<=size; ++x)
00037 for (register int y=0; y<=size; ++y)
00038 if (mask()[x][y]) {
00039 v = vcl_min(v, getpixel(in, i+x, j+y, DataIn(0)));
00040 v = vcl_min(v, getpixel(in, i-x, j+y, DataIn(0)));
00041 v = vcl_min(v, getpixel(in, i+x, j-y, DataIn(0)));
00042 v = vcl_min(v, getpixel(in, i-x, j-y, DataIn(0)));
00043 }
00044 fsetpixel(out, i, j, DataOut(v));
00045 }
00046 #ifdef DEBUG
00047 vcl_cout << " done\n";
00048 #endif
00049 return true;
00050 }
00051
00052
00053
00054 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00055 bool vipl_erode_disk <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: preop()
00056 {
00057 #ifdef DEBUG
00058 vcl_cout << "Starting vipl_erode_disk::preop() ...";
00059 #endif
00060
00061 int size = (radius() < 0) ? 0 : int(radius());
00062 float rs = (radius() < 0) ? 0 : radius() * radius();
00063 typedef bool* boolptr;
00064 if (mask() == 0) {
00065 #ifdef DEBUG
00066 vcl_cout << " allocate mask ...";
00067 #endif
00068 ref_mask() = new boolptr[1+size];
00069 }
00070 else {
00071 #ifdef DEBUG
00072 vcl_cout << " re-allocate mask ...";
00073 #endif
00074 for (int x=0; x<=size; ++x)
00075 if (mask()[x]) delete[] ref_mask()[x];
00076 delete[] ref_mask();
00077 ref_mask() = new boolptr[1+size];
00078 }
00079 #ifdef DEBUG
00080 vcl_cout << " write mask ...";
00081 #endif
00082 for (int x=0; x<=size; ++x) {
00083 ref_mask()[x] = new bool[size+1];
00084 for (int y=0; y<=size; ++y)
00085 ref_mask()[x][y] = (x*x + y*y <= rs);
00086 }
00087 #ifdef DEBUG
00088 vcl_cout << " done\n";
00089 #endif
00090 return true;
00091 }
00092
00093
00094
00095 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00096 bool vipl_erode_disk <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: postop()
00097 {
00098 #ifdef DEBUG
00099 vcl_cout << "Starting vipl_erode_disk::postop() ...";
00100 #endif
00101 int size = (radius() < 0) ? 0 : int(radius());
00102 if (mask()) {
00103 #ifdef DEBUG
00104 vcl_cout << " de-allocate mask ...";
00105 #endif
00106 for (int x=0; x<=size; ++x)
00107 if (mask()[x]) delete[] ref_mask()[x];
00108 delete[] ref_mask();
00109 ref_mask()=0;
00110 }
00111 #ifdef DEBUG
00112 vcl_cout << " done\n";
00113 #endif
00114 return true;
00115 }
00116
00117 #endif // vipl_erode_disk_txx_