contrib/tbl/vipl/vipl_dilate_disk.txx
Go to the documentation of this file.
00001 #ifndef vipl_dilate_disk_txx_
00002 #define vipl_dilate_disk_txx_
00003 
00004 #include "vipl_dilate_disk.h"
00005 #include <vcl_algorithm.h>
00006 
00007 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00008 bool vipl_dilate_disk <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: section_applyop()
00009 {
00010   const ImgIn &in = this->in_data(0);
00011   ImgOut &out = this->out_data();
00012   int size = (radius() < 0) ? 0 : int(radius());
00013   // mask is filled in preop function
00014   // apply filter:
00015   int startx = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::start(this->X_Axis());
00016   int starty = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::start(this->Y_Axis());
00017   int stopx  = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::stop(this->X_Axis());
00018   int stopy  = vipl_filter<ImgIn,ImgOut,DataIn,DataOut,2,PixelItr>::stop(this->Y_Axis());
00019   for (register int j = starty, ej =  stopy; j < ej  ; ++j)
00020     for (register int i = startx, ei = stopx; i < ei ; ++i)
00021     {
00022       DataIn v = fgetpixel(in, i, j, DataIn(0)); // set v to max of surrounding pixels:
00023       for (register int x=0; x<=size; ++x)
00024       for (register int y=0; y<=size; ++y)
00025         if (mask()[x][y]) {
00026           v = vcl_max(v, getpixel(in, i+x, j+y, DataIn(0)));
00027           v = vcl_max(v, getpixel(in, i-x, j+y, DataIn(0)));
00028           v = vcl_max(v, getpixel(in, i+x, j-y, DataIn(0)));
00029           v = vcl_max(v, getpixel(in, i-x, j-y, DataIn(0)));
00030         }
00031       fsetpixel(out, i, j, DataOut(v));
00032     }
00033   return true;
00034 }
00035 
00036 // it is important that the mask be computed in preop, if it was done in
00037 // section_applyop then on a large image it would be computed many times.
00038 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00039 bool vipl_dilate_disk <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: preop()
00040 {
00041   // create circular mask:
00042   int size = (radius() < 0) ? 0 : int(radius());
00043   float rs = (radius() < 0) ? 0 : radius() * radius();
00044   typedef bool* boolptr;
00045   if (mask() == 0)
00046          ref_mask() = new boolptr[1+size];
00047   else {
00048     for (int x=0; x<=size; ++x)
00049       if (mask()[x]) delete[] ref_mask()[x];
00050     delete[] ref_mask();
00051     ref_mask() = new boolptr[1+size];
00052   }
00053   for (int x=0; x<=size; ++x) {
00054     ref_mask()[x] = new bool[size+1];
00055     for (int y=0; y<=size; ++y)
00056       ref_mask()[x][y] = (x*x + y*y <= rs);
00057   }
00058   return true;
00059 }
00060 
00061 // Since we will know if radius changes between calls to filter, we
00062 // destroy the mask in postop, after we are all done filtering
00063 template <class ImgIn,class ImgOut,class DataIn,class DataOut,class PixelItr>
00064 bool vipl_dilate_disk <ImgIn,ImgOut,DataIn,DataOut,PixelItr> :: postop()
00065 {
00066   int size = (radius() < 0) ? 0 : int(radius());
00067   if (mask()) {
00068     for (int x=0; x<=size; ++x)
00069       if (mask()[x]) delete[] ref_mask()[x];
00070     delete[] ref_mask();
00071     ref_mask()=0;
00072   }
00073   return true;
00074 }
00075 
00076 #endif // vipl_dilate_disk_txx_