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 namespace
00015 {
00016
00017
00018
00019 class disjoint_sets
00020 {
00021 typedef unsigned LABEL;
00022 typedef unsigned LEN;
00023 struct node
00024 {
00025 LABEL parent;
00026 LEN rank;
00027 };
00028 vcl_vector<node> store_;
00029 public:
00030 disjoint_sets(): store_(1u)
00031 {
00032 store_.front().parent=0;
00033 store_.front().rank=0;
00034 }
00035
00036
00037 LABEL root(LABEL v)
00038 {
00039 node & n=store_[v];
00040 if (n.parent == v)
00041 return v;
00042 else
00043 {
00044 n.parent=root(n.parent);
00045 return n.parent;
00046 }
00047 }
00048
00049
00050 void merge_labels(LABEL left_label, LABEL right_label)
00051 {
00052 LABEL left_root = root(left_label);
00053 LABEL right_root = root(right_label);
00054 if (left_root == right_root) return;
00055 node& left_root_node = store_[left_root];
00056 node& right_root_node = store_[right_root];
00057 if (left_root_node.rank > right_root_node.rank)
00058 {
00059 right_root_node.parent = left_root_node.parent;
00060 }
00061 else
00062 {
00063 left_root_node.parent = right_root_node.parent;
00064 if (left_root_node.rank == right_root_node.rank)
00065 right_root_node.rank++;
00066 }
00067 }
00068
00069
00070 LABEL new_label()
00071 {
00072 node n = {(LABEL)store_.size(), 0};
00073 store_.push_back(n);
00074 return n.parent;
00075 }
00076
00077 LEN size()
00078 {
00079 return store_.size();
00080 }
00081 };
00082 }
00083
00084
00085 void vil3d_find_blobs(const vil3d_image_view<bool>& src,
00086 vil3d_find_blob_connectivity conn,
00087 vil3d_image_view<unsigned>& dst)
00088 {
00089 unsigned ni=src.ni();
00090 unsigned nj=src.nj();
00091 unsigned nk=src.nk();
00092 dst.set_size(ni, nj, nk);
00093 dst.fill(0);
00094
00095 disjoint_sets merge_list;
00096 vcl_vector<unsigned> neighbouring_labels;
00097
00098 unsigned n_neighbours;
00099 switch (conn)
00100 {
00101 case vil3d_find_blob_connectivity_6_conn:
00102 n_neighbours=3;
00103 break;
00104 case vil3d_find_blob_connectivity_26_conn:
00105 n_neighbours=13;
00106 break;
00107 default:
00108 n_neighbours=0; assert(!"unknown connectivity");
00109 }
00110
00111
00112
00113 int neighbourhood_ii[] = { -1, 0, 0, -1, 0, +1, -1, +1, -1, 0, +1, -1, +1};
00114 int neighbourhood_jj[] = { 0, -1, 0, -1, -1, -1, 0, 0, +1, +1, +1, -1, -1};
00115 int neighbourhood_kk[] = { 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0};
00116
00117 typedef vcl_vector<unsigned>::iterator ITER;
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 {
00123 if (!src(i,j,k)) continue;
00124 neighbouring_labels.clear();
00125 for (unsigned l=0; l<n_neighbours; ++l)
00126 {
00127 unsigned ii = i + neighbourhood_ii[l];
00128 if (ii >= ni) continue;
00129 unsigned jj = j + neighbourhood_jj[l];
00130 if (jj >= nj) continue;
00131 unsigned kk = k + neighbourhood_kk[l];
00132 if (kk >= nk) continue;
00133 unsigned d = dst(ii,jj,kk);
00134 if (d==0) continue;
00135 neighbouring_labels.push_back(d);
00136 }
00137 if (neighbouring_labels.empty())
00138 {
00139 unsigned new_label = merge_list.new_label();
00140 dst(i,j,k) = new_label;
00141 }
00142 else
00143 {
00144
00145 vcl_sort(neighbouring_labels.begin(), neighbouring_labels.end());
00146 ITER end = vcl_unique(neighbouring_labels.begin(), neighbouring_labels.end());
00147
00148
00149 ITER it=neighbouring_labels.begin();
00150 unsigned label = *it++;
00151 dst(i,j,k) = label;
00152
00153
00154
00155
00156
00157 for (; it!=end; ++it)
00158 merge_list.merge_labels(*it, label);
00159 }
00160 }
00161
00162 unsigned n_merge=merge_list.size();
00163 vcl_vector<unsigned> renumbering(n_merge, 0u);
00164
00165
00166
00167 for (unsigned l=1; l<n_merge; ++l)
00168 {
00169 if (renumbering[l]!=0) continue;
00170 unsigned root_label = merge_list.root(l);
00171 unsigned root_label_renumber = renumbering[root_label];
00172 if (root_label_renumber==0)
00173 {
00174 renumbering[root_label]=l;
00175 renumbering[l]=l;
00176 }
00177 else
00178 renumbering[l]=renumbering[root_label];
00179 }
00180
00181
00182
00183 vcl_vector<unsigned> labels(renumbering.begin(), renumbering.end());
00184 vcl_sort(labels.begin(), labels.end());
00185 labels.erase(vcl_unique(labels.begin(), labels.end()), labels.end());
00186 const unsigned dodgy = static_cast<unsigned>(-1);
00187 vcl_vector<unsigned> renum_renum(renumbering.size(), dodgy);
00188 renum_renum[0]=0;
00189 for (unsigned l=0, n=labels.size(); l<n; ++l)
00190 renum_renum[labels[l]] = l;
00191
00192 for (ITER it=renumbering.begin(), end=renumbering.end(); it!=end; ++it)
00193 *it=renum_renum[*it];
00194
00195
00196 assert(vcl_find(renumbering.begin(), renumbering.end(), dodgy)
00197 == renumbering.end() );
00198
00199
00200
00201 for (unsigned k=0; k<nk; ++k)
00202 for (unsigned j=0; j<nj; ++j)
00203 for (unsigned i=0; i<ni; ++i)
00204 dst(i,j,k) = renumbering[dst(i,j,k)];
00205 }
00206