DGtal  1.2.0
testImageAdapter.cpp
Go to the documentation of this file.
1 
31 #include <iostream>
32 #include "DGtal/base/Common.h"
33 #include "DGtal/helpers/StdDefs.h"
34 #include "DGtal/images/ImageContainerBySTLVector.h"
35 
36 //#define DEBUG_VERBOSE
37 
38 #include "DGtal/images/ImageAdapter.h"
39 #include "DGtal/images/ConstImageAdapter.h"
40 #include "DGtal/io/colormaps/GrayscaleColorMap.h"
41 #include "DGtal/io/readers/PGMReader.h"
42 #include "DGtal/io/boards/Board2D.h"
43 
44 #include "ConfigTest.h"
46 
47 using namespace std;
48 using namespace DGtal;
49 
51 // Functions for testing class ImageAdapter.
53 bool testSimple()
54 {
55  unsigned int nbok = 0;
56  unsigned int nb = 0;
57 
58  trace.beginBlock("Testing simple ImageAdapter");
59 
61 
62  VImage image(Z2i::Domain(Z2i::Point(0,0), Z2i::Point(10,10)));
63  for (VImage::Iterator it = image.begin(); it != image.end(); ++it)
64  *it = 10;
65 
66  trace.info() << "Original image: " << image << endl;
67 
70  BOOST_CONCEPT_ASSERT(( concepts::CImage< MyImageAdapter > ));
71 
74  functors::Identity idVm1;
75 
76  MyImageAdapter restimage(image, domain, idD, idV, idVm1);
77  trace.info() << "Restricted Image: " << restimage << " " << restimage.domain() << std::endl;
78 
79  nbok += (restimage(Z2i::Point(3,3)) == 10) ? 1 : 0;
80  nb++;
81  trace.info() << "(" << nbok << "/" << nb << ") "
82  << " read access on restricted Image" << endl;
83 
84  restimage.setValue(Z2i::Point(3,3), 5);
85  nbok += (restimage(Z2i::Point(3,3)) == 5) ? 1 : 0;
86  nb++;
87  trace.info() << "(" << nbok << "/" << nb << ") "
88  << " write on restricted Image" << endl;
89 
90  nbok += (image(Z2i::Point(3,3)) == 5) ? 1 : 0;
91  nb++;
92  trace.info() << "(" << nbok << "/" << nb << ") "
93  << " written on original image" << endl;
94 
95  trace.warning()<< "Original image at (3,3) = "<< (image)(Z2i::Point(3,3)) << std::endl;
96 
97  trace.endBlock();
98 
99  return nbok == nb;
100 }
101 
109  template <typename TValue>
110  class MyTransValueFunctor
111  {
112  public:
113  typedef TValue Value;
114 
119  MyTransValueFunctor(const Value& aValue = 0)
120  :myValue(aValue) {};
121 
130  template <typename TInput>
131  inline
132  Value operator()(const TInput& aInput) const
133  {
134  return aInput+myValue;
135  }
136 
137  private:
141  Value myValue;
142 
143  };
144 
146 {
147  unsigned int nbok = 0;
148  unsigned int nb = 0;
149 
150  trace.beginBlock("Testing g, f and fm1 with ImageAdapter");
151 
153 
154  VImage image(Z2i::Domain(Z2i::Point(0,0), Z2i::Point(10,10)));
155  for (VImage::Iterator it = image.begin(); it != image.end(); ++it)
156  *it = 10;
157 
158  trace.info() << "Original image: " << image << endl;
159 
160  //ConstAdapter
163  BOOST_CONCEPT_ASSERT(( concepts::CConstImage< MyImageAdapter > ));
164  functors::Identity idD;
166  MyImageAdapter restimage(image, domain, idD, idV);
167  trace.info() << "Restricted Image: " << restimage << " " << restimage.domain() << std::endl;
168  nbok += (restimage(Z2i::Point(3,3)) == 3) ? 1 : 0;
169  nb++;
170  trace.info() << "(" << nbok << "/" << nb << ") "
171  << " read access on restricted Image" << endl;
172 
175  BOOST_CONCEPT_ASSERT(( concepts::CImage< MyImageAdapter2 > ));
176 
177  functors::Identity idD_2;
180 
181  MyImageAdapter2 restimage2(image, domain, idD_2, idV_2, idVm1_2);
183 
184  restimage2.setValue(Z2i::Point(2,2), true);
185  nbok += (restimage2(Z2i::Point(2,2)) == true) ? 1 : 0;
186  nb++;
187  trace.info() << "(" << nbok << "/" << nb << ") "
188  << " write on restricted Image 2" << endl;
189 
190  trace.warning()<< "Restricted image 2 at (2,2) = "<< (int)(restimage2)(Z2i::Point(2,2)) << std::endl;
191  trace.warning()<< "Original image at (2,2) = "<< (image)(Z2i::Point(2,2)) << std::endl;
192  trace.warning()<< "Original image at (3,3) = "<< (image)(Z2i::Point(3,3)) << std::endl;
193 
194  restimage2.setValue(Z2i::Point(2,2), false);
195  trace.warning()<< "Restricted image with false at (2,2) = "<< (int)(restimage2)(Z2i::Point(2,2)) << std::endl;
196  nbok += (restimage2(Z2i::Point(2,2)) == true) ? 1 : 0;
197  nb++;
198  trace.info() << "(" << nbok << "/" << nb << ") "
199  << " write on restricted Image 2" << endl;
200 
201  trace.warning()<< "Restricted image 2 at (2,2) = "<< (restimage2)(Z2i::Point(2,2)) << std::endl;
202  trace.warning()<< "Original image at (2,2) = "<< (image)(Z2i::Point(2,2)) << std::endl;
203 
205  BOOST_CONCEPT_ASSERT(( concepts::CImage< MyImageAdapter3 > ));
206 
207  MyTransValueFunctor<Z2i::Point> idD_3(Z2i::Point(2,2));
208  functors::Identity idV_3;
209  functors::Identity idVm1_3;
210 
211  MyImageAdapter3 restimage3(image, domain, idD_3, idV_3, idVm1_3);
212 
213  restimage3.setValue(Z2i::Point(2,2), 5);
214  nbok += (image(Z2i::Point(4,4)) == 5) ? 1 : 0;
215  nb++;
216  trace.info() << "(" << nbok << "/" << nb << ") "
217  << " write on restricted Image 3" << endl;
218 
219  trace.warning()<< "Original image at (2,2) = "<< (image)(Z2i::Point(2,2)) << std::endl;
220  trace.warning()<< "Original image at (4,4) = "<< (image)(Z2i::Point(4,4)) << std::endl;
221  trace.warning()<< "Original image at (5,5) = "<< (image)(Z2i::Point(5,5)) << std::endl;
222 
223  trace.endBlock();
224 
225  return nbok == nb;
226 }
227 
229 {
230  unsigned int nbok = 0;
231  unsigned int nb = 0;
232 
233  trace.beginBlock("Testing range/constRange with ImageAdapter");
234 
236 
237  VImage image(Z2i::Domain(Z2i::Point(0,0), Z2i::Point(10,10)));
238  for (VImage::Iterator it = image.begin(); it != image.end(); ++it)
239  *it = 10;
240 
241  trace.info() << "Original image: " << image << endl;
242 
245  BOOST_CONCEPT_ASSERT(( concepts::CImage< MyImageAdapter > ));
246 
247  functors::Identity idD;
248  functors::Identity idV;
249  functors::Identity idVm1;
250 
251  MyImageAdapter restimage(image, domain, idD, idV, idVm1);
252  trace.info() << "Restricted Image: " << restimage << " " << restimage.domain() << std::endl;
253 
254  // writing values
255  const int maximalValue = domain.size();
256  MyImageAdapter::Range::OutputIterator it = restimage.range().outputIterator();
257  for (int i = 0; i < maximalValue; ++i)
258  *it++ = i;
259 
260  // reading values
261  MyImageAdapter::ConstRange r = restimage.constRange();
262  std::copy( r.begin(), r.end(), std::ostream_iterator<int>(cout,", ") );
263  cout << endl;
264 
265  std::vector<int> to_vector(9);
266  std::copy(r.begin(), r.end(), to_vector.begin());
267  for (int i = 0; i < 9; i++)
268  {
269  if (to_vector[i]==i)
270  {
271  cout << "ok, ";
272  nbok += 1 ;
273  nb++;
274  }
275  else
276  {
277  cout << "!ok, ";
278  nb++;
279  }
280  }
281 
282  cout << endl;
283 
284  trace.endBlock();
285 
286  return nbok == nb;
287 }
288 
290 {
291  unsigned int nbok = 0;
292  unsigned int nb = 0;
293 
294  trace.beginBlock ("Testing ImageAdapter");
295 
298 
299  string filename = testPath + "samples/church-small.pgm";
300  VImage image = PGMReader<VImage>::importPGM(filename);
301  trace.info() << "Imported image: " << image << endl;
302 
303  Board2D aBoard;
304 
305  Display2DFactory::drawImage<Gray>(aBoard, image, (unsigned char)0, (unsigned char)255);
306  aBoard.saveSVG("church.svg");
307 #ifdef WITH_CAIRO
308  aBoard.saveCairo("church.png", Board2D::CairoPNG);
309 #endif
310 
312  BOOST_CONCEPT_ASSERT(( concepts::CImage< MyImageAdapter > ));
313 
314  // 1) bell_tower
316  Z2i::Point p1( 43, 107 );
317  Z2i::Point p2( 73, 177 );
318  Z2i::Domain domain_bell_tower( p1, p2 );
319 
320  functors::Identity idbtD, idbtV, idbtVm1;
321  MyImageAdapter bell_tower(image, domain_bell_tower, idbtD, idbtV, idbtVm1);
323 
324  trace.info() << "ImageAdapter: " << bell_tower << " " << bell_tower.domain() << std::endl;
325 
326  nbok += bell_tower.isValid() ? 1 : 0;
327  nb++;
328 
329  aBoard.clear();
330  Display2DFactory::drawImage<Gray>(aBoard, bell_tower, (unsigned char)0, (unsigned char)255);
331  aBoard.saveSVG("bell_tower.svg");
332 #ifdef WITH_CAIRO
333  aBoard.saveCairo("bell_tower.png", Board2D::CairoPNG);
334 #endif
335 
336  // 2) cars
337  Z2i::Point p3( 0, 49 );
338  Z2i::Point p4( 58, 72 );
339  Z2i::Domain domain_cars( p3, p4 );
340 
341  functors::Identity idcD;
342  functors::Identity idcV;
343  functors::Identity idcVm1;
344  MyImageAdapter cars(image, domain_cars, idcD, idcV, idcVm1);
345 
346  trace.info() << "ImageAdapter: " << cars << " " << cars.domain() << std::endl;
347 
348  nbok += cars.isValid() ? 1 : 0;
349  nb++;
350 
351  aBoard.clear();
352  Display2DFactory::drawImage<Gray>(aBoard, cars, (unsigned char)0, (unsigned char)255);
353  aBoard.saveSVG("cars.svg");
354 #ifdef WITH_CAIRO
355  aBoard.saveCairo("cars.png", Board2D::CairoPNG);
356 #endif
357 
358  // 3) fill 255 for 'bell_tower' image
359  MyImageAdapter::Domain::ConstIterator bt_it = bell_tower.domain().begin();
360  MyImageAdapter::Domain::ConstIterator bt_itEnd = bell_tower.domain().end();
361  for (; bt_it != bt_itEnd; ++bt_it)
362  {
363  bell_tower.setValue(*bt_it, 255);
364  }
365 
366  aBoard.clear();
367  Display2DFactory::drawImage<Gray>(aBoard, bell_tower, (unsigned char)0, (unsigned char)255);
368  aBoard.saveSVG("bell_tower_after_filling.svg");
369 #ifdef WITH_CAIRO
370  aBoard.saveCairo("bell_tower_after_filling.png", Board2D::CairoPNG);
371 #endif
372 
373  // 4) fill 55 for 'cars' image
374  MyImageAdapter::Domain::ConstIterator c_it = cars.domain().begin();
375  MyImageAdapter::Domain::ConstIterator c_itEnd = cars.domain().end();
376  for (; c_it != c_itEnd; ++c_it)
377  {
378  cars.setValue(*c_it, 55);
379  }
380 
381  aBoard.clear();
382  Display2DFactory::drawImage<Gray>(aBoard, cars, (unsigned char)0, (unsigned char)255);
383  aBoard.saveSVG("cars_after_filling.svg");
384 #ifdef WITH_CAIRO
385  aBoard.saveCairo("cars_after_filling.png", Board2D::CairoPNG);
386 #endif
387 
388  // 5) fill 0 (only for one pixel on two) for 'floor_lamp' image
390  Z2i::Point p5( 56, 33 );
391  Z2i::Point p6( 68, 79 );
392  Z2i::Domain domain_floor_lamp( p5, p6 );
393 
394  // --- DigitalSetDomain
395  Z2i::DigitalSet mySet( domain_floor_lamp );
396 
397  unsigned int i = 0;
398  for ( Z2i::Domain::ConstIterator it = domain_floor_lamp.begin() ;
399  it != domain_floor_lamp.end();
400  ++it, ++i )
401  {
402  if (i%2)
403  mySet.insertNew( *it );
404  }
405 
406  DigitalSetDomain<Z2i::DigitalSet> my_specific_domain_floor_lamp(mySet);
407  // --- DigitalSetDomain
408 
409 
411  // BOOST_CONCEPT_ASSERT(( CImage< MyImageAdapter2 > )); // pb here
412 
413  functors::Identity idflD, idflV, idflVm1;
414  MyImageAdapter2 floor_lamp(image, my_specific_domain_floor_lamp, idflD, idflV, idflVm1);
416 
417  trace.info() << "ImageAdapter: " << floor_lamp << " " << floor_lamp.domain() << std::endl;
418 
419  nbok += floor_lamp.isValid() ? 1 : 0;
420  nb++;
421 
422  aBoard.clear();
423  Display2DFactory::drawImage<Gray>(aBoard, floor_lamp, (unsigned char)0, (unsigned char)255);
424  aBoard.saveSVG("floor_lamp.svg");
425 #ifdef WITH_CAIRO
426  aBoard.saveCairo("floor_lamp.png", Board2D::CairoPNG);
427 #endif
428 
429  MyImageAdapter2::Domain::ConstIterator f_it = floor_lamp.domain().begin();
430  MyImageAdapter2::Domain::ConstIterator f_itEnd = floor_lamp.domain().end();
431  for (; f_it != f_itEnd; ++f_it)
432  {
433  floor_lamp.setValue(*f_it, 0);
434  }
435 
436  aBoard.clear();
437  Display2DFactory::drawImage<Gray>(aBoard, floor_lamp, (unsigned char)0, (unsigned char)255);
438  aBoard.saveSVG("floor_lamp_after_filling.svg");
439 #ifdef WITH_CAIRO
440  aBoard.saveCairo("floor_lamp_after_filling.png", Board2D::CairoPNG);
441 #endif
442 
443  aBoard.clear();
444  Display2DFactory::drawImage<Gray>(aBoard, image, (unsigned char)0, (unsigned char)255);
445  aBoard.saveSVG("church_after_filling.svg");
446 #ifdef WITH_CAIRO
447  aBoard.saveCairo("church_after_filling.png", Board2D::CairoPNG);
448 #endif
449 
450  trace.info() << "(" << nbok << "/" << nb << ") "
451  << "true == true" << endl;
452  trace.endBlock();
453 
454  return nbok == nb;
455 }
456 
457 
459 // Standard services - public :
460 
461 int main( int argc, char** argv )
462 {
463  trace.beginBlock ( "Testing class ImageAdapter" );
464  trace.info() << "Args:";
465  for ( int i = 0; i < argc; ++i )
466  trace.info() << " " << argv[ i ];
467  trace.info() << endl;
468 
469  bool res = testSimple() && test_g_f_fm1() && test_range_constRange() && testImageAdapter(); // && ... other tests
470 
471  trace.emphase() << ( res ? "Passed." : "Error." ) << endl;
472  trace.endBlock();
473  return res ? 0 : 1;
474 }
475 // //
Aim: This class specializes a 'Board' class so as to display DGtal objects more naturally (with <<)....
Definition: Board2D.h:71
Aim: implements a const image adapter with a given domain (i.e. a subdomain) and 2 functors : g for d...
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: Constructs a domain limited to the given digital set.
Aim: This class template may be used to (linearly) convert scalar values in a given range into gray l...
Iterator for HyperRectDomain.
const ConstIterator & end() const
const ConstIterator & begin() const
Aim: implements an image adapter with a given domain (i.e. a subdomain) and 3 functors : g for domain...
Definition: ImageAdapter.h:110
void beginBlock(const std::string &keyword="")
std::ostream & emphase()
std::ostream & info()
std::ostream & warning()
double endBlock()
Aim: Define a simple functor that returns a constant value (0 by default).
Aim: A small functor with an operator () that compares one value to a threshold value according to tw...
void clear(const DGtal::Color &color=DGtal::Color::None)
Definition: Board.cpp:152
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1012
void saveCairo(const char *filename, CairoType type=CairoPNG, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition: Board.cpp:1139
MyDigitalSurface::ConstIterator ConstIterator
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition: Common.h:154
Aim: Import a 2D or 3D using the Netpbm formats (ASCII mode).
Definition: PGMReader.h:98
Aim: Defines the concept describing a read-only image, which is a refinement of CPointFunctor.
Definition: CConstImage.h:95
Aim: Defines the concept describing a read/write image, having an output iterator.
Definition: CImage.h:103
Aim: Define a simple functor using the static cast operator.
Aim: Define a simple default functor that just returns its argument.
MyPointD Point
Definition: testClone2.cpp:383
bool testSimple()
int main(int argc, char **argv)
bool test_g_f_fm1()
bool testImageAdapter()
bool test_range_constRange()
Domain domain
Image image(domain)
Image::ConstRange ConstRange