DGtalTools  0.9.4
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  trace.endBlock();
143  std::cout << "Number of disjoint "<<connectivity<<"-components = "
144  <<dsets.count_sets(elements.domain().begin(),
145  elements.domain().end())
146  << std::endl;
147 }
148 
149 
150 
151 int main( int argc, char** argv )
152 {
153  // parse command line ----------------------------------------------
154  po::options_description general_opt("Allowed options are");
155  general_opt.add_options()
156  ("help,h", "display this message")
157  ("connectivity,c", po::value<unsigned int>()->default_value(6), "object connectivity (6,18,26)" " (default: 6 )")
158  ("input,i", po::value<std::string>(), "volume file (Vol)" " (default: standard input)");
159  bool parseOK=true;
160  po::variables_map vm;
161  try{
162  po::store(po::parse_command_line(argc, argv, general_opt), vm);
163  }catch(const std::exception& ex){
164  parseOK=false;
165  trace.info()<< "Error checking program options: "<< ex.what()<< endl;
166  }
167  po::notify(vm);
168  if( !parseOK || vm.count("help")||argc<=1)
169  {
170  std::cout << "Usage: " << argv[0] << " [input]\n"
171  << "Count the number of connected component (same values) in a volume (Vol) file image\n"
172  << general_opt << "\n"
173  << "Example : \n \t volCComponentCounter -i $DGtal/examples/samples/Al.100.vol ";
174  return 0;
175  }
176  string inputFilename = vm["input"].as<std::string>();
177  unsigned int connectivity = vm["connectivity"].as<unsigned int>();
178 
179  if ((connectivity != 6) && (connectivity != 18) && (connectivity != 26))
180  {
181  trace.error() << "Bad connectivity value.";
182  trace.info() << std::endl;
183  exit(1);
184  }
185 
187  Image image = VolReader<Image>::importVol( inputFilename );
188 
189  trace.info() << "Image loaded: "<<image<< std::endl;
190 
191  typedef std::map<Point,std::size_t> rank_t; // => order on Element
192  typedef std::map<Point,Point> parent_t;
193  rank_t rank_map;
194  parent_t parent_map;
195 
196  boost::associative_property_map<rank_t> rank_pmap(rank_map);
197  boost::associative_property_map<parent_t> parent_pmap(parent_map);
198 
199  CCCounter(rank_pmap, parent_pmap, image, connectivity);
200 
201 
202  return 0;
203 }
void beginBlock(const std::string &keyword="")
STL namespace.
double endBlock()
Trace trace(traceWriterTerm)
std::ostream & info()
std::vector< Value >::const_iterator ConstIterator
const Domain & domain() const
std::ostream & error()