contrib/tbl/vipl/vipl_erode_disk.txx
Go to the documentation of this file.
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   // circular mask was generated in preop(), we just use it here
00019 
00020   // apply filter:
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; // = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::start(this->Y_Axis());
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()); // = height(out);
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)); // set v to min of surrounding pixels:
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 // it is important that the mask be computed in preop, if it was done in
00053 // section_applyop then on a large image it would be computed many times.
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   // create circular mask:
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 // Since we will know if radius changes between calls to filter, we
00094 // destroy the mask in postop, after we are all done filtering
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_