DGtal 1.4.0
Loading...
Searching...
No Matches
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
47using namespace std;
48using namespace DGtal;
49
51// Functions for testing class ImageAdapter.
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
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
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 > ));
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
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
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
461int 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...
const ConstIterator & begin() const
const ConstIterator & end() const
Aim: implements an image adapter with a given domain (i.e. a subdomain) and 3 functors : g for domain...
void beginBlock(const std::string &keyword="")
std::ostream & warning()
std::ostream & emphase()
std::ostream & info()
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:151
void saveSVG(const char *filename, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition Board.cpp:1011
void saveCairo(const char *filename, CairoType type=CairoPNG, PageSize size=Board::BoundingBox, double margin=10.0) const
Definition Board.cpp:1138
Space::Point Point
Definition StdDefs.h:95
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition Common.h:153
STL namespace.
static void drawImage(DGtal::Board2D &board, const Image &i, const typename Image::Value &minV, const typename Image::Value &maxV)
static ImageContainer importPGM(const std::string &aFilename, const Functor &aFunctor=Functor(), bool topbotomOrder=true)
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.
int main()
Definition testBits.cpp:56
bool testSimple()
bool test_g_f_fm1()
bool testImageAdapter()
bool test_range_constRange()
Domain domain