DGtal  0.6.devel
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
pgm2freeman.cpp
1 
29 
30 #include <iostream>
31 
32 #include "DGtal/base/Common.h"
33 
34 #include "DGtal/topology/KhalimskySpaceND.h"
35 
36 
37 #include "DGtal/shapes/ShapeFactory.h"
38 #include "DGtal/shapes/Shapes.h"
39 #include "DGtal/helpers/StdDefs.h"
40 #include "DGtal/geometry/helpers/ContourHelper.h"
41 
42 
43 #include "DGtal/io/colormaps/GrayscaleColorMap.h"
44 #include "DGtal/images/imagesSetsUtils/ImageFromSet.h"
45 #include "DGtal/images/imagesSetsUtils/SetFromImage.h"
46 #include "DGtal/images/ImageContainerBySTLVector.h"
47 #include "DGtal/images/ImageSelector.h"
48 #include "DGtal/io/readers/PNMReader.h"
49 #include "DGtal/geometry/curves/FreemanChain.h"
50 
51 #include "DGtal/io/boards/Board2D.h"
52 #include "DGtal/topology/helpers/Surfaces.h"
53 
54 #include <boost/program_options/options_description.hpp>
55 #include <boost/program_options/parsers.hpp>
56 #include <boost/program_options/variables_map.hpp>
57 
58 #include <vector>
59 #include <string>
60 
61 using namespace DGtal;
62 
63 
64 
65 
67 namespace po = boost::program_options;
68 
69 int main( int argc, char** argv )
70 {
71  // parse command line ----------------------------------------------
72  po::options_description general_opt("Allowed options are: ");
73  general_opt.add_options()
74  ("help,h", "display this message")
75  ("image,i", po::value<std::string>(), "image file name")
76  ("min,m", po::value<int>(), "min image threshold value (default 128)")
77  ("max,M", po::value<int>(), "max image threshold value (default 255)")
78 
79  ("minSize,s", po::value<int>(), "minSize of the extracted freeman chain (default 0)")
80  ("contourSelect,s", po::value<vector <int> >()->multitoken(),
81  "Select contour according reference point and maximal distance: ex. --contourSelect X Y distanceMax")
82  ("thresholdRange,R", po::value<vector <int> >()->multitoken(),
83  "use a range interval as threshold : --thresholdRange min increment max : for each possible i, it define a digital sets [min+(i*increment),min+((i+1)*increment)] and extract their boundary. ");
84 
85 
86 
87  po::variables_map vm;
88  po::store(po::parse_command_line(argc, argv, general_opt), vm);
89  po::notify(vm);
90  if(vm.count("help")||argc<=1)
91  {
92  trace.info()<< "Extract FreemanChains from thresholded image" <<std::endl << "Basic usage: "<<std::endl
93  << "\t image2freeman [options] --image <imageName> -min 128 -max 255 > contours.fc"<<std::endl
94  << general_opt << "\n";
95  return 0;
96  }
97 
98 
99  double minThreshold = 128;
100  double maxThreshold = 255;
101  unsigned int minSize =0;
102  bool select=false;
103  bool thresholdRange=vm.count("thresholdRange");
104  Z2i::Point selectCenter;
105  unsigned int selectDistanceMax = 0;
106 
107 
108  //Parse options
109  if (!(vm.count("image"))){
110  trace.info() << "Image file name needed"<< endl;
111  return 0;
112  }
113 
114  if(vm.count("min")){
115  minThreshold= vm["min"].as<int>();
116  }
117  if(vm.count("max")){
118  maxThreshold= vm["max"].as<int>();
119  }
120  if(vm.count("minSize")){
121  minSize = vm["minSize"].as<int>();
122  }
123  if(vm.count("contourSelect")){
124  select=true;
125  vector<int> cntConstraints= vm["contourSelect"].as<vector <int> >();
126  if(cntConstraints.size()!=3){
127  trace.info() << "Incomplete option \"--contourSelect\""<< endl;
128  return 0;
129  }
130  selectCenter[0]= cntConstraints.at(0);
131  selectCenter[1]= cntConstraints.at(1);
132  selectDistanceMax= (unsigned int) cntConstraints.at(2);
133  }
134 
135  int min, max, increment;
136  if(! thresholdRange){
137  min=(int)minThreshold;
138  max= (int)maxThreshold;
139  increment = (int)(maxThreshold- minThreshold);
140  }else{
141  vector<int> vectRange= vm["thresholdRange"].as<vector <int> >();
142  if(vectRange.size()!=3){
143  trace.info() << "Incomplete option \"--thresholdRange\""<< endl;
144  return 0;
145  }
146  min=vectRange.at(0);
147  increment=vectRange.at(1);
148  max = vectRange.at(2);
149  }
150 
151 
152 
154  string imageFileName = vm["image"].as<std::string>();
155  Image image = PNMReader<Image>::importPGM( imageFileName );
156  Z2i::DigitalSet set2d (image.domain());
157  SetPredicate<Z2i::DigitalSet> set2dPredicate( set2d );
158 
159  for(int i=0; minThreshold+i*increment< maxThreshold; i++){
160  min = (int)(minThreshold+i*increment);
161  max = (int)(minThreshold+(i+1)*increment);
162 
163 
164  SetFromImage<Z2i::DigitalSet>::append<Image>(set2d, image, min, max);
165  trace.info() << "DGtal set imported from thresholds ["<< min << "," << max << "]" << endl;
166  Z2i::KSpace ks;
167  if(! ks.init( image.domain().lowerBound(),
168  image.domain().upperBound(), true )){
169  trace.error() << "Problem in KSpace initialisation"<< endl;
170  }
171  SurfelAdjacency<2> sAdj( true );
172 
173  std::vector< std::vector< Z2i::Point > > vectContoursBdryPointels;
174  Surfaces<Z2i::KSpace>::extractAllPointContours4C( vectContoursBdryPointels,
175  ks, set2dPredicate, sAdj );
176  for(unsigned int k=0; k<vectContoursBdryPointels.size(); k++){
177  if(vectContoursBdryPointels.at(k).size()>minSize){
178  if(select){
179  Z2i::Point ptMean = ContourHelper::getMeanPoint(vectContoursBdryPointels.at(k));
180  unsigned int distance = (unsigned int)ceil(sqrt((double)(ptMean[0]-selectCenter[0])*(ptMean[0]-selectCenter[0])+
181  (ptMean[1]-selectCenter[1])*(ptMean[1]-selectCenter[1])));
182  if(distance<=selectDistanceMax){
183  FreemanChain<Z2i::Integer> fc (vectContoursBdryPointels.at(k));
184  cout << fc.x0 << " " << fc.y0 << " " << fc.chain << endl;
185  }
186  }else{
187  FreemanChain<Z2i::Integer> fc (vectContoursBdryPointels.at(k));
188  cout << fc.x0 << " " << fc.y0 << " " << fc.chain << endl;
189  }
190  }
191 
192  }
193 
194 
195 
196  }
197 
198 
199 
200 }
201