DGtalTools  0.9.4
freeman2img.cpp
1 
29 #include <iostream>
31 
32 #include "DGtal/base/Common.h"
33 #include "DGtal/helpers/StdDefs.h"
34 
35 //image
36 #include "DGtal/io/readers/PointListReader.h"
37 #include "DGtal/io/writers/GenericWriter.h"
38 
39 //contour
40 #include "DGtal/geometry/curves/FreemanChain.h"
41 #include "DGtal/topology/helpers/Surfaces.h"
42 #include "DGtal/topology/SurfelSetPredicate.h"
43 
44 
45 //boost
46 #include <boost/program_options/options_description.hpp>
47 #include <boost/program_options/parsers.hpp>
48 #include <boost/program_options/variables_map.hpp>
49 
50 //STL
51 #include <vector>
52 #include <string>
53 
54 using namespace DGtal;
55 
56 
58 namespace po = boost::program_options;
59 
110 int main( int argc, char** argv )
111 {
112  // parse command line ----------------------------------------------
113  po::options_description general_opt("Allowed options are: ");
114  general_opt.add_options()
115  ("help,h", "display this message")
116  ("input,i", po::value<std::string>(), "the input FreemanChain file name")
117  ("output,o", po::value<std::string>()->default_value("result.pgm"), " the output filename")
118  ("border,b", po::value<unsigned int>()->default_value(0), " add a border in the resulting image (used only in the automatic mode i.e when --space is not used.")
119  ("space,s", po::value<std::vector <int> >()->multitoken(), "Define the space from its bounding box (lower and upper coordinates) \
120 else the space is automatically defined from the freemanchain bounding boxes.");
121 
127 
128  bool parseOK=true;
129  po::variables_map vm;
130  try{
131  po::store(po::parse_command_line(argc, argv, general_opt), vm);
132  }catch(const std::exception& ex){
133  parseOK=false;
134  trace.info()<< "Error checking program options: "<< ex.what()<< std::endl;
135  }
136 
137 
138  po::notify(vm);
139  if(!parseOK||vm.count("help")||argc<=1 || (!(vm.count("input") ) ) )
140  {
141  if(!parseOK){
142  trace.info() <<" Error parsing options\n" <<std::endl;
143  }
144  trace.info()<< "Transform one or several freeman chains into an grayscale image file by filling its interior areas." << std::endl
145  << "The transformation can fill shapes with hole by using the freemanchain orientation."
146  <<" The interior is considered on the left according to a freeman chain move, i.e. a clockwise oriented contour represents a hole in the shape." <<std::endl
147  << "Basic usage: "<<std::endl
148  << "\t freeman2img -i inputChain.fc -o contourDisplay.pgm -b 5 "<<std::endl
149  << general_opt << "\n";
150  return 0;
151  }
152 
153  if( vm.count("input") ){
154  unsigned int border = vm["border"].as<unsigned int>();
155  std::string fileName = vm["input"].as<std::string>();
156  std::vector< FreemanChain > vectFcs = PointListReader< Z2i::Point >::getFreemanChainsFromFile<Z2i::Integer> (fileName);
157  int minx=std::numeric_limits<int>::max();
158  int miny=std::numeric_limits<int>::max();
159  int maxx=std::numeric_limits<int>::min();
160  int maxy=std::numeric_limits<int>::min();
161 
162  if(!vm.count("space")){
163  for(std::vector< FreemanChain >::const_iterator it = vectFcs.begin(); it!= vectFcs.end(); it++){
164  FreemanChain fc = *it;
165  int t_minx=std::numeric_limits<int>::max();
166  int t_miny=std::numeric_limits<int>::max();
167  int t_maxx=std::numeric_limits<int>::min();
168  int t_maxy=std::numeric_limits<int>::min();
169  fc.computeBoundingBox(t_minx, t_miny, t_maxx, t_maxy);
170  minx = t_minx > minx? minx: t_minx;
171  miny = t_miny > miny? miny: t_miny;
172  maxx = t_maxx < maxx? maxx: t_maxx;
173  maxy = t_maxy < maxy? maxy: t_maxy;
174  }
175  minx-=border; miny-=border; maxx+=border; maxy+=border;
176  }else{
177  std::vector<int> vectSpace = vm["space"].as<std::vector<int> > ();
178  if(vectSpace.size()!=4){
179  trace.error() << " Option : --space: you need to enter the two lower and upper point of the space."<<std::endl;
180  return 0;
181  }
182  minx = vectSpace[0];
183  miny = vectSpace[1];
184  maxx = vectSpace[2];
185  maxy = vectSpace[3];
186  }
187  KSpace aKSpace;
188  aKSpace.init(Z2i::Point(minx, miny), Z2i::Point(maxx, maxy), true);
189  std::set<SCell> boundarySCell;
190  std::set<Cell> interiorCell;
191  for(std::vector< FreemanChain >::const_iterator it = vectFcs.begin(); it!= vectFcs.end(); it++){
192  FreemanChain fc = *it;
193  FreemanChain::getInterPixelLinels(aKSpace, fc, boundarySCell, true);
194  }
195 
196  Image2D imageResult (Z2i::Domain(Z2i::Point(minx, miny), Z2i::Point(maxx, maxy)));
197  Surfaces<KSpace>::uFillInterior(aKSpace, functors::SurfelSetPredicate<std::set<SCell>,SCell>(boundarySCell), imageResult, 255, false, false );
198  imageResult >> vm["output"].as<std::string>();
199  }
200 
201 }
202 
203 
DGtal::int32_t Integer
static void getInterPixelLinels(const KhalimskySpaceND< 2, TInteger > &aKSpace, const FreemanChain &fc, typename KhalimskySpaceND< 2, TInteger >::SCellSet &aSCellContour, bool aFlagForAppend=false)
void computeBoundingBox(TInteger &min_x, TInteger &min_y, TInteger &max_x, TInteger &max_y) const
bool init(const Point &lower, const Point &upper, bool isClosed)
Trace trace(traceWriterTerm)
std::ostream & info()
unsigned static int uFillInterior(const KSpace &aKSpace, const TSurfelPredicate &aSurfPred, TImageContainer &anImage, const typename TImageContainer::Value &aValue, bool empty_is_inside=false, bool incrementMode=true)
std::ostream & error()