00001
00002
00003
00004
00005
00006 #include "vil_blob_finder.h"
00007 #include "vil_trace_4con_boundary.h"
00008 #include "vil_trace_8con_boundary.h"
00009 #include "vil_flood_fill.h"
00010
00011
00012 vil_blob_finder::vil_blob_finder()
00013 : i_((unsigned int)(-1)),j_((unsigned int)(-1)) {}
00014
00015
00016 vil_blob_finder::vil_blob_finder(const vil_image_view<bool>& image)
00017 : i_(0),j_(0)
00018 {
00019 image_.deep_copy(image);
00020 }
00021
00022
00023 void vil_blob_finder::set_image(const vil_image_view<bool>& image)
00024 {
00025 i_=0; j_=0;
00026 image_.deep_copy(image);
00027 }
00028
00029
00030
00031 void vil_blob_finder::set_work_image(vil_image_view<bool>& image)
00032 {
00033 i_=0; j_=0;
00034 image_ = image;
00035 }
00036
00037
00038 void delete_blob(vil_image_view<bool>& image,
00039 const vcl_vector<int>& bi, const vcl_vector<int>& bj)
00040 {
00041 const unsigned n = bi.size();
00042 const unsigned ni = image.ni();
00043 for (unsigned k=0;k<n;++k)
00044 {
00045 int j = bj[k];
00046
00047
00048 unsigned int i = bi[k];
00049 while (i<ni && image(i,j)) image(i++,j)=false;
00050
00051
00052 i=bi[k];
00053 while (i>0 && image(i-1,j)) image(--i,j)=false;
00054 }
00055 }
00056
00057
00058
00059
00060 bool vil_blob_finder::next_4con_region(vcl_vector<int>& bi, vcl_vector<int>& bj)
00061 {
00062
00063 for (; j_<image_.nj(); ++j_,i_=0)
00064 {
00065 for (; i_<image_.ni(); ++i_)
00066 {
00067 if (image_(i_,j_))
00068 {
00069 vil_trace_4con_boundary(bi,bj,image_,i_,j_);
00070
00071 vil_flood_fill4(image_,bi[0],bj[0],true,false);
00072 return true;
00073 }
00074 }
00075 }
00076
00077 return false;
00078 }
00079
00080
00081
00082
00083 bool vil_blob_finder::next_4con_region(vcl_vector<vil_chord>& region)
00084 {
00085 region.resize(0);
00086
00087 for (; j_<image_.nj(); ++j_,i_=0)
00088 {
00089 for (; i_<image_.ni(); ++i_)
00090 {
00091 if (image_(i_,j_))
00092 {
00093
00094 vil_flood_fill4(image_,i_,j_,true,false,region);
00095 return true;
00096 }
00097 }
00098 }
00099
00100 return false;
00101 }
00102
00103
00104
00105
00106 bool vil_blob_finder::next_8con_region(vcl_vector<vil_chord>& region)
00107 {
00108 region.resize(0);
00109
00110 for (; j_<image_.nj(); ++j_,i_=0)
00111 {
00112 for (; i_<image_.ni(); ++i_)
00113 {
00114 if (image_(i_,j_))
00115 {
00116
00117 vil_flood_fill8(image_,i_,j_,true,false,region);
00118 return true;
00119 }
00120 }
00121 }
00122
00123 return false;
00124 }
00125
00126
00127
00128
00129
00130 void vil_blob_finder::longest_4con_boundary(vcl_vector<int>& bi, vcl_vector<int>& bj)
00131 {
00132 bi.resize(0); bj.resize(0);
00133 vcl_vector<int> tmp_bi,tmp_bj;
00134 while (next_4con_region(tmp_bi,tmp_bj))
00135 {
00136 if (tmp_bi.size()>bi.size())
00137 {
00138 vcl_swap(bi,tmp_bi);
00139 vcl_swap(bj,tmp_bj);
00140 }
00141 }
00142 }
00143
00144
00145 unsigned vil_blob_finder::n_4con_regions(const vil_image_view<bool>& image)
00146 {
00147 set_image(image);
00148 unsigned n=0;
00149 vcl_vector<int> tmp_bi,tmp_bj;
00150 while (next_4con_region(tmp_bi,tmp_bj)) n++;
00151 return n;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160 bool vil_blob_finder::next_8con_region(vcl_vector<int>& bi, vcl_vector<int>& bj)
00161 {
00162
00163 for (; j_<image_.nj(); ++j_,i_=0)
00164 {
00165 for (; i_<image_.ni(); ++i_)
00166 {
00167 if (image_(i_,j_))
00168 {
00169 vil_trace_8con_boundary(bi,bj,image_,i_,j_);
00170
00171 vil_flood_fill8(image_,bi[0],bj[0],true,false);
00172 return true;
00173 }
00174 }
00175 }
00176
00177 return false;
00178 }
00179
00180
00181
00182
00183
00184 void vil_blob_finder::longest_8con_boundary(vcl_vector<int>& bi, vcl_vector<int>& bj)
00185 {
00186 bi.resize(0); bj.resize(0);
00187 vcl_vector<int> tmp_bi,tmp_bj;
00188 while (next_8con_region(tmp_bi,tmp_bj))
00189 {
00190 if (tmp_bi.size()>bi.size())
00191 {
00192 vcl_swap(bi,tmp_bi);
00193 vcl_swap(bj,tmp_bj);
00194 }
00195 }
00196 }
00197
00198
00199 unsigned vil_blob_finder::largest_8con_region(vcl_vector<vil_chord>& region)
00200 {
00201 region.resize(0);
00202 vcl_vector<vil_chord> tmp_region;
00203 unsigned max_area=0;
00204 while (next_8con_region(tmp_region))
00205 {
00206 unsigned area = vil_area(tmp_region);
00207 if (area>max_area)
00208 {
00209 vcl_swap(region,tmp_region);
00210 max_area=area;
00211 }
00212 }
00213 return max_area;
00214 }
00215
00216
00217 unsigned vil_blob_finder::largest_4con_region(vcl_vector<vil_chord>& region)
00218 {
00219 region.resize(0);
00220 vcl_vector<vil_chord> tmp_region;
00221 unsigned max_area=0;
00222 while (next_4con_region(tmp_region))
00223 {
00224 unsigned area = vil_area(tmp_region);
00225 if (area>max_area)
00226 {
00227 vcl_swap(region,tmp_region);
00228 max_area=area;
00229 }
00230 }
00231 return max_area;
00232 }
00233
00234
00235 unsigned vil_blob_finder::n_8con_regions(const vil_image_view<bool>& image)
00236 {
00237 set_image(image);
00238 unsigned n=0;
00239 vcl_vector<int> tmp_bi,tmp_bj;
00240 while (next_8con_region(tmp_bi,tmp_bj)) n++;
00241 return n;
00242 }
00243
00244