core/vil/algo/vil_find_4con_boundary.h
Go to the documentation of this file.
00001 #ifndef vil_find_4con_boundary_h_
00002 #define vil_find_4con_boundary_h_
00003 
00004 #include <vil/vil_image_view.h>
00005 #include <vcl_cassert.h>
00006 #include <vcl_vector.h>
00007 
00008 //:
00009 // \file
00010 // \brief Function to find 4-connected boundary around thresholded region
00011 // \author Tim Cootes
00012 
00013 //: Move (i,j) to next point below threshold
00014 //  Start looking in direction dir (0=++x,1=++y,2=--x,3=--y)
00015 //  *p is current point (i,j).
00016 //  On exit (i,j) and p are updated to move to neighbour
00017 template<class T>
00018 inline void vil_next_point_below_thresh4(int& i,int& j,int& dir, const T* &p,
00019                                          int ni1, int nj1,
00020                                          vcl_ptrdiff_t istep,vcl_ptrdiff_t jstep,
00021                                          T threshold)
00022 {
00023   for (int k=0;k<4;++k)
00024   {
00025     switch ((dir+k)%4)
00026     {
00027       case 0:   // Try at (i+1,j)
00028         if (i<ni1 && p[istep]<=threshold) { ++i; p+=istep; dir=3; return; }
00029       case 1:   // Try at (i,j+1)
00030         if (j<nj1 && p[jstep]<=threshold) { ++j; p+=jstep; dir=0; return; }
00031       case 2:   // Try at (i-1,j)
00032         if (i>0 && p[-istep]<=threshold)  { --i; p-=istep; dir=1; return; }
00033       case 3:   // Try at (i,j-1)
00034         if (j>0 && p[-jstep]<=threshold)  { --j; p-=jstep; dir=2; return; }
00035       default:
00036         break;
00037     }
00038   }
00039 }
00040 
00041 //: Move (i,j) to next point above threshold
00042 //  Start looking in direction dir (0=++x,1=++y,2=--x,3=--y)
00043 //  *p is current point (i,j).
00044 //  On exit (i,j) and p are updated to move to neighbour
00045 template<class T>
00046 inline void vil_next_point_above_thresh4(int& i,int& j,int& dir, const T* &p,
00047                                          int ni1, int nj1, vcl_ptrdiff_t istep, vcl_ptrdiff_t jstep,
00048                                          T threshold)
00049 {
00050   for (int k=0;k<4;++k)
00051   {
00052     switch ((dir+k)%4)
00053     {
00054       case (0):   // Try at (i+1,j)
00055         if (i<ni1 && p[istep]>=threshold) { ++i; p+=istep; dir=3; return; }
00056       case (1):   // Try at (i,j+1)
00057         if (j<nj1 && p[jstep]>=threshold) { ++j; p+=jstep; dir=0; return; }
00058       case (2):   // Try at (i-1,j)
00059         if (i>0 && p[-istep]>=threshold)  { --i; p-=istep; dir=1; return; }
00060       case (3):   // Try at (i,j-1)
00061         if (j>0 && p[-jstep]>=threshold)  { --j; p-=jstep; dir=2; return; }
00062       default:
00063         break;
00064     }
00065   }
00066 }
00067 
00068 
00069 //: Find 4-connected boundary around thresholded region containing point
00070 //  Assumes that (p0_i,p0_j) is a point in the image which satisfies
00071 //  the threshold (ie image(p0_i,p0_j)<=threshold).
00072 //  Searches for the boundary pixels (ie points which satisfy threshold
00073 //  next to ones which don't) and runs around until it gets back to beginning.
00074 //  On exit the boundary points are given by (bi[k],bj[k])
00075 template <class T>
00076 inline void vil_find_4con_boundary_below_threshold(vcl_vector<int>& bi,
00077                                                    vcl_vector<int>& bj,
00078                                                    const vil_image_view<T>& image,
00079                                                    const T& threshold,
00080                                                    int p0_i, int p0_j)
00081 {
00082   bi.resize(0); bj.resize(0);
00083   int ni1 = image.ni()-1;
00084   int nj1 = image.nj()-1;
00085   vcl_ptrdiff_t istep = image.istep(), jstep=image.jstep();
00086 
00087   int i = p0_i, j = p0_j;
00088   const T* p = &image(i,j);
00089   assert(*p<=threshold);
00090 
00091   // Move to extremal point on boundary
00092   while (i<ni1 && p[istep]<=threshold) {i++;p+=istep;}
00093   int dir = 1;
00094 
00095   if (i==p0_i)
00096   {
00097     // Initial point already on boundary - move to extreme j
00098     while (j<nj1 && p[jstep]<=threshold) {j++;p+=jstep;}
00099     dir = 2;
00100   }
00101 
00102   int i0 = i, j0=j;
00103 
00104   do
00105   {
00106     bi.push_back(i); bj.push_back(j);
00107     vil_next_point_below_thresh4(i,j,dir,p,ni1,nj1,istep,jstep,threshold);
00108   }
00109   while (i!=i0 || j!=j0);
00110 }
00111 
00112 //: Find 4-connected boundary around thresholded region containing point
00113 //  Assumes that (p0_i,p0_j) is a point in the image which satisfies
00114 //  the threshold (ie image(p0_i,p0_j)>=threshold).
00115 //  Searches for the boundary pixels (ie points which satisfy threshold
00116 //  next to ones which don't) and runs around until it gets back to beginning.
00117 //  On exit the boundary points are given by (bi[k],bj[k])
00118 template <class T>
00119 inline void vil_find_4con_boundary_above_threshold(vcl_vector<int>& bi,
00120                                                    vcl_vector<int>& bj,
00121                                                    const vil_image_view<T>& image,
00122                                                    const T& threshold,
00123                                                    int p0_i, int p0_j)
00124 {
00125   bi.resize(0); bj.resize(0);
00126   int ni1 = image.ni()-1;
00127   int nj1 = image.nj()-1;
00128   vcl_ptrdiff_t istep = image.istep(), jstep=image.jstep();
00129 
00130   int i = p0_i, j = p0_j;
00131   const T* p = &image(i,j);
00132   assert(*p>=threshold);
00133 
00134   // Move to extremal point on boundary
00135   while (i<ni1 && p[istep]>=threshold) {i++;p+=istep;}
00136   int dir = 1;
00137 
00138   if (i==p0_i)
00139   {
00140     // Initial point already on boundary - move to extreme j
00141     while (j<nj1 && p[jstep]>=threshold) {j++;p+=jstep;}
00142     dir = 2;
00143   }
00144 
00145   int i0 = i, j0=j;
00146 
00147   do
00148   {
00149     bi.push_back(i); bj.push_back(j);
00150     vil_next_point_above_thresh4(i,j,dir,p,ni1,nj1,istep,jstep,threshold);
00151   }
00152   while (i!=i0 || j!=j0);
00153 }
00154 
00155 #endif // vil_find_4con_boundary_h_