core/vil/algo/vil_suppress_non_max.h
Go to the documentation of this file.
00001 // This is core/vil/algo/vil_suppress_non_max.h
00002 #ifndef vil_suppress_non_max_h_
00003 #define vil_suppress_non_max_h_
00004 //:
00005 // \file
00006 // \brief Suppress all non-maximal points in image
00007 // \author Tim Cootes
00008 
00009 #include <vil/vil_image_view.h>
00010 #include <vil/algo/vil_find_peaks.h>
00011 #include <vil/vil_fill.h>
00012 #include <vcl_cassert.h>
00013 
00014 //: Suppress all non-maximal (non peaks) pixels in the image
00015 //  If image(i,j) is strictly larger than all neighbouring pixels,
00016 //  and is above the threshold, then it is retained. All other
00017 //  pixels are set to non_max_value.
00018 //
00019 //  non_max_value must be below the threshold (so the default value of
00020 //  zero is inappropriate if the image contains peaks of interest with
00021 //  negative values)
00022 //
00023 //  Note that where there are neighbouring pixels with identical values
00024 //  on a raised plateau, then all the pixels on the plateau will be
00025 //  suppressed.  This can cause some peaks to be missed.  The effect
00026 //  can be reduced by using float images and pre-smoothing slightly.
00027 //  Alternatively, use vil_suppress_non_plateau_3x3() to retain plateau
00028 //  points as well as strict maxima.
00029 //
00030 // \sa vil_suppress_non_plateau_3x3()
00031 // \relatesalso vil_image_view
00032 template <class T>
00033 inline void vil_suppress_non_max_3x3(const vil_image_view<T>& src_im,
00034                                      vil_image_view<T>& dest_im,
00035                                      T threshold=0, T non_max_value=0)
00036 {
00037   unsigned ni=src_im.ni(),nj=src_im.nj();
00038   assert(src_im.nplanes()==1);
00039 
00040   dest_im.set_size(ni,nj,1);
00041 
00042   vcl_ptrdiff_t istep = src_im.istep(),jstep=src_im.jstep();
00043   vcl_ptrdiff_t distep = dest_im.istep(),djstep=dest_im.jstep();
00044   const T* row = src_im.top_left_ptr()+istep+jstep;
00045   T* drow = dest_im.top_left_ptr()+distep+djstep;
00046   for (unsigned j=1;j<nj-1;++j,row+=jstep,drow+=djstep)
00047   {
00048     const T* pixel = row;
00049     T* dpixel = drow;
00050     for (unsigned i=1;i<ni-1;++i,pixel+=istep,dpixel+=distep)
00051     {
00052       if (*pixel<threshold || !vil_is_peak_3x3(pixel,istep,jstep))
00053         *dpixel = non_max_value;
00054       else
00055         *dpixel = *pixel;
00056     }
00057   }
00058 
00059   // Border pixels assumed not to be local maxima
00060   vil_fill_row(dest_im,0,non_max_value);
00061   vil_fill_row(dest_im,nj-1,non_max_value);
00062   vil_fill_col(dest_im,0,non_max_value);
00063   vil_fill_col(dest_im,ni-1,non_max_value);
00064 }
00065 
00066 #endif // vil_suppress_non_max_h_