33 #include <boost/program_options/options_description.hpp> 34 #include <boost/program_options/parsers.hpp> 35 #include <boost/program_options/variables_map.hpp> 36 #include <DGtal/kernel/sets/SetPredicate.h> 37 #include <DGtal/io/readers/VolReader.h> 38 #include <DGtal/images/ImageSelector.h> 39 #include <DGtal/images/SimpleThresholdForegroundPredicate.h> 40 #include <DGtal/images/ImageLinearCellEmbedder.h> 41 #include <DGtal/shapes/Shapes.h> 42 #include <DGtal/kernel/CanonicEmbedder.h> 43 #include <DGtal/helpers/StdDefs.h> 44 #include <DGtal/topology/helpers/Surfaces.h> 45 #include <DGtal/topology/DigitalSurface.h> 46 #include <DGtal/topology/SetOfSurfels.h> 51 using namespace DGtal;
53 namespace po = boost::program_options;
110 int main(
int argc,
char** argv )
114 po::options_description general_opt(
"Allowed options are ");
115 general_opt.add_options()
116 (
"help,h",
"display this message")
117 (
"input,i", po::value<std::string>(),
"the volume file (.vol)" )
118 (
"threshold,t", po::value<unsigned int>()->default_value(1),
"the value that defines the isosurface in the image (an integer between 0 and 255)." )
119 (
"adjacency,a", po::value<unsigned int>()->default_value(0),
"0: interior adjacency, 1: exterior adjacency")
120 (
"output,o", po::value<std::string>()->default_value(
"marching-cubes.off" ),
"the output OFF file that represents the geometry of the isosurface") ;
122 po::variables_map vm;
124 po::store(po::parse_command_line(argc, argv, general_opt), vm);
125 }
catch(
const std::exception& ex){
127 trace.info()<<
"Error checking program options: "<< ex.what()<< std::endl;
130 if ( !parseOK || vm.count(
"help") || ( argc <= 1 ) )
132 std::cout <<
"Usage: " << argv[0]
133 <<
" [-i <fileName.vol>] [-t <threshold>] [-a <adjacency>] [-o <output.off>]" << std::endl
134 <<
"Outputs the isosurface of value <threshold> of the volume <fileName.vol> as an OFF file <output.off>. The <adjacency> (0/1) allows to choose between interior (6,18) and exterior (18,6) adjacency." << std::endl
135 << general_opt << std::endl;
138 if ( ! vm.count(
"input") )
140 trace.error() <<
"The input file name was defined." << std::endl;
143 std::string inputFilename = vm[
"input"].as<std::string>();
144 unsigned int threshold = vm[
"threshold"].as<
unsigned int>();
145 bool intAdjacency = ( vm[
"adjacency"].as<
unsigned int>() == 0 );
146 std::string outputFilename = vm[
"output"].as<std::string>();
150 trace.beginBlock(
"Reading vol file into an image." );
151 typedef ImageSelector < Domain, int>::Type Image;
152 Image image = VolReader<Image>::importVol(inputFilename);
154 typedef functors::SimpleThresholdForegroundPredicate<Image> ThresholdedImage;
155 ThresholdedImage thresholdedImage( image, threshold );
163 trace.beginBlock(
"Construct the Khalimsky space from the image domain." );
165 bool space_ok = ks.init( image.domain().lowerBound(),
166 image.domain().upperBound(), true );
169 trace.error() <<
"Error in the Khamisky space construction."<<std::endl;
176 typedef SurfelAdjacency<KSpace::dimension> MySurfelAdjacency;
177 MySurfelAdjacency surfAdj( intAdjacency );
181 trace.beginBlock(
"Extracting boundary by scanning the space. " );
182 typedef KSpace::SurfelSet SurfelSet;
183 typedef SetOfSurfels< KSpace, SurfelSet > MySetOfSurfels;
184 typedef DigitalSurface< MySetOfSurfels > MyDigitalSurface;
185 MySetOfSurfels theSetOfSurfels( ks, surfAdj );
186 Surfaces<KSpace>::sMakeBoundary( theSetOfSurfels.surfelSet(),
187 ks, thresholdedImage,
188 image.domain().lowerBound(),
189 image.domain().upperBound() );
190 MyDigitalSurface digSurf( theSetOfSurfels );
191 trace.info() <<
"Digital surface has " << digSurf.size() <<
" surfels." 197 trace.beginBlock(
"Making OFF surface. " );
199 typedef CanonicEmbedder< Space > MyEmbedder;
201 typedef ImageLinearCellEmbedder< KSpace, Image, MyEmbedder > CellEmbedder;
202 CellEmbedder cellEmbedder;
203 MyEmbedder trivialEmbedder;
207 cellEmbedder.init( ks, image, trivialEmbedder,
208 ( (
double) threshold ) + 0.5 );
209 std::ofstream out( outputFilename.c_str() );
211 digSurf.exportEmbeddedSurfaceAs3DOFF( out, cellEmbedder );