vil_find_4con_boundary.h
Go to the documentation of this file.
1 #ifndef vil_find_4con_boundary_h_
2 #define vil_find_4con_boundary_h_
3 
4 #include <vector>
5 #include <vil/vil_image_view.h>
6 #include <cassert>
7 #ifdef _MSC_VER
8 # include <vcl_msvc_warnings.h>
9 #endif
10 
11 //:
12 // \file
13 // \brief Function to find 4-connected boundary around thresholded region
14 // \author Tim Cootes
15 
16 //: Move (i,j) to next point below threshold
17 // Start looking in direction dir (0=++x,1=++y,2=--x,3=--y)
18 // *p is current point (i,j).
19 // On exit (i,j) and p are updated to move to neighbour
20 template<class T>
21 inline void vil_next_point_below_thresh4(int& i,int& j,int& dir, const T* &p,
22  int ni1, int nj1,
23  std::ptrdiff_t istep,std::ptrdiff_t jstep,
24  T threshold)
25 {
26  for (int k=0;k<4;++k)
27  {
28  switch ((dir+k)%4)
29  {
30  case 0: // Try at (i+1,j)
31  if (i<ni1 && p[istep]<=threshold) { ++i; p+=istep; dir=3; return; }
32  case 1: // Try at (i,j+1)
33  if (j<nj1 && p[jstep]<=threshold) { ++j; p+=jstep; dir=0; return; }
34  case 2: // Try at (i-1,j)
35  if (i>0 && p[-istep]<=threshold) { --i; p-=istep; dir=1; return; }
36  case 3: // Try at (i,j-1)
37  if (j>0 && p[-jstep]<=threshold) { --j; p-=jstep; dir=2; return; }
38  default:
39  break;
40  }
41  }
42 }
43 
44 //: Move (i,j) to next point above threshold
45 // Start looking in direction dir (0=++x,1=++y,2=--x,3=--y)
46 // *p is current point (i,j).
47 // On exit (i,j) and p are updated to move to neighbour
48 template<class T>
49 inline void vil_next_point_above_thresh4(int& i,int& j,int& dir, const T* &p,
50  int ni1, int nj1, std::ptrdiff_t istep, std::ptrdiff_t jstep,
51  T threshold)
52 {
53  for (int k=0;k<4;++k)
54  {
55  switch ((dir+k)%4)
56  {
57  case (0): // Try at (i+1,j)
58  if (i<ni1 && p[istep]>=threshold) { ++i; p+=istep; dir=3; return; }
59  case (1): // Try at (i,j+1)
60  if (j<nj1 && p[jstep]>=threshold) { ++j; p+=jstep; dir=0; return; }
61  case (2): // Try at (i-1,j)
62  if (i>0 && p[-istep]>=threshold) { --i; p-=istep; dir=1; return; }
63  case (3): // Try at (i,j-1)
64  if (j>0 && p[-jstep]>=threshold) { --j; p-=jstep; dir=2; return; }
65  default:
66  break;
67  }
68  }
69 }
70 
71 
72 //: Find 4-connected boundary around thresholded region containing point
73 // Assumes that (p0_i,p0_j) is a point in the image which satisfies
74 // the threshold (ie image(p0_i,p0_j)<=threshold).
75 // Searches for the boundary pixels (ie points which satisfy threshold
76 // next to ones which don't) and runs around until it gets back to beginning.
77 // On exit the boundary points are given by (bi[k],bj[k])
78 template <class T>
79 inline void vil_find_4con_boundary_below_threshold(std::vector<int>& bi,
80  std::vector<int>& bj,
81  const vil_image_view<T>& image,
82  const T& threshold,
83  int p0_i, int p0_j)
84 {
85  bi.resize(0); bj.resize(0);
86  int ni1 = image.ni()-1;
87  int nj1 = image.nj()-1;
88  std::ptrdiff_t istep = image.istep(), jstep=image.jstep();
89 
90  int i = p0_i, j = p0_j;
91  const T* p = &image(i,j);
92  assert(*p<=threshold);
93 
94  // Move to extremal point on boundary
95  while (i<ni1 && p[istep]<=threshold) {i++;p+=istep;}
96  int dir = 1;
97 
98  if (i==p0_i)
99  {
100  // Initial point already on boundary - move to extreme j
101  while (j<nj1 && p[jstep]<=threshold) {j++;p+=jstep;}
102  dir = 2;
103  }
104 
105  int i0 = i, j0=j;
106 
107  do
108  {
109  bi.push_back(i); bj.push_back(j);
110  vil_next_point_below_thresh4(i,j,dir,p,ni1,nj1,istep,jstep,threshold);
111  }
112  while (i!=i0 || j!=j0);
113 }
114 
115 //: Find 4-connected boundary around thresholded region containing point
116 // Assumes that (p0_i,p0_j) is a point in the image which satisfies
117 // the threshold (ie image(p0_i,p0_j)>=threshold).
118 // Searches for the boundary pixels (ie points which satisfy threshold
119 // next to ones which don't) and runs around until it gets back to beginning.
120 // On exit the boundary points are given by (bi[k],bj[k])
121 template <class T>
122 inline void vil_find_4con_boundary_above_threshold(std::vector<int>& bi,
123  std::vector<int>& bj,
124  const vil_image_view<T>& image,
125  const T& threshold,
126  int p0_i, int p0_j)
127 {
128  bi.resize(0); bj.resize(0);
129  int ni1 = image.ni()-1;
130  int nj1 = image.nj()-1;
131  std::ptrdiff_t istep = image.istep(), jstep=image.jstep();
132 
133  int i = p0_i, j = p0_j;
134  const T* p = &image(i,j);
135  assert(*p>=threshold);
136 
137  // Move to extremal point on boundary
138  while (i<ni1 && p[istep]>=threshold) {i++;p+=istep;}
139  int dir = 1;
140 
141  if (i==p0_i)
142  {
143  // Initial point already on boundary - move to extreme j
144  while (j<nj1 && p[jstep]>=threshold) {j++;p+=jstep;}
145  dir = 2;
146  }
147 
148  int i0 = i, j0=j;
149 
150  do
151  {
152  bi.push_back(i); bj.push_back(j);
153  vil_next_point_above_thresh4(i,j,dir,p,ni1,nj1,istep,jstep,threshold);
154  }
155  while (i!=i0 || j!=j0);
156 }
157 
158 #endif // vil_find_4con_boundary_h_
Concrete view of image data of type T held in memory.
Definition: vil_fwd.h:13
void vil_next_point_below_thresh4(int &i, int &j, int &dir, const T *&p, int ni1, int nj1, std::ptrdiff_t istep, std::ptrdiff_t jstep, T threshold)
Move (i,j) to next point below threshold.
void vil_find_4con_boundary_below_threshold(std::vector< int > &bi, std::vector< int > &bj, const vil_image_view< T > &image, const T &threshold, int p0_i, int p0_j)
Find 4-connected boundary around thresholded region containing point.
std::ptrdiff_t jstep() const
Add this to your pixel pointer to get next j pixel.
unsigned ni() const
Width.
unsigned nj() const
Height.
void vil_next_point_above_thresh4(int &i, int &j, int &dir, const T *&p, int ni1, int nj1, std::ptrdiff_t istep, std::ptrdiff_t jstep, T threshold)
Move (i,j) to next point above threshold.
void vil_find_4con_boundary_above_threshold(std::vector< int > &bi, std::vector< int > &bj, const vil_image_view< T > &image, const T &threshold, int p0_i, int p0_j)
Find 4-connected boundary around thresholded region containing point.
A base class reference-counting view of some image data.
std::ptrdiff_t istep() const
Add this to your pixel pointer to get next i pixel.