DGtalTools  0.9.2
volCComponentCounter.cpp
1 
29 #include <iostream>
31 
32 #include "DGtal/base/Common.h"
33 #include "DGtal/io/readers/VolReader.h"
34 #include "DGtal/io/Color.h"
35 #include "DGtal/images/ImageSelector.h"
36 #include "DGtal/helpers/StdDefs.h"
37 
38 #include <boost/pending/disjoint_sets.hpp>
39 #include <boost/program_options/options_description.hpp>
40 #include <boost/program_options/parsers.hpp>
41 #include <boost/program_options/variables_map.hpp>
42 
43 
44 using namespace std;
45 using namespace DGtal;
46 using namespace Z3i;
47 
49 namespace po = boost::program_options;
50 
51 
90 template <typename Rank, typename Parent, typename Image>
91 void CCCounter(Rank& r, Parent& p, const Image& elements, const unsigned int connectivity)
92 {
93 
94  boost::disjoint_sets<Rank,Parent> dsets(r, p);
95  trace.beginBlock("Initial disjoint sets construction");
96  for(typename Image::Domain::ConstIterator e = elements.domain().begin();
97  e != elements.domain().end(); ++e)
98  dsets.make_set(*e);
99  trace.endBlock();
100 
101  trace.beginBlock("Merging neighboring sets");
102  typename Image::Point decx(1,0,0);
103  typename Image::Point decy(0,1,0);
104  typename Image::Point decz(0,0,1);
105 
106  //Merging process
107  for(typename Image::Domain::ConstIterator e = elements.domain().begin();
108  e !=elements.domain().end(); ++e)
109  {
110  if ( elements.domain().isInside(*e+decx) &&
111  (elements(*e) == elements(*e+decx)))
112  dsets.union_set(*e,*e+decx);
113 
114  if ( elements.domain().isInside(*e+decy) &&
115  (elements(*e) == elements(*e+decy)))
116  dsets.union_set(*e,*e+decy);
117 
118  if ( elements.domain().isInside(*e+decz) &&
119  (elements(*e) == elements(*e+decz)))
120  dsets.union_set(*e,*e+decz);
121 
122  if (connectivity > 6)
123  {
124  if ( elements.domain().isInside(*e+decx+decy) &&
125  (elements(*e) == elements(*e+decx+decy)))
126  dsets.union_set(*e,*e+decx+decy);
127 
128  if ( elements.domain().isInside(*e+decx+decz) &&
129  (elements(*e) == elements(*e+decx+decz)))
130  dsets.union_set(*e,*e+decx+decz);
131 
132  if ( elements.domain().isInside(*e+decy+decz) &&
133  (elements(*e) == elements(*e+decy+decz)))
134  dsets.union_set(*e,*e+decy+decz);
135 
136  if (connectivity == 26)
137  if ( elements.domain().isInside(*e+decy+decz+decx) &&
138  (elements(*e) == elements(*e+decy+decz+decx)))
139  dsets.union_set(*e,*e+decy+decz+decx);
140 
141  }
142 
143  }
144  trace.endBlock();
145  std::cout << "Number of disjoint "<<connectivity<<"-components = "
146  <<dsets.count_sets(elements.domain().begin(),
147  elements.domain().end())
148  << std::endl;
149 }
150 
151 
152 
153 int main( int argc, char** argv )
154 {
155  // parse command line ----------------------------------------------
156  po::options_description general_opt("Allowed options are");
157  general_opt.add_options()
158  ("help,h", "display this message")
159  ("connectivity,c", po::value<unsigned int>()->default_value(6), "object connectivity (6,18,26)" " (default: 6 )")
160  ("input,i", po::value<std::string>(), "volume file (Vol)" " (default: standard input)");
161  bool parseOK=true;
162  po::variables_map vm;
163  try{
164  po::store(po::parse_command_line(argc, argv, general_opt), vm);
165  }catch(const std::exception& ex){
166  parseOK=false;
167  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
168  }
169  po::notify(vm);
170  if( !parseOK || vm.count("help")||argc<=1)
171  {
172  std::cout << "Usage: " << argv[0] << " [input]\n"
173  << "Count the number of connected component (same values) in a volume (Vol) file image\n"
174  << general_opt << "\n"
175  << "Example : \n \t volCComponentCounter -i $DGtal/examples/samples/Al.100.vol ";
176  return 0;
177  }
178  string inputFilename = vm["input"].as<std::string>();
179  unsigned int connectivity = vm["connectivity"].as<unsigned int>();
180 
181  if ((connectivity != 6) && (connectivity != 18) && (connectivity != 26))
182  {
183  trace.error() << "Bad connectivity value.";
184  trace.info() << std::endl;
185  exit(1);
186  }
187 
188  typedef ImageSelector<Domain, unsigned char>::Type Image;
189  Image image = VolReader<Image>::importVol( inputFilename );
190 
191  trace.info() << "Image loaded: "<<image<< std::endl;
192 
193  typedef std::map<Point,std::size_t> rank_t; // => order on Element
194  typedef std::map<Point,Point> parent_t;
195  rank_t rank_map;
196  parent_t parent_map;
197 
198  boost::associative_property_map<rank_t> rank_pmap(rank_map);
199  boost::associative_property_map<parent_t> parent_pmap(parent_map);
200 
201  CCCounter(rank_pmap, parent_pmap, image, connectivity);
202 
203 
204  return 0;
205 }
STL namespace.