core/vil/algo/vil_trace_4con_boundary.cxx

Go to the documentation of this file.
00001 //:
00002 // \file
00003 // \brief Function to trace 4-connected boundary around region in bool image
00004 // \author Tim Cootes
00005 
00006 #include "vil_trace_4con_boundary.h"
00007 
00008 //: Move (i,j) to next boundary point
00009 //  Start looking in direction dir (0=++x,1=++y,2=--x,3=--y)
00010 //  *p is current point (i,j).
00011 //  On exit (i,j) and p are updated to move to neighbour
00012 inline void vil_next_4con_boundary_point(int& i,int& j,int& dir, const bool* &p,
00013                                          int ni1, int nj1,
00014                                          vcl_ptrdiff_t istep, vcl_ptrdiff_t jstep)
00015 {
00016   for (int k=0;k<4;++k)
00017   {
00018     switch ((dir+k)%4)
00019     {
00020       case (0):   // Try at (i+1,j)
00021         if (i<ni1 && p[istep]) { ++i; p+=istep; dir=3; return; }
00022       case (1):   // Try at (i,j+1)
00023         if (j<nj1 && p[jstep]) { ++j; p+=jstep; dir=0; return; }
00024       case (2):   // Try at (i-1,j)
00025         if (i>0 && p[-istep])  { --i; p-=istep; dir=1; return; }
00026       case (3):   // Try at (i,j-1)
00027         if (j>0 && p[-jstep])  { --j; p-=jstep; dir=2; return; }
00028       default:
00029         break;
00030     }
00031   }
00032 }
00033 
00034 static inline int vil_first_direction(unsigned int i, unsigned int j, const vil_image_view<bool>& image)
00035 {
00036   if (i>=image.ni() || j>=image.nj() || !image(i,j)) return -1;
00037 
00038   // Find first neighbour outside
00039   if (i+1>=image.ni() || !image(i+1,j)) return 0;
00040   if (j+1>=image.nj() || !image(i,j+1)) return 1;
00041   if (i==0 || !image(i-1,j)) return 2;
00042   if (j==0 || !image(i,j-1)) return 3;
00043 
00044   return -1; // No neighbours are outside
00045 }
00046 
00047 
00048 //: Trace 4-connected boundary around region in boolean image
00049 //  Assumes that (i0,j0) is a boundary point.
00050 //  Searches for the boundary pixels and runs around until it gets back to beginning.
00051 //  On exit the boundary points are given by (bi[k],bj[k])
00052 void vil_trace_4con_boundary(vcl_vector<int>& bi, vcl_vector<int>& bj,
00053                              const vil_image_view<bool>& image,
00054                              int i0, int j0)
00055 {
00056   bi.resize(0); bj.resize(0);
00057   unsigned int ni1 = image.ni()-1;
00058   unsigned int nj1 = image.nj()-1;
00059   vcl_ptrdiff_t istep = image.istep(), jstep=image.jstep();
00060 
00061   int i = i0, j = j0;
00062   const bool* p = &image(i,j);
00063 
00064   // Check that p is a boundary pixel
00065   int dir = vil_first_direction(i,j,image);
00066 
00067   if (dir<0) return;  // Not a boundary point!
00068 
00069   do
00070   {
00071     bi.push_back(i); bj.push_back(j);
00072     vil_next_4con_boundary_point(i,j,dir,p,ni1,nj1,istep,jstep);
00073   }
00074   while (i!=i0 || j!=j0);
00075 
00076   if (bi.size()==1) return;  // Isolated pixel (how sad).
00077 
00078   // Got back to start.
00079   // However, if start is part of a 1 pixel wide line, we need to
00080   // investigate the other side of the line
00081   // To check for this, find the next boundary point and check that it
00082   // is the same as was found during the first pass
00083   vil_next_4con_boundary_point(i,j,dir,p,ni1,nj1,istep,jstep);
00084   if (i!=bi[1] || j!=bj[1])
00085   {
00086     // Second pass is different from first
00087     // Investigate the other side of the blob
00088     bi.push_back(i0); bj.push_back(j0);
00089     do
00090     {
00091       bi.push_back(i); bj.push_back(j);
00092       vil_next_4con_boundary_point(i,j,dir,p,ni1,nj1,istep,jstep);
00093     }
00094     while (i!=i0 || j!=j0);
00095   }
00096 }

Generated on Mon Mar 8 05:08:45 2010 for core/vil by  doxygen 1.5.1