00001
00002 #include "vil3d_find_blobs.h"
00003
00004
00005
00006
00007
00008 #include <vcl_vector.h>
00009 #include <vcl_cassert.h>
00010 #include <vcl_algorithm.h>
00011
00012 #include <vil3d/vil3d_image_view.h>
00013
00014
00015
00016 void vil3d_find_blobs(const vil3d_image_view<bool>& src,
00017 vil3d_find_blob_connectivity conn,
00018 vil3d_image_view<unsigned>& dst)
00019 {
00020 unsigned ni=src.ni();
00021 unsigned nj=src.nj();
00022 unsigned nk=src.nk();
00023 dst.set_size(ni, nj, nk);
00024 dst.fill(0);
00025
00026 vcl_vector<unsigned> renumbering(1u, 0u);
00027 vcl_vector<unsigned> neighbouring_labels;
00028
00029 unsigned n_neighbours;
00030 switch (conn)
00031 {
00032 case vil3d_find_blob_connectivity_6_conn:
00033 n_neighbours=3;
00034 break;
00035 case vil3d_find_blob_connectivity_26_conn:
00036 n_neighbours=13;
00037 break;
00038 default:
00039 n_neighbours=0; assert(!"unknown connectivity");
00040 }
00041
00042
00043
00044 int neighbourhood_ii[] = { -1, 0, 0, -1, 0, +1, -1, +1, -1, 0, +1, -1, +1};
00045 int neighbourhood_jj[] = { 0, -1, 0, -1, -1, -1, 0, 0, +1, +1, +1, -1, -1};
00046 int neighbourhood_kk[] = { 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0};
00047
00048 typedef vcl_vector<unsigned>::iterator ITER;
00049
00050 for (unsigned k=0; k<nk; ++k)
00051 for (unsigned j=0; j<nj; ++j)
00052 for (unsigned i=0; i<ni; ++i)
00053 {
00054 if (!src(i,j,k)) continue;
00055 neighbouring_labels.clear();
00056 for (unsigned l=0; l<n_neighbours; ++l)
00057 {
00058 unsigned ii = i + neighbourhood_ii[l];
00059 if (ii >= ni) continue;
00060 unsigned jj = j + neighbourhood_jj[l];
00061 if (jj >= ni) continue;
00062 unsigned kk = k + neighbourhood_kk[l];
00063 if (kk >= nk) continue;
00064 unsigned d = dst(ii,jj,kk);
00065 if (d==0) continue;
00066 neighbouring_labels.push_back(d);
00067 }
00068 if (neighbouring_labels.empty())
00069 {
00070 unsigned new_label = renumbering.size();
00071 dst(i,j,k) = new_label;
00072 renumbering.push_back(new_label);
00073 }
00074 else
00075 {
00076
00077 vcl_sort(neighbouring_labels.begin(), neighbouring_labels.end());
00078 ITER end = vcl_unique(neighbouring_labels.begin(), neighbouring_labels.end());
00079
00080
00081 ITER it=neighbouring_labels.begin();
00082 unsigned label = *it++;
00083 dst(i,j,k) = label;
00084
00085
00086
00087
00088
00089 for (; it!=end; ++it)
00090 renumbering[*it] = vcl_min(renumbering[*it], label);
00091 }
00092 }
00093
00094
00095
00096 for (ITER it=renumbering.begin(), end=renumbering.end(); it!=end; ++it)
00097 *it = renumbering[*it];
00098
00099
00100
00101 vcl_vector<unsigned> labels(renumbering.begin(), renumbering.end());
00102 vcl_sort(labels.begin(), labels.end());
00103 labels.erase(vcl_unique(labels.begin(), labels.end()), labels.end());
00104 const unsigned dodgy = static_cast<unsigned>(-1);
00105 vcl_vector<unsigned> renum_renum(renumbering.size(), dodgy);
00106 renum_renum[0]=0;
00107 for (unsigned l=0, n=labels.size(); l<n; ++l)
00108 renum_renum[labels[l]] = l;
00109
00110 for (ITER it=renumbering.begin(), end=renumbering.end(); it!=end; ++it)
00111 *it=renum_renum[*it];
00112
00113
00114 assert(vcl_find(renumbering.begin(), renumbering.end(), dodgy)
00115 == renumbering.end() );
00116
00117
00118
00119 for (unsigned k=0; k<nk; ++k)
00120 for (unsigned j=0; j<nj; ++j)
00121 for (unsigned i=0; i<ni; ++i)
00122 dst(i,j,k) = renumbering[dst(i,j,k)];
00123 }
00124