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