00001
00002
00003
00004
00005
00006 #include "vil_trace_8con_boundary.h"
00007
00008
00009
00010
00011
00012 inline void vil_next_8con_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<8;++k)
00017 {
00018 switch ((dir+k)%8)
00019 {
00020 case 0:
00021 if (i<ni1 && p[istep]) { ++i; p+=istep; dir=5; return; }
00022 case 1:
00023 if (i<ni1 && j<nj1 && p[istep+jstep]) {
00024 ++i; ++j; p+=(istep+jstep); dir=6; return; }
00025 case 2:
00026 if (j<nj1 && p[jstep]) { ++j; p+=jstep; dir=7; return; }
00027 case 3:
00028 if (i>0 && j<nj1 && p[jstep-istep]) {
00029 --i; ++j; p+=(jstep-istep); dir=0; return; }
00030 case 4:
00031 if (i>0 && p[-istep]) { --i; p-=istep; dir=1; return; }
00032 case 5:
00033 if (i>0 && j>0 && p[-jstep-istep]) {
00034 --i; --j; p+=(-jstep-istep); dir=2; return; }
00035 case 6:
00036 if (j>0 && p[-jstep]) { --j; p-=jstep; dir=3; return; }
00037 case 7:
00038 if (i<ni1 && j>0 && p[istep-jstep]) {
00039 ++i; --j; p+=(istep-jstep); dir=4; return; }
00040 default:
00041 break;
00042 }
00043 }
00044 }
00045
00046 static inline int vil_first_direction(unsigned int i, unsigned int j, const vil_image_view<bool>& image)
00047 {
00048 if (i>=image.ni() || j>=image.nj() || !image(i,j)) return -1;
00049
00050
00051
00052
00053 if (i+1>=image.ni()) return 0;
00054 if (j+1>=image.nj()) return 2;
00055 if (i==0) return 4;
00056 if (j==0) return 6;
00057
00058 if (!image(i+1,j)) return 0;
00059 if (!image(i+1,j+1)) return 1;
00060 if (!image(i,j+1)) return 2;
00061 if (!image(i-1,j+1)) return 3;
00062 if (!image(i-1,j)) return 4;
00063 if (!image(i-1,j-1)) return 5;
00064 if (!image(i,j-1)) return 6;
00065 if (!image(i+1,j-1)) return 7;
00066
00067 return -1;
00068 }
00069
00070
00071
00072
00073
00074
00075 void vil_trace_8con_boundary(vcl_vector<int>& bi, vcl_vector<int>& bj,
00076 const vil_image_view<bool>& image,
00077 int i0, int j0)
00078 {
00079 bi.resize(0); bj.resize(0);
00080 unsigned int ni1 = image.ni()-1;
00081 unsigned int nj1 = image.nj()-1;
00082 vcl_ptrdiff_t istep = image.istep(), jstep=image.jstep();
00083
00084 int i = i0, j = j0;
00085 const bool* p = &image(i,j);
00086
00087
00088 int dir = vil_first_direction(i,j,image);
00089
00090 if (dir<0) return;
00091
00092 do
00093 {
00094 bi.push_back(i); bj.push_back(j);
00095 vil_next_8con_boundary_point(i,j,dir,p,ni1,nj1,istep,jstep);
00096 }
00097 while (i!=i0 || j!=j0);
00098
00099 if (bi.size()==1) return;
00100
00101
00102
00103
00104
00105
00106
00107 vil_next_8con_boundary_point(i,j,dir,p,ni1,nj1,istep,jstep);
00108 while (i!=bi[1] || j!=bj[1])
00109 {
00110
00111
00112 bi.push_back(i0); bj.push_back(j0);
00113 do
00114 {
00115 bi.push_back(i); bj.push_back(j);
00116 vil_next_8con_boundary_point(i,j,dir,p,ni1,nj1,istep,jstep);
00117 }
00118 while (i!=i0 || j!=j0);
00119
00120 vil_next_8con_boundary_point(i,j,dir,p,ni1,nj1,istep,jstep);
00121 }
00122 }