DGtalTools 2.0.0
Loading...
Searching...
No Matches
shapeGenerator.cpp
1
30#include <iostream>
31#include <vector>
32#include <string>
33
34#include "CLI11.hpp"
35
36#include "DGtal/base/Common.h"
37
38#include "DGtal/shapes/ShapeFactory.h"
39#include "DGtal/shapes/Shapes.h"
40#include "DGtal/helpers/StdDefs.h"
41#include "DGtal/topology/helpers/Surfaces.h"
42
43#include "DGtal/images/imagesSetsUtils/ImageFromSet.h"
44#include "DGtal/images/imagesSetsUtils/SetFromImage.h"
45#include "DGtal/images/ImageContainerBySTLVector.h"
46
47#include "DGtal/io/writers/PGMWriter.h"
48#include "DGtal/io/writers/RawWriter.h"
49#include "DGtal/io/writers/VolWriter.h"
50#include "DGtal/io/boards/Board2D.h"
51
52
53using namespace DGtal;
54
55
125std::vector<std::string> shapes2D;
126std::vector<std::string> shapesDesc;
127std::vector<std::string> shapesParam1;
128std::vector<std::string> shapesParam2;
129std::vector<std::string> shapesParam3;
130std::vector<std::string> shapesParam4;
131
132
137void createList()
138{
139 shapes2D.push_back("ball");
140 shapesDesc.push_back("Ball for the Euclidean metric.");
141 shapesParam1.push_back("--radius [-R]");
142 shapesParam2.push_back("");
143 shapesParam3.push_back("");
144 shapesParam4.push_back("");
145
146 shapes2D.push_back("square");
147 shapesDesc.push_back("square (no signature).");
148 shapesParam1.push_back("--width [-w]");
149 shapesParam2.push_back("");
150 shapesParam3.push_back("");
151 shapesParam4.push_back("");
152
153 shapes2D.push_back("lpball");
154 shapesDesc.push_back("Ball for the l_power metric (no signature).");
155 shapesParam1.push_back("--radius [-R],");
156 shapesParam2.push_back("--power [-p]");
157 shapesParam3.push_back("");
158 shapesParam4.push_back("");
159
160 shapes2D.push_back("flower");
161 shapesDesc.push_back("Flower with k petals.");
162 shapesParam1.push_back("--radius [-R],");
163 shapesParam2.push_back("--varsmallradius [-v],");
164 shapesParam3.push_back("--k [-k],");
165 shapesParam4.push_back("--phi");
166
167 shapes2D.push_back("ngon");
168 shapesDesc.push_back("Regular k-gon.");
169 shapesParam1.push_back("--radius [-R],");
170 shapesParam2.push_back("--k [-k],");
171 shapesParam3.push_back("--phi");
172 shapesParam4.push_back("");
173
174 shapes2D.push_back("accflower");
175 shapesDesc.push_back("Accelerated Flower with k petals.");
176 shapesParam1.push_back("--radius [-R],");
177 shapesParam2.push_back("--varsmallradius [-v],");
178 shapesParam3.push_back("--k [-k],");
179 shapesParam4.push_back("--phi");
180
181 shapes2D.push_back("ellipse");
182 shapesDesc.push_back("Ellipse.");
183 shapesParam1.push_back("--axis1 [-A],");
184 shapesParam2.push_back("--axis2 [-a],");
185 shapesParam3.push_back("--phi");
186 shapesParam4.push_back("");
187
188
189}
190
195void displayList()
196{
197 trace.emphase()<<"2D Shapes:"<<std::endl;
198 for(unsigned int i=0; i<shapes2D.size(); ++i)
199 trace.info()<<"\t"<<shapes2D[i]<<"\t"
200 <<shapesDesc[i]<<std::endl
201 <<"\t\tRequired parameter(s): "
202 << shapesParam1[i]<<" "
203 << shapesParam2[i]<<" "
204 << shapesParam3[i]<<" "
205 << shapesParam4[i]<<std::endl;
206
207}
208
209
218unsigned int checkAndRetrunIndex(const std::string &shapeName)
219{
220 unsigned int pos=0;
221
222 while ((pos < shapes2D.size()) && (shapes2D[pos] != shapeName))
223 pos++;
224
225 if (pos == shapes2D.size())
226 {
227 trace.error() << "The specified shape has not found.";
228 trace.info()<<std::endl;
229 exit(1);
230 }
231
232 return pos;
233}
234
235
243template <typename Set, typename Image>
244struct Exporter
245{
246
255 static
256 void save(const Set &aSet,
257 const std::string outputName,
258 const std::string outputFormat)
259 {
260
261 Image image = ImageFromSet<Image>::template create<Set>(aSet, 255, true);
262
263 if (outputFormat == "pgm")
264 PGMWriter<Image>::exportPGM(outputName+"."+outputFormat,image);
265 else
266 if (outputFormat == "raw")
267 RawWriter<Image>::exportRaw8(outputName+"."+outputFormat,image);
268 else
269 if (outputFormat == "svg")
270 {
271 Board2D board;
272 board << aSet;
273 board.saveSVG((outputName+"."+outputFormat).c_str());
274 }
275 else
276#ifdef DGTAL_WITH_CAIRO
277 if (outputFormat == "pdf")
278 {
279 Board2D board;
280 board << aSet;
281 board.saveCairo((outputName+"."+outputFormat).c_str(), Board2D::CairoPDF);
282
283 }
284 else
285 if (outputFormat == "png")
286 {
287 Board2D board;
288 board << aSet;
289 board.saveCairo((outputName+"."+outputFormat).c_str(), Board2D::CairoPNG);
290 }
291 else
292#endif
293 {
294 trace.error()<< "Output format: "<<outputFormat<< " not recognized."<<std::endl;
295 exit(1);
296 }
297 }
298
299
300
301
302
303
312 template <typename Shape>
313 static
314 void exportSignature(const Shape & aShape, Set &aSet, const Z2i::Domain &aDomain)
315 {
316 trace.beginBlock("Extracting the boundary");
317 Z2i::KSpace ks;
318 bool space_ok = ks.init( aDomain.lowerBound(),aDomain.upperBound(), true );
319 SurfelAdjacency<2> sAdj( true );
320
321 ASSERT(space_ok);
322 trace.info() << aSet << std::endl;
323 trace.info() << ks
324 << ( space_ok ? " Successfully instantiated" : " Error" )
325 << std::endl;
326
327 std::vector< std::vector< Z2i::Point > > vectContoursBdryPointels;
328 Surfaces<Z2i::KSpace>::extractAllPointContours4C( vectContoursBdryPointels,
329 ks, aSet, sAdj );
330 trace.endBlock();
331
333 std::cout<<"## shapeGenerator signature export"<<std::endl;
334 std::cout<<"## shape: "<<aShape<<std::endl;
335 std::cout<<"## x\ty\tdx\tdy\tddx\tddy"<<std::endl;
336 for(unsigned int i=0; i<vectContoursBdryPointels.size(); i++)
337 for(unsigned int j=0 ; j< vectContoursBdryPointels.at(i).size() - 1; j++)
338 {
339 Z2i::Space::Point point = (vectContoursBdryPointels.at(i).at(j)
340 + vectContoursBdryPointels.at(i).at(j+1));
341 Z2i::Space::RealPoint midpoint (point[0]/2.0,point[1]/2.0);
342
343 Z2i::Space::RealPoint xp,xpp;
344 double t = aShape.parameter(midpoint);
345 xp = aShape.xp( t );
346 xpp = aShape.xpp( t );
347
348 std::cout<< midpoint[0]<<"\t"<<midpoint[1]<<"\t"
349 << xp[0]<<"\t"<<xp[1]<<"\t"
350 << xpp[0]<<"\t"<<xpp[1]<<std::endl;
351
352 }
353
354 }
355};
356
362void missingParam(std::string param)
363{
364 trace.error() <<" Parameter: "<<param<<" is required..";
365 trace.info()<<std::endl;
366 exit(1);
367}
368
370
371int main( int argc, char** argv )
372{
373 // parse command line CLI ----------------------------------------------
374 CLI::App app;
375 std::string shapeName;
376 std::string outputName;
377 std::string outputFormat {"pgm"};
378 double radius;
379 double power {2.0};
380 double smallradius {5};
381 double varsmallradius {5};
382 unsigned int k {3};
383 double phi {0.0};
384 double width {10.0};
385 double axis1, axis2;
386
387 app.description("Generates shapes using DGtal library.\n Typical use example:\n \t shapeGenerator [options] --shape <shapeName> --output <outputBasename>\n");
388 auto listOpt = app.add_flag("--list,-l","List all available shapes");
389 auto shapeNameOpt = app.add_option("--shape,-s", shapeName, "Shape name");
390 auto radiusOpt = app.add_option("--radius,-R", radius, "Radius of the shape" );
391 auto axis1Opt = app.add_option("--axis1,-A", axis1, "Half big axis of the shape (ellipse)" );
392 auto axis2Opt = app.add_option("--axis2,-a", axis2, "Half small axis of the shape (ellipse)" );
393 auto smallradiusOpt = app.add_option("--smallradius,-r", smallradius, "Small radius of the shape (default 5)");
394 auto varsmallradiusOpt = app.add_option("--varsmallradius,-v", varsmallradius, "Variable small radius of the shape (default 5)" );
395 auto kOpt = app.add_option("-k", k, "Number of branches or corners the shape (default 3)" );
396 auto phiOpt = app.add_option("--phi", phi, "Phase of the shape (in radian, default 0.0)" );
397 auto widthOpt = app.add_option("--width,-w", width, "Width of the shape (default 10.0)" );
398 auto powerOpt = app.add_option("--power,-p", power, "Power of the metric (default 2.0)" );
399 auto outputNameOpt = app.add_option("--output,-o", outputName, "Basename of the output file");
400 auto signatureOpt = app.add_flag("--signature", "Display to the standard output the signature (normal, curvature) at each point of the specified shape contour (middle point of each contour linel)");
401 app.add_option("--format,-f", outputFormat, "Output format:\n\t Bitmap {pgm, raw}\n\t Vector {svg} (+ {png,pdf} if libCairo installed) (default pgm)" );
402
403 app.get_formatter()->column_width(40);
404 CLI11_PARSE(app, argc, argv);
405 // END parse command line using CLI ----------------------------------------------
406
407 //List creation
408 createList();
409
410 if ( listOpt->count() > 0 )
411 {
412 displayList();
413 return 0;
414 }
415
416 if(shapeNameOpt->count()==0) missingParam("--shape");
417 if(outputNameOpt->count()==0) missingParam("--output");
418
419 //We check that the shape is known
420 unsigned int id = checkAndRetrunIndex(shapeName);
421 typedef ImageContainerBySTLVector<Z2i::Domain,unsigned char> Image;
422
423 if (id ==0)
424 {
425 if (radiusOpt->count()==0) missingParam("--radius");
426 Ball2D<Z2i::Space> ball(Z2i::Point(0,0), radius);
427 Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound());
428 Z2i::DigitalSet aSet(domain);
429
430 Shapes<Z2i::Domain>::euclideanShaper(aSet, ball);
431 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
432
433 if (signatureOpt->count()>0)
434 Exporter<Z2i::DigitalSet,Image>::exportSignature(ball,aSet,domain);
435
436 return 0;
437 }
438 else
439 if (id ==1)
440 {
441 //if (widthOpt->count()==0) missingParam("--width");
442 ImplicitHyperCube<Z2i::Space> object(Z2i::Point(0,0), width/2.0);
443 Z2i::Domain domain(object.getLowerBound(), object.getUpperBound());
444 Z2i::DigitalSet aSet(domain);
445
446 Shapes<Z2i::Domain>::euclideanShaper(aSet, object);
447 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
448
449 if (signatureOpt->count()>0)
450 {
451 trace.error()<< "No signature export for this shape.";
452 trace.info()<<std::endl;
453 }
454
455 return 0;
456 }
457 else
458 if (id ==2)
459 {
460 //if (powerOpt->count()==0) missingParam("--power");
461 if (radiusOpt->count()==0) missingParam("--radius");
462 ImplicitRoundedHyperCube<Z2i::Space> ball(Z2i::Point(0,0), radius, power);
463 Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound());
464 Z2i::DigitalSet aSet(domain);
465
466 Shapes<Z2i::Domain>::euclideanShaper(aSet, ball);
467 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
468
469 if (signatureOpt->count()>0)
470 {
471 trace.error()<< "No signature export for this shape.";
472 trace.info()<<std::endl;
473 }
474
475 return 0;
476 }
477 else
478 if (id ==3)
479 {
480 //if (varsmallradiusOpt->count()==0) missingParam("--varsmallradius");
481 if (radiusOpt->count()==0) missingParam("--radius");
482 //if (kOpt->count()==0) missingParam("--k");
483 //if (phiOpt->count()==0) missingParam("--phi");
484 Flower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
485 Z2i::Domain domain(flower.getLowerBound(), flower.getUpperBound());
486 Z2i::DigitalSet aSet(domain);
487
488 Shapes<Z2i::Domain>::euclideanShaper(aSet, flower);
489 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
490
491 if (signatureOpt->count()>0)
492 Exporter<Z2i::DigitalSet,Image>::exportSignature(flower,aSet,domain);
493
494 return 0;
495 }
496 else
497 if (id ==4)
498 {
499 if (radiusOpt->count()==0) missingParam("--radius");
500 //if (kOpt->count()==0) missingParam("--k");
501 //if (phiOpt->count()==0) missingParam("--phi");
502 NGon2D<Z2i::Space> object(Z2i::Point(0,0), radius,k,phi);
503 Z2i::Domain domain(object.getLowerBound(), object.getUpperBound());
504 Z2i::DigitalSet aSet(domain);
505
506 Shapes<Z2i::Domain>::euclideanShaper(aSet, object);
507 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
508
509 if (signatureOpt->count()>0)
510 Exporter<Z2i::DigitalSet,Image>::exportSignature(object,aSet,domain);
511
512 return 0;
513 }
514 else
515 if (id ==5)
516 {
517 //if (varsmallradiusOpt->count()==0) missingParam("--varsmallradius");
518 if (radiusOpt->count()==0) missingParam("--radius");
519 //if (kOpt->count()==0) missingParam("--k");
520 //if (phiOpt->count()==0) missingParam("--phi");
521 AccFlower2D<Z2i::Space> flower(Z2i::Point(0,0), radius, varsmallradius,k,phi);
522 Z2i::Domain domain(flower.getLowerBound(), flower.getUpperBound());
523 Z2i::DigitalSet aSet(domain);
524
525 Shapes<Z2i::Domain>::euclideanShaper(aSet, flower);
526 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
527
528 if (signatureOpt->count()>0)
529 Exporter<Z2i::DigitalSet,Image>::exportSignature(flower,aSet,domain);
530
531 return 0;
532 }
533 else
534 //if (id ==6)
535 {
536 if (axis1Opt->count()==0) missingParam("--axis1");
537 if (axis2Opt->count()==0) missingParam("--axis2");
538 //if (phiOpt->count()==0) missingParam("--phi");
539 Ellipse2D<Z2i::Space> ell(Z2i::Point(0,0), axis1, axis2,phi);
540 Z2i::Domain domain(ell.getLowerBound(), ell.getUpperBound());
541 Z2i::DigitalSet aSet(domain);
542
543 Shapes<Z2i::Domain>::euclideanShaper(aSet, ell);
544 Exporter<Z2i::DigitalSet,Image>::save(aSet,outputName,outputFormat);
545
546 if (signatureOpt->count()>0)
547 Exporter<Z2i::DigitalSet,Image>::exportSignature(ell,aSet,domain);
548
549 return 0;
550 }
551}
Definition ATu0v1.h:57