32 #include "DGtal/base/Common.h" 33 #include "DGtal/helpers/StdDefs.h" 34 #include "DGtal/images/ImageContainerBySTLVector.h" 35 #include "DGtal/io/writers/GenericWriter.h" 36 #include "DGtal/io/readers/VolReader.h" 37 #include "DGtal/images/ConstImageAdapter.h" 38 #include "DGtal/kernel/BasicPointFunctors.h" 41 #include <boost/program_options/options_description.hpp> 42 #include <boost/program_options/parsers.hpp> 43 #include <boost/program_options/variables_map.hpp> 46 using namespace DGtal;
50 namespace po = boost::program_options;
101 int main(
int argc,
char** argv )
103 typedef ImageContainerBySTLVector < Z3i::Domain, unsigned char > Image3D;
104 typedef ImageContainerBySTLVector < Z2i::Domain, unsigned char> Image2D;
105 typedef DGtal::ConstImageAdapter<Image3D, Z2i::Domain, DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain>,
106 Image3D::Value, DGtal::functors::Identity > ImageAdapterExtractor;
109 po::options_description general_opt(
"Allowed options are: ");
110 general_opt.add_options()
111 (
"help,h",
"display this message")
112 (
"input,i", po::value<std::string>(),
"volumetric file (.vol) " )
113 (
"output,o", po::value<std::string>(),
"sequence of discrete point file (.sdp) ")
114 (
"thresholdMin,m", po::value<int>()->default_value(128),
"min threshold (default 128)" )
115 (
"thresholdMax,M", po::value<int>()->default_value(255),
"max threshold (default 255)" )
116 (
"nx", po::value<double>()->default_value(0),
"set the x component of the projection direction." )
117 (
"ny", po::value<double>()->default_value(0),
"set the y component of the projection direction." )
118 (
"nz", po::value<double>()->default_value(1),
"set the z component of the projection direction." )
119 (
"centerX,x", po::value<unsigned int>()->default_value(0),
"choose x center of the projected image." )
120 (
"centerY,y", po::value<unsigned int>()->default_value(0),
"choose y center of the projected image." )
121 (
"centerZ,z", po::value<unsigned int>()->default_value(1),
"choose z center of the projected image." )
122 (
"width", po::value<unsigned int>()->default_value(100),
"set the width of the resulting height Field image." )
123 (
"height", po::value<unsigned int>()->default_value(100),
"set the height of the resulting height Field image." )
124 (
"heightFieldMaxScan", po::value<unsigned int>()->default_value(255),
"set the maximal scan deep." )
125 (
"setBackgroundLastDepth",
"change the default background (black with the last filled intensity).");
130 po::variables_map vm;
132 po::store(po::parse_command_line(argc, argv, general_opt), vm);
133 }
catch(
const std::exception& ex){
135 trace.info()<<
"Error checking program options: "<< ex.what()<< endl;
138 if( !parseOK || vm.count(
"help")||argc<=1)
140 std::cout <<
"Usage: " << argv[0] <<
" [input] [output]\n" 141 <<
"Convert volumetric file into a projected 2D image given from a normal direction N and from a starting point P. The 3D volume is scanned in this normal direction N starting from P with a step 1. If the intensity of the 3d point is inside the given thresholds its 2D gray values are set to the current scan number." 142 << general_opt <<
"\n";
143 std::cout <<
"Example:\n" 144 <<
"vol2heightfield -i ${DGtal}/examples/samples/lobster.vol -m 60 -M 500 --nx 0 --ny 0.7 --nz -1 -x 150 -y 0 -z 150 --width 300 --height 300 --heightFieldMaxScan 350 -o resultingHeightMap.pgm \n";
148 if(! vm.count(
"input") ||! vm.count(
"output"))
150 trace.error() <<
" Input and output filename are needed to be defined" << endl;
154 string inputFilename = vm[
"input"].as<std::string>();
155 string outputFilename = vm[
"output"].as<std::string>();
157 trace.info() <<
"Reading input file " << inputFilename ;
158 Image3D inputImage = DGtal::VolReader<Image3D>::importVol(inputFilename);
159 trace.info() <<
" [done] " << std::endl ;
161 std::ofstream outStream;
162 outStream.open(outputFilename.c_str());
163 int minTh = vm[
"thresholdMin"].as<
int>();
164 int maxTh = vm[
"thresholdMax"].as<
int>();
166 trace.info() <<
"Processing image to output file " << outputFilename ;
168 unsigned int widthImageScan = vm[
"height"].as<
unsigned int>();
169 unsigned int heightImageScan = vm[
"width"].as<
unsigned int>();
170 unsigned int maxScan = vm[
"heightFieldMaxScan"].as<
unsigned int>();
171 if(maxScan > std::numeric_limits<Image2D::Value>::max()){
172 maxScan = std::numeric_limits<Image2D::Value>::max();
173 trace.warning()<<
"value --setBackgroundLastDepth outside mox value of image. Set to max value:" << maxScan << std::endl;
176 unsigned int centerX = vm[
"centerX"].as<
unsigned int>();
177 unsigned int centerY = vm[
"centerY"].as<
unsigned int>();
178 unsigned int centerZ = vm[
"centerZ"].as<
unsigned int>();
180 double nx = vm[
"nx"].as<
double>();
181 double ny = vm[
"ny"].as<
double>();
182 double nz = vm[
"nz"].as<
double>();
185 Image2D::Domain aDomain2D(DGtal::Z2i::Point(0,0),
186 DGtal::Z2i::Point(widthImageScan, heightImageScan));
187 Z3i::Point ptCenter (centerX, centerY, centerZ);
188 Z3i::RealPoint normalDir (nx, ny, nz);
189 Image2D resultingImage(aDomain2D);
191 for(Image2D::Domain::ConstIterator it = resultingImage.domain().begin();
192 it != resultingImage.domain().end(); it++){
193 resultingImage.setValue(*it, 0);
195 DGtal::functors::Identity idV;
197 unsigned int maxDepthFound = 0;
198 for(
unsigned int k=0; k < maxScan; k++){
199 DGtal::functors::Point2DEmbedderIn3D<DGtal::Z3i::Domain > embedder(inputImage.domain(),
200 ptCenter+normalDir*k,
203 ImageAdapterExtractor extractedImage(inputImage, aDomain2D, embedder, idV);
204 for(Image2D::Domain::ConstIterator it = extractedImage.domain().begin();
205 it != extractedImage.domain().end(); it++){
206 if( resultingImage(*it)== 0 && extractedImage(*it) < maxTh &&
207 extractedImage(*it) > minTh){
209 resultingImage.setValue(*it, maxScan-k);
213 if (vm.count(
"setBackgroundLastDepth")){
214 for(Image2D::Domain::ConstIterator it = resultingImage.domain().begin();
215 it != resultingImage.domain().end(); it++){
216 if( resultingImage(*it)== 0 ){
217 resultingImage.setValue(*it, maxScan-maxDepthFound);
222 resultingImage >> outputFilename;
224 trace.info() <<
" [done] " << std::endl ;