32 #include "DGtal/base/Common.h" 33 #include "DGtal/helpers/StdDefs.h" 36 #include "DGtal/io/readers/PointListReader.h" 37 #include "DGtal/io/writers/GenericWriter.h" 40 #include "DGtal/geometry/curves/FreemanChain.h" 41 #include "DGtal/topology/helpers/Surfaces.h" 42 #include "DGtal/topology/SurfelSetPredicate.h" 46 #include <boost/program_options/options_description.hpp> 47 #include <boost/program_options/parsers.hpp> 48 #include <boost/program_options/variables_map.hpp> 54 using namespace DGtal;
58 namespace po = boost::program_options;
110 int main(
int argc,
char** argv )
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.");
122 typedef KhalimskySpaceND<2, int>::Cell Cell;
123 typedef KhalimskySpaceND<2, int>::SCell SCell;
124 typedef FreemanChain<Z2i::Integer> FreemanChain;
125 typedef DGtal::KhalimskySpaceND< 2, int > KSpace;
126 typedef DGtal::ImageContainerBySTLVector<Z2i::Domain, unsigned char> Image2D ;
129 po::variables_map vm;
131 po::store(po::parse_command_line(argc, argv, general_opt), vm);
132 }
catch(
const std::exception& ex){
134 trace.info()<<
"Error checking program options: "<< ex.what()<< std::endl;
139 if(!parseOK||vm.count(
"help")||argc<=1 || (!(vm.count(
"input") ) ) )
142 trace.info() <<
" Error parsing options\n" <<std::endl;
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";
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();
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;
175 minx-=border; miny-=border; maxx+=border; maxy+=border;
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;
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);
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>();