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" 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> 45 using namespace DGtal;
49 namespace po = boost::program_options;
90 template <
typename Rank,
typename Parent,
typename Image>
91 void CCCounter(Rank& r, Parent& p,
const Image& elements,
const unsigned int connectivity)
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)
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);
107 for(
typename Image::Domain::ConstIterator e = elements.domain().begin();
108 e !=elements.domain().end(); ++e)
110 if ( elements.domain().isInside(*e+decx) &&
111 (elements(*e) == elements(*e+decx)))
112 dsets.union_set(*e,*e+decx);
114 if ( elements.domain().isInside(*e+decy) &&
115 (elements(*e) == elements(*e+decy)))
116 dsets.union_set(*e,*e+decy);
118 if ( elements.domain().isInside(*e+decz) &&
119 (elements(*e) == elements(*e+decz)))
120 dsets.union_set(*e,*e+decz);
122 if (connectivity > 6)
124 if ( elements.domain().isInside(*e+decx+decy) &&
125 (elements(*e) == elements(*e+decx+decy)))
126 dsets.union_set(*e,*e+decx+decy);
128 if ( elements.domain().isInside(*e+decx+decz) &&
129 (elements(*e) == elements(*e+decx+decz)))
130 dsets.union_set(*e,*e+decx+decz);
132 if ( elements.domain().isInside(*e+decy+decz) &&
133 (elements(*e) == elements(*e+decy+decz)))
134 dsets.union_set(*e,*e+decy+decz);
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);
145 std::cout <<
"Number of disjoint "<<connectivity<<
"-components = " 146 <<dsets.count_sets(elements.domain().begin(),
147 elements.domain().end())
153 int main(
int argc,
char** argv )
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)");
162 po::variables_map vm;
164 po::store(po::parse_command_line(argc, argv, general_opt), vm);
165 }
catch(
const std::exception& ex){
167 trace.info()<<
"Error checking program options: "<< ex.what()<< endl;
170 if( !parseOK || vm.count(
"help")||argc<=1)
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 ";
178 string inputFilename = vm[
"input"].as<std::string>();
179 unsigned int connectivity = vm[
"connectivity"].as<
unsigned int>();
181 if ((connectivity != 6) && (connectivity != 18) && (connectivity != 26))
183 trace.error() <<
"Bad connectivity value.";
184 trace.info() << std::endl;
188 typedef ImageSelector<Domain, unsigned char>::Type Image;
189 Image image = VolReader<Image>::importVol( inputFilename );
191 trace.info() <<
"Image loaded: "<<image<< std::endl;
193 typedef std::map<Point,std::size_t> rank_t;
194 typedef std::map<Point,Point> parent_t;
198 boost::associative_property_map<rank_t> rank_pmap(rank_map);
199 boost::associative_property_map<parent_t> parent_pmap(parent_map);
201 CCCounter(rank_pmap, parent_pmap, image, connectivity);