[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

inspectimage.hxx
1 /************************************************************************/
2 /* */
3 /* Copyright 1998-2002 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35 
36 
37 #ifndef VIGRA_INSPECTIMAGE_HXX
38 #define VIGRA_INSPECTIMAGE_HXX
39 
40 #include <vector>
41 #include <algorithm>
42 #include "utilities.hxx"
43 #include "numerictraits.hxx"
44 #include "iteratortraits.hxx"
45 #include "functortraits.hxx"
46 #include "rgbvalue.hxx"
47 #include "inspector_passes.hxx"
48 
49 namespace vigra {
50 
51 /** \addtogroup InspectAlgo Algorithms to Inspect Images
52 
53  Apply read-only functor to every pixel
54 */
55 //@{
56 
57 /********************************************************/
58 /* */
59 /* inspectLine */
60 /* */
61 /********************************************************/
62 
63 template <class SrcIterator, class SrcAccessor, class Functor>
64 void
65 inspectLine(SrcIterator s,
66  SrcIterator send, SrcAccessor src,
67  Functor & f)
68 {
69  for(; s != send; ++s)
70  f(src(s));
71 }
72 
73 template <class SrcIterator, class SrcAccessor,
74  class MaskIterator, class MaskAccessor,
75  class Functor>
76 void
77 inspectLineIf(SrcIterator s,
78  SrcIterator send, SrcAccessor src,
79  MaskIterator m, MaskAccessor mask,
80  Functor & f)
81 {
82  for(; s != send; ++s, ++m)
83  if(mask(m))
84  f(src(s));
85 }
86 
87 template <class SrcIterator1, class SrcAccessor1,
88  class SrcIterator2, class SrcAccessor2,
89  class Functor>
90 void
91 inspectTwoLines(SrcIterator1 s1,
92  SrcIterator1 s1end, SrcAccessor1 src1,
93  SrcIterator2 s2, SrcAccessor2 src2,
94  Functor & f)
95 {
96  for(; s1 != s1end; ++s1, ++s2)
97  f(src1(s1), src2(s2));
98 }
99 
100 template <class SrcIterator1, class SrcAccessor1,
101  class SrcIterator2, class SrcAccessor2,
102  class MaskIterator, class MaskAccessor,
103  class Functor>
104 void
105 inspectTwoLinesIf(SrcIterator1 s1,
106  SrcIterator1 s1end, SrcAccessor1 src1,
107  SrcIterator2 s2, SrcAccessor2 src2,
108  MaskIterator m, MaskAccessor mask,
109  Functor & f)
110 {
111  for(; s1 != s1end; ++s1, ++s2, ++m)
112  if(mask(m))
113  f(src1(s1), src2(s2));
114 }
115 
116 /********************************************************/
117 /* */
118 /* inspectImage */
119 /* */
120 /********************************************************/
121 
122 /** \brief Apply read-only functor to every pixel in the image.
123 
124  This function can be used to collect statistics of the image etc.
125  The results must be stored in the functor, which serves as a return
126  value.
127  The function uses an accessor to access the pixel data.
128 
129  <b> Declarations:</b>
130 
131  pass arguments explicitly:
132  \code
133  namespace vigra {
134  template <class ImageIterator, class Accessor, class Functor>
135  void
136  inspectImage(ImageIterator upperleft, ImageIterator lowerright,
137  Accessor a, Functor & f)
138  }
139  \endcode
140 
141  use argument objects in conjunction with \ref ArgumentObjectFactories :
142  \code
143  namespace vigra {
144  template <class ImageIterator, class Accessor, class Functor>
145  void
146  inspectImage(triple<ImageIterator, ImageIterator, Accessor> img,
147  Functor & f)
148  }
149  \endcode
150 
151  <b> Usage:</b>
152 
153  <b>\#include</b> <vigra/inspectimage.hxx><br>
154  Namespace: vigra
155 
156  \code
157  // init functor
158  vigra::BImage img;
159 
160  vigra::FindMinMax<vigra::BImage::PixelType> minmax;
161 
162  vigra::inspectImage(srcImageRange(img), minmax);
163 
164  cout << "Min: " << minmax.min << " Max: " << minmax.max;
165 
166  \endcode
167 
168  <b> Required Interface:</b>
169 
170  \code
171  ConstImageIterator upperleft, lowerright;
172  ConstImageIterator::row_iterator ix = upperleft.rowIterator();
173 
174  Accessor accessor;
175  Functor functor;
176 
177  functor(accessor(ix)); // return not used
178  \endcode
179 
180 */
181 doxygen_overloaded_function(template <...> void inspectImage)
182 
183 template <class ImageIterator, class Accessor>
184 struct inspectImage_binder
185 {
186  ImageIterator upperleft;
187  ImageIterator lowerright;
188  Accessor a;
189 
190  inspectImage_binder(ImageIterator ul, ImageIterator lr, Accessor ac)
191  : upperleft(ul), lowerright(lr), a(ac) {}
192  template <class Functor>
193  void operator()(Functor & f)
194  {
195  int w = lowerright.x - upperleft.x;
196 
197  for (ImageIterator t = upperleft; t.y < lowerright.y; ++t.y)
198  {
199  inspectLine(t.rowIterator(), t.rowIterator() + w, a, f);
200  }
201  }
202 };
203 
204 template <class ImageIterator, class Accessor, class Functor>
205 void
206 inspectImage(ImageIterator upperleft, ImageIterator lowerright,
207  Accessor a, Functor & f)
208 {
209  inspectImage_binder<ImageIterator, Accessor> g(upperleft, lowerright, a);
210  detail::extra_passes_select(g, f);
211 }
212 
213 template <class ImageIterator, class Accessor, class Functor>
214 inline
215 void
216 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img,
217  Functor & f)
218 {
219  inspectImage(img.first, img.second, img.third, f);
220 }
221 
222 namespace functor
223 {
224  template <class T> class UnaryAnalyser;
225 }
226 
227 template <class ImageIterator, class Accessor, class Functor>
228 inline
229 void
230 inspectImage(ImageIterator upperleft, ImageIterator lowerright,
231  Accessor a, functor::UnaryAnalyser<Functor> const & f)
232 {
233  inspectImage(upperleft, lowerright, a,
234  const_cast<functor::UnaryAnalyser<Functor> &>(f));
235 }
236 
237 template <class ImageIterator, class Accessor, class Functor>
238 inline
239 void
240 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img,
241  functor::UnaryAnalyser<Functor> const & f)
242 {
243  inspectImage(img.first, img.second, img.third,
244  const_cast<functor::UnaryAnalyser<Functor> &>(f));
245 }
246 
247 /********************************************************/
248 /* */
249 /* inspectImageIf */
250 /* */
251 /********************************************************/
252 
253 /** \brief Apply read-only functor to every pixel in the ROI.
254 
255  This function can be used to collect statistics of the roi etc.
256  The functor is called whenever the return value of the mask's
257  accessor is not zero.
258  The results must be stored in the functor, which serves as a return
259  value.
260  Accessors are used to access the pixel and mask data.
261 
262  <b> Declarations:</b>
263 
264  pass arguments explicitly:
265  \code
266  namespace vigra {
267  template <class ImageIterator, class Accessor,
268  class MaskImageIterator, class MaskAccessor, class Functor>
269  void
270  inspectImageIf(ImageIterator upperleft, ImageIterator lowerright,
271  MaskImageIterator mask_upperleft, MaskAccessor ma,
272  Functor & f)
273  }
274  \endcode
275 
276 
277  use argument objects in conjunction with \ref ArgumentObjectFactories :
278  \code
279  namespace vigra {
280  template <class ImageIterator, class Accessor,
281  class MaskImageIterator, class MaskAccessor, class Functor>
282  void
283  inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
284  pair<MaskImageIterator, MaskAccessor> mask,
285  Functor & f)
286  }
287  \endcode
288 
289  <b> Usage:</b>
290 
291  <b>\#include</b> <vigra/inspectimage.hxx><br>
292  Namespace: vigra
293 
294  \code
295  vigra::BImage img(100, 100);
296  vigra::BImage mask(100, 100);
297 
298  // init functor
299  vigra::FindMinMax<vigra::BImage::PixelType> minmax;
300 
301  vigra::inspectImageIf(srcImageRange(img),
302  maskImage(mask), minmax);
303 
304  cout << "Min: " << minmax.min << " Max: " << minmax.max;
305 
306  \endcode
307 
308  <b> Required Interface:</b>
309 
310  \code
311  ConstImageIterator upperleft, lowerright;
312  MaskImageIterator mask_upperleft;
313  ConstImageIterator::row_iterator ix = upperleft.rowIterator();
314  MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator();
315 
316  Accessor accessor;
317  MaskAccessor mask_accessor;
318 
319  Functor functor;
320 
321  if(mask_accessor(mx)) functor(accessor(ix));
322  \endcode
323 
324 */
325 doxygen_overloaded_function(template <...> void inspectImageIf)
326 
327 template <class ImageIterator, class Accessor,
328  class MaskImageIterator, class MaskAccessor>
329 struct inspectImageIf_binder
330 {
331  ImageIterator upperleft;
332  ImageIterator lowerright;
333  Accessor a;
334  MaskImageIterator mask_upperleft;
335  MaskAccessor ma;
336 
337  inspectImageIf_binder(ImageIterator ul, ImageIterator lr, Accessor ac,
338  MaskImageIterator m_ul, MaskAccessor m_ac)
339  : upperleft(ul), lowerright(lr), a(ac), mask_upperleft(m_ul), ma(m_ac)
340  {}
341  template <class Functor>
342  void operator()(Functor & f)
343  {
344  int w = lowerright.x - upperleft.x;
345 
346  MaskImageIterator mt = mask_upperleft;
347  for (ImageIterator t = upperleft; t.y < lowerright.y; ++t.y, ++mt.y)
348  {
349  inspectLineIf(t.rowIterator(),
350  t.rowIterator() + w, a,
351  mt.rowIterator(), ma, f);
352  }
353  }
354 };
355 
356 template <class ImageIterator, class Accessor,
357  class MaskImageIterator, class MaskAccessor, class Functor>
358 void
359 inspectImageIf(ImageIterator upperleft,
360  ImageIterator lowerright, Accessor a,
361  MaskImageIterator mask_upperleft, MaskAccessor ma,
362  Functor & f)
363 {
364  inspectImageIf_binder<ImageIterator, Accessor, MaskImageIterator,
365  MaskAccessor>
366  g(upperleft, lowerright, a, mask_upperleft, ma);
367  detail::extra_passes_select(g, f);
368 }
369 
370 template <class ImageIterator, class Accessor,
371  class MaskImageIterator, class MaskAccessor, class Functor>
372 inline
373 void
374 inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
375  pair<MaskImageIterator, MaskAccessor> mask,
376  Functor & f)
377 {
378  inspectImageIf(img.first, img.second, img.third,
379  mask.first, mask.second, f);
380 }
381 
382 template <class ImageIterator, class Accessor,
383  class MaskImageIterator, class MaskAccessor, class Functor>
384 inline void
385 inspectImageIf(ImageIterator upperleft,
386  ImageIterator lowerright, Accessor a,
387  MaskImageIterator mask_upperleft, MaskAccessor ma,
388  functor::UnaryAnalyser<Functor> const & f)
389 {
390  inspectImageIf(upperleft, lowerright, a,
391  mask_upperleft, ma, const_cast<functor::UnaryAnalyser<Functor> &>(f));
392 }
393 
394 template <class ImageIterator, class Accessor,
395  class MaskImageIterator, class MaskAccessor, class Functor>
396 inline void
397 inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
398  pair<MaskImageIterator, MaskAccessor> mask,
399  functor::UnaryAnalyser<Functor> const & f)
400 {
401  inspectImageIf(img.first, img.second, img.third,
402  mask.first, mask.second, const_cast<functor::UnaryAnalyser<Functor> &>(f));
403 }
404 
405 /********************************************************/
406 /* */
407 /* inspectTwoImages */
408 /* */
409 /********************************************************/
410 
411 /** \brief Apply read-only functor to every pixel of both images.
412 
413  This function can be used to collect statistics for each region of a
414  labeled image, especially in conjunction with
415  the \ref ArrayOfRegionStatistics functor. The results must be
416  stored in the functor which serves as a return value.
417  Accessors are used to access the pixel data.
418 
419  <b> Declarations:</b>
420 
421  pass arguments explicitly:
422  \code
423  namespace vigra {
424  template <class ImageIterator1, class Accessor1,
425  class ImageIterator2, class Accessor2,
426  class Functor>
427  void
428  inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
429  ImageIterator2 upperleft2, Accessor2 a2,
430  Functor & f)
431  }
432  \endcode
433 
434 
435  use argument objects in conjunction with \ref ArgumentObjectFactories :
436  \code
437  namespace vigra {
438  template <class ImageIterator1, class Accessor1,
439  class ImageIterator2, class Accessor2,
440  class Functor>
441  void
442  inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
443  pair<ImageIterator2, Accessor2> img2,
444  Functor & f)
445  }
446  \endcode
447 
448  <b> Usage:</b>
449 
450  <b>\#include</b> <vigra/inspectimage.hxx><br>
451  Namespace: vigra
452 
453  \code
454  vigra::BImage image1;
455  vigra::BImage image2;
456 
457  SomeStatisticsFunctor stats(...); // init functor
458 
459  vigra::inspectTwoImages(srcImageRange(image1), srcImage(image2),
460  stats);
461 
462 
463  \endcode
464 
465  <b> Required Interface:</b>
466 
467  \code
468  ImageIterator1 upperleft1, lowerright1;
469  ImageIterator2 upperleft2;
470  ImageIterator1::row_iterator ix1 = upperleft1.rowIterator();
471  ImageIterator2::row_iterator ix2 = upperleft2.rowIterator();
472 
473  Accessor1 accessor1;
474  Accessor2 accessor2;
475 
476  Functor functor;
477  functor(accessor1(ix1), accessor2(ix2)); // return not used
478  \endcode
479 
480 */
481 doxygen_overloaded_function(template <...> void inspectTwoImages)
482 
483 template <class ImageIterator1, class Accessor1,
484  class ImageIterator2, class Accessor2>
485 struct inspectTwoImages_binder
486 {
487  ImageIterator1 upperleft1;
488  ImageIterator1 lowerright1;
489  Accessor1 a1;
490  ImageIterator2 upperleft2;
491  Accessor2 a2;
492  inspectTwoImages_binder(ImageIterator1 u1, ImageIterator1 l1, Accessor1 a1_,
493  ImageIterator2 u2, Accessor2 a2_)
494  : upperleft1(u1), lowerright1(l1), a1(a1_), upperleft2(u2), a2(a2_) {}
495  template <class Functor>
496  void operator()(Functor & f)
497  {
498  int w = lowerright1.x - upperleft1.x;
499 
500  ImageIterator1 t1 = upperleft1;
501  ImageIterator2 t2 = upperleft2;
502  for (; t1.y < lowerright1.y; ++t1.y, ++t2.y)
503  {
504  inspectTwoLines(t1.rowIterator(),
505  t1.rowIterator() + w, a1,
506  t2.rowIterator(), a2, f);
507  }
508  }
509 };
510 
511 template <class ImageIterator1, class Accessor1,
512  class ImageIterator2, class Accessor2,
513  class Functor>
514 void
515 inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1,
516  Accessor1 a1,
517  ImageIterator2 upperleft2, Accessor2 a2,
518  Functor & f)
519 {
520  inspectTwoImages_binder<ImageIterator1, Accessor1,
521  ImageIterator2, Accessor2>
522  g(upperleft1, lowerright1, a1, upperleft2, a2);
523  detail::extra_passes_select(g, f);
524 }
525 
526 template <class ImageIterator1, class Accessor1,
527  class ImageIterator2, class Accessor2,
528  class Functor>
529 inline
530 void
531 inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
532  pair<ImageIterator2, Accessor2> img2,
533  Functor & f)
534 {
535  inspectTwoImages(img1.first, img1.second, img1.third,
536  img2.first, img2.second, f);
537 }
538 
539 template <class ImageIterator1, class Accessor1,
540  class ImageIterator2, class Accessor2,
541  class Functor>
542 inline void
543 inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
544  ImageIterator2 upperleft2, Accessor2 a2,
545  functor::UnaryAnalyser<Functor> const & f)
546 {
547  inspectTwoImages(upperleft1, lowerright1, a1,
548  upperleft2, a2, const_cast<functor::UnaryAnalyser<Functor> &>(f));
549 }
550 
551 template <class ImageIterator1, class Accessor1,
552  class ImageIterator2, class Accessor2,
553  class Functor>
554 inline
555 void
556 inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
557  pair<ImageIterator2, Accessor2> img2,
558  functor::UnaryAnalyser<Functor> const & f)
559 {
560  inspectTwoImages(img1.first, img1.second, img1.third,
561  img2.first, img2.second, const_cast<functor::UnaryAnalyser<Functor> &>(f));
562 }
563 
564 /********************************************************/
565 /* */
566 /* inspectTwoImagesIf */
567 /* */
568 /********************************************************/
569 
570 /** \brief Apply read-only functor to those pixels of both images where
571  the mask image is non-zero.
572 
573  This function can be used to collect statistics for selected regions of a
574  labeled image, especially in conjunction with
575  the \ref ArrayOfRegionStatistics functor. The results must be
576  stored in the functor which serves as a return value.
577  Accessors are used to access the pixel data.
578 
579  <b> Declarations:</b>
580 
581  pass arguments explicitly:
582  \code
583  namespace vigra {
584  template <class ImageIterator1, class Accessor1,
585  class ImageIterator2, class Accessor2,
586  class MaskImageIterator, class MaskAccessor,
587  class Functor>
588  void
589  inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
590  ImageIterator2 upperleft2, Accessor2 a2,
591  MaskImageIterator mupperleft, MaskAccessor mask,
592  Functor & f)
593  }
594  \endcode
595 
596 
597  use argument objects in conjunction with \ref ArgumentObjectFactories :
598  \code
599  namespace vigra {
600  template <class ImageIterator1, class Accessor1,
601  class ImageIterator2, class Accessor2,
602  class MaskImageIterator, class MaskAccessor,
603  class Functor>
604  void
605  inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
606  pair<ImageIterator2, Accessor2> img2,
607  pair<MaskImageIterator, MaskAccessor> mimg,
608  Functor & f)
609  }
610  \endcode
611 
612  <b> Usage:</b>
613 
614  <b>\#include</b> <vigra/inspectimage.hxx><br>
615  Namespace: vigra
616 
617  \code
618  vigra::BImage image1;
619  vigra::BImage image2;
620  vigra::BImage maskimage;
621 
622  SomeStatisticsFunctor stats(...); // init functor
623 
624  vigra::inspectTwoImagesIf(srcImageRange(image1), srcImage(image2),
625  srcImage(maskimage), region_stats);
626 
627  \endcode
628 
629  <b> Required Interface:</b>
630 
631  \code
632  ImageIterator1 upperleft1, lowerright1;
633  ImageIterator2 upperleft2;
634  MaskImageIterator upperleftm;
635  ImageIterator1::row_iterator ix1 = upperleft1.rowIterator();
636  ImageIterator2::row_iterator ix2 = upperleft2.rowIterator();
637  MaskImageIterator::row_iterator mx = mupperleft.rowIterator();
638 
639  Accessor1 accessor1;
640  Accessor2 accessor2;
641  MaskAccessor mask;
642 
643  Functor functor;
644  if(mask(mx))
645  functor(accessor1(ix1), accessor2(ix2));
646  \endcode
647 
648 */
649 doxygen_overloaded_function(template <...> void inspectTwoImagesIf)
650 
651 template <class ImageIterator1, class Accessor1,
652  class ImageIterator2, class Accessor2,
653  class MaskImageIterator, class MaskAccessor>
654 struct inspectTwoImagesIf_binder
655 {
656  ImageIterator1 upperleft1;
657  ImageIterator1 lowerright1;
658  Accessor1 a1;
659  ImageIterator2 upperleft2;
660  Accessor2 a2;
661  MaskImageIterator mupperleft;
662  MaskAccessor mask;
663  inspectTwoImagesIf_binder(ImageIterator1 u1, ImageIterator1 l1,
664  Accessor1 a1_, ImageIterator2 u2, Accessor2 a2_,
665  MaskImageIterator mu, MaskAccessor ma)
666  : upperleft1(u1), lowerright1(l1), a1(a1_), upperleft2(u2), a2(a2_),
667  mupperleft(mu), mask(ma) {}
668  template <class Functor>
669  void operator()(Functor & f)
670  {
671  int w = lowerright1.x - upperleft1.x;
672 
673  ImageIterator1 t1 = upperleft1;
674  ImageIterator2 t2 = upperleft2;
675  MaskImageIterator mu = mupperleft;
676  for(; t1.y < lowerright1.y; ++t1.y, ++t2.y, ++mu.y)
677  {
678  inspectTwoLinesIf(t1.rowIterator(),
679  t1.rowIterator() + w, a1,
680  t2.rowIterator(), a2,
681  mu.rowIterator(), mask, f);
682  }
683  }
684 };
685 
686 template <class ImageIterator1, class Accessor1,
687  class ImageIterator2, class Accessor2,
688  class MaskImageIterator, class MaskAccessor,
689  class Functor>
690 void
691 inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1,
692  Accessor1 a1,
693  ImageIterator2 upperleft2, Accessor2 a2,
694  MaskImageIterator mupperleft, MaskAccessor mask,
695  Functor & f)
696 {
697  inspectTwoImagesIf_binder<ImageIterator1, Accessor1,
698  ImageIterator2, Accessor2,
699  MaskImageIterator, MaskAccessor>
700  g(upperleft1, lowerright1, a1, upperleft2, a2, mupperleft, mask);
701  detail::extra_passes_select(g, f);
702 }
703 
704 template <class ImageIterator1, class Accessor1,
705  class ImageIterator2, class Accessor2,
706  class MaskImageIterator, class MaskAccessor,
707  class Functor>
708 inline
709 void
710 inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
711  pair<ImageIterator2, Accessor2> img2,
712  pair<MaskImageIterator, MaskAccessor> m,
713  Functor & f)
714 {
715  inspectTwoImagesIf(img1.first, img1.second, img1.third,
716  img2.first, img2.second,
717  m.first, m.second,
718  f);
719 }
720 
721 template <class ImageIterator1, class Accessor1,
722  class ImageIterator2, class Accessor2,
723  class MaskImageIterator, class MaskAccessor,
724  class Functor>
725 inline void
726 inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
727  ImageIterator2 upperleft2, Accessor2 a2,
728  MaskImageIterator mupperleft, MaskAccessor mask,
729  functor::UnaryAnalyser<Functor> const & f)
730 {
731  inspectTwoImagesIf(upperleft1, lowerright1, a1,
732  upperleft2, a2,
733  mupperleft, mask,
734  const_cast<functor::UnaryAnalyser<Functor> &>(f));
735 }
736 
737 template <class ImageIterator1, class Accessor1,
738  class ImageIterator2, class Accessor2,
739  class MaskImageIterator, class MaskAccessor,
740  class Functor>
741 inline
742 void
743 inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
744  pair<ImageIterator2, Accessor2> img2,
745  pair<MaskImageIterator, MaskAccessor> m,
746  functor::UnaryAnalyser<Functor> const & f)
747 {
748  inspectTwoImagesIf(img1.first, img1.second, img1.third,
749  img2.first, img2.second,
750  m.first, m.second,
751  const_cast<functor::UnaryAnalyser<Functor> &>(f));
752 }
753 
754 //@}
755 
756 /** \addtogroup InspectFunctor Functors To Inspect Images
757  Functors which report image statistics
758 */
759 //@{
760 
761 /********************************************************/
762 /* */
763 /* FindMinMax */
764 /* */
765 /********************************************************/
766 
767 /** \brief Find the minimum and maximum pixel value in an image or ROI.
768 
769  In addition the size of the ROI is calculated.
770  These functors can also be used in conjunction with
771  \ref ArrayOfRegionStatistics to find the extremes of all regions in
772  a labeled image.
773 
774  <b> Traits defined:</b>
775 
776  <tt>FunctorTraits::isUnaryAnalyser</tt> is true (<tt>VigraTrueType</tt>)
777 
778  <b> Usage:</b>
779 
780  <b>\#include</b> <vigra/inspectimage.hxx><br>
781  Namespace: vigra
782 
783  \code
784  vigra::BImage img;
785 
786  vigra::FindMinMax<vigra::BImage::PixelType> minmax; // init functor
787 
788  vigra::inspectImage(srcImageRange(img), minmax);
789 
790  cout << "Min: " << minmax.min << " Max: " << minmax.max;
791 
792  \endcode
793 
794  <b> Required Interface:</b>
795 
796  \code
797  VALUETYPE v1, v2(v1);
798 
799  v1 < v2;
800  v1 = v2;
801  \endcode
802 
803 */
804 template <class VALUETYPE>
806 {
807  public:
808 
809  /** the functor's argument type
810  */
811  typedef VALUETYPE argument_type;
812 
813  /** the functor's result type
814  */
815  typedef VALUETYPE result_type;
816 
817  /** \deprecated use argument_type
818  */
819  typedef VALUETYPE value_type;
820 
821  /** init min and max
822  */
824  : min( NumericTraits<value_type>::max() ),
825  max( NumericTraits<value_type>::min() ),
826  count(0)
827  {}
828 
829  /** (re-)init functor (clear min, max)
830  */
831  void reset()
832  {
833  count = 0;
834  }
835 
836  /** update min and max
837  */
838  void operator()(argument_type const & v)
839  {
840  if(count)
841  {
842  if(v < min) min = v;
843  if(max < v) max = v;
844  }
845  else
846  {
847  min = v;
848  max = v;
849  }
850  ++count;
851  }
852 
853  /** update min and max with components of RGBValue<VALUETYPE>
854  */
856  {
857  operator()(v.red());
858  operator()(v.green());
859  operator()(v.blue());
860  }
861 
862  /** merge two statistics
863  */
864  void operator()(FindMinMax const & v)
865  {
866  if(v.count)
867  {
868  if(count)
869  {
870  if(v.min < min) min = v.min;
871  if((this->max) < v.max) max = v.max;
872  }
873  else
874  {
875  min = v.min;
876  max = v.max;
877  }
878  }
879  count += v.count;
880  }
881 
882  /** the current min
883  */
884  VALUETYPE min;
885 
886  /** the current max
887  */
888  VALUETYPE max;
889 
890  /** the number of values processed so far
891  */
892  unsigned int count;
893 
894 };
895 
896 template <class VALUETYPE>
897 class FunctorTraits<FindMinMax<VALUETYPE> >
898 : public FunctorTraitsBase<FindMinMax<VALUETYPE> >
899 {
900  public:
901  typedef VigraTrueType isUnaryAnalyser;
902 };
903 
904 /********************************************************/
905 /* */
906 /* FindSum */
907 /* */
908 /********************************************************/
909 
910 /** \brief Find the sum of the pixel values in an image or ROI.
911 
912  This Functor can also be used in conjunction with
913  \ref ArrayOfRegionStatistics to find the sum of all regions in
914  a labeled image, and with the reduce mode of transformMultiArray().
915 
916  <b> Traits defined:</b>
917 
918  <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
919  are true (<tt>VigraTrueType</tt>)
920 
921  <b> Usage:</b>
922 
923  <b>\#include</b> <vigra/inspectimage.hxx><br>
924  Namespace: vigra
925 
926  \code
927  vigra::BImage img;
928 
929  vigra::FindSum<vigra::BImage::PixelType> sum; // init functor
930 
931  vigra::inspectImage(srcImageRange(img), sum);
932 
933  cout << "Sum: " << sum();
934 
935  \endcode
936 
937  <b> Required Interface:</b>
938 
939  \code
940  VALUETYPE v1, v2(v1);
941 
942  v1 += v2;
943  \endcode
944 
945 */
946 template <class VALUETYPE>
947 class FindSum
948 : public UnaryReduceFunctorTag
949 {
950  public:
951 
952  /** the functor's argument type
953  */
954  typedef VALUETYPE argument_type;
955 
956  /** the functor's result type
957  */
958  typedef typename NumericTraits<VALUETYPE>::Promote result_type;
959 
960  /** init sum
961  */
963  : sum_(NumericTraits<result_type>::zero())
964  {}
965 
966  /** (re-)init sum
967  */
968  void reset()
969  {
970  sum_ = NumericTraits<result_type>::zero();
971  }
972 
973  /** update sum
974  */
975  void operator()(argument_type const & v)
976  {
977  sum_ += v;
978  }
979 
980  /** merge two statistics
981  */
982  void operator()(FindSum const & v)
983  {
984  sum_ += v.sum_;
985  }
986 
987  /** return current sum
988  */
989  result_type sum() const
990  {
991  return sum_;
992  }
993 
994  /** return current sum
995  */
997  {
998  return sum_;
999  }
1000 
1001  result_type sum_;
1002 };
1003 
1004 
1005 
1006 /********************************************************/
1007 /* */
1008 /* FindAverage */
1009 /* */
1010 /********************************************************/
1011 
1012 /** \brief Find the average pixel value in an image or ROI.
1013 
1014  In addition the size of the ROI is calculated.
1015  This Functor can also be used in conjunction with
1016  \ref ArrayOfRegionStatistics to find the average of all regions in
1017  a labeled image.
1018 
1019  <b> Traits defined:</b>
1020 
1021  <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
1022  are true (<tt>VigraTrueType</tt>)
1023 
1024  <b> Usage:</b>
1025 
1026  <b>\#include</b> <vigra/inspectimage.hxx><br>
1027  Namespace: vigra
1028 
1029  \code
1030  vigra::BImage img;
1031 
1032  vigra::FindAverage<vigra::BImage::PixelType> average; // init functor
1033 
1034  vigra::inspectImage(srcImageRange(img), average);
1035 
1036  cout << "Average: " << average();
1037 
1038  \endcode
1039 
1040  <b> Required Interface:</b>
1041 
1042  \code
1043  VALUETYPE v1, v2(v1);
1044  double d;
1045 
1046  v1 += v2;
1047  v1 / d;
1048  \endcode
1049 
1050 */
1051 template <class VALUETYPE>
1053 {
1054  public:
1055 
1056  /** the functor's argument type
1057  */
1058  typedef VALUETYPE argument_type;
1059 
1060  /** the functor's first argument type (for calls with a weight)
1061  */
1062  typedef VALUETYPE first_argument_type;
1063 
1064  /** the functor's second argument type (for calls with a weight)
1065  */
1066  typedef double second_argument_type;
1067 
1068  /** the functor's result type
1069  */
1070  typedef typename NumericTraits<VALUETYPE>::RealPromote result_type;
1071 
1072  /** \deprecated use argument_type and result_type
1073  */
1074  typedef typename NumericTraits<VALUETYPE>::RealPromote value_type;
1075 
1076  /** init average
1077  */
1079  : sum_(NumericTraits<result_type>::zero()), count_(0)
1080  {}
1081 
1082  /** (re-)init average
1083  */
1084  void reset()
1085  {
1086  count_ = 0;
1087  sum_ = NumericTraits<result_type>::zero();
1088  }
1089 
1090  /** update average
1091  */
1092  void operator()(argument_type const & v)
1093  {
1094  sum_ += v;
1095  ++count_;
1096  }
1097 
1098  /** update average, using weighted input.
1099  * <tt>stats(value, 1.0)</tt> is equivalent to the unweighted
1100  * call <tt>stats(value)</tt>, and <tt>stats(value, 2.0)</tt>
1101  * is equivalent to two unweighted calls.
1102  */
1104  {
1105  sum_ += v * weight;
1106  count_ += weight;
1107  }
1108 
1109  /** merge two statistics
1110  */
1111  void operator()(FindAverage const & v)
1112  {
1113  sum_ += v.sum_;
1114  count_ += v.count_;
1115  }
1116 
1117  /** return number of values (sum of weights) seen so far
1118  */
1119  double count() const
1120  {
1121  return count_;
1122  }
1123 
1124  /** return current average
1125  */
1127  {
1128  return sum_ / (double)count_;
1129  }
1130 
1131  /** return current average
1132  */
1134  {
1135  return sum_ / (double)count_;
1136  }
1137 
1138  result_type sum_;
1139  double count_;
1140 };
1141 
1142 template <class VALUETYPE>
1143 class FunctorTraits<FindAverage<VALUETYPE> >
1144 : public FunctorTraitsBase<FindAverage<VALUETYPE> >
1145 {
1146  public:
1147  typedef VigraTrueType isInitializer;
1148  typedef VigraTrueType isUnaryAnalyser;
1149 };
1150 
1151 /********************************************************/
1152 /* */
1153 /* FindAverageAndVariance */
1154 /* */
1155 /********************************************************/
1156 
1157 /** \brief Find the average pixel value and its variance in an image or ROI.
1158 
1159  This Functor uses West's algorithm to accumulate highly accurate values for
1160  the mean and the sum of squared differences of all values seen so far (the
1161  naive incremental algorithm for the computation of the sum of squares
1162  produces large round-off errors when the mean is much larger than the
1163  standard deviation of the data.) This Functor can also be used in
1164  conjunction with \ref ArrayOfRegionStatistics to find the statistics of all
1165  regions in a labeled image.
1166 
1167  <b> Traits defined:</b>
1168 
1169  <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
1170  are true (<tt>VigraTrueType</tt>)
1171 
1172  <b> Usage:</b>
1173 
1174  <b>\#include</b> <vigra/inspectimage.hxx><br>
1175  Namespace: vigra
1176 
1177  \code
1178  vigra::BImage img;
1179 
1180  vigra::FindAverageAndVariance<vigra::BImage::PixelType> averageAndVariance; // init functor
1181 
1182  vigra::inspectImage(srcImageRange(img), averageAndVariance);
1183 
1184  cout << "Average: " << averageAndVariance.average() << "\n";
1185  cout << "Standard deviation: " << sqrt(averageAndVariance.variance()) << "\n";
1186 
1187  \endcode
1188 
1189  <b> Required Interface:</b>
1190 
1191  \code
1192  VALUETYPE v1, v2(v1);
1193  double d;
1194 
1195  v1 += v2;
1196  v1 + v2;
1197  v1 - v2;
1198  v1 * v2;
1199  v1 / d;
1200  d * v1;
1201  \endcode
1202 
1203 */
1204 template <class VALUETYPE>
1206 {
1207  public:
1208 
1209  /** the functor's argument type
1210  */
1211  typedef VALUETYPE argument_type;
1212 
1213  /** the functor's first argument type (for calls with a weight)
1214  */
1215  typedef VALUETYPE first_argument_type;
1216 
1217  /** the functor's second argument type (for calls with a weight)
1218  */
1219  typedef double second_argument_type;
1220 
1221  /** the functor's result type
1222  */
1223  typedef typename NumericTraits<VALUETYPE>::RealPromote result_type;
1224 
1225  /** \deprecated use argument_type and result_type
1226  */
1227  typedef typename NumericTraits<VALUETYPE>::RealPromote value_type;
1228 
1229  /** init average
1230  */
1232  : mean_(NumericTraits<result_type>::zero()),
1233  sumOfSquaredDifferences_(NumericTraits<result_type>::zero()),
1234  count_(0.0)
1235  {}
1236 
1237  /** (re-)init average and variance
1238  */
1239  void reset()
1240  {
1241  count_ = 0.0;
1242  mean_ = NumericTraits<result_type>::zero();
1243  sumOfSquaredDifferences_ = NumericTraits<result_type>::zero();
1244  }
1245 
1246  /** update average and variance
1247  */
1248  void operator()(argument_type const & v)
1249  {
1250  ++count_;
1251  result_type t1 = v - mean_;
1252  result_type t2 = t1 / count_;
1253  mean_ += t2;
1254  sumOfSquaredDifferences_ += (count_-1.0)*t1*t2;
1255  }
1256 
1257  /** update average and variance, using weighted input.
1258  * <tt>stats(value, 1.0)</tt> is equivalent to the unweighted
1259  * call <tt>stats(value)</tt>, and <tt>stats(value, 2.0)</tt>
1260  * is equivalent to two unweighted calls.
1261  */
1263  {
1264  count_ += weight;
1265  result_type t1 = v - mean_;
1266  result_type t2 = t1 * weight / count_;
1267  mean_ += t2;
1268 
1269  //sumOfSquaredDifferences_ += (count_ - weight)*t1*t2;
1270 
1271  if(count_ > weight)
1272  sumOfSquaredDifferences_ +=
1273  (t1 * t1 * weight / count_) * (count_ - weight );
1274  }
1275 
1276  /** merge two statistics
1277  */
1279  {
1280  double newCount = count_ + v.count_;
1281  sumOfSquaredDifferences_ += v.sumOfSquaredDifferences_ +
1282  count_ / newCount * v.count_ * (mean_ - v.mean_) * (mean_ - v.mean_);
1283  mean_ = (count_ * mean_ + v.count_ * v.mean_) / newCount;
1284  count_ += v.count_;
1285  }
1286 
1287  /** return number of values (sum of weights) seen so far
1288  */
1289  unsigned int count() const
1290  {
1291  return (unsigned int)count_;
1292  }
1293 
1294  /** return current average
1295  */
1297  {
1298  return mean_;
1299  }
1300 
1301  /** return current variance.
1302  If <tt>unbiased = true</tt>, the sum of squared differences
1303  is divided by <tt>count()-1</tt> instead of just <tt>count()</tt>.
1304  */
1305  result_type variance(bool unbiased = false) const
1306  {
1307  return unbiased
1308  ? sumOfSquaredDifferences_ / (count_ - 1.0)
1309  : sumOfSquaredDifferences_ / count_;
1310  }
1311 
1312  /** return current variance. calls <tt>variance()</tt>.
1313  */
1315  {
1316  return variance();
1317  }
1318 
1319  result_type mean_, sumOfSquaredDifferences_;
1320  double count_;
1321 };
1322 
1323 template <class VALUETYPE>
1324 class FunctorTraits<FindAverageAndVariance<VALUETYPE> >
1325 : public FunctorTraitsBase<FindAverageAndVariance<VALUETYPE> >
1326 {
1327  public:
1328  typedef VigraTrueType isInitializer;
1329  typedef VigraTrueType isUnaryAnalyser;
1330 };
1331 
1332 /********************************************************/
1333 /* */
1334 /* FindROISize */
1335 /* */
1336 /********************************************************/
1337 
1338 /** \brief Calculate the size of an ROI in an image.
1339 
1340  This Functor is often used in conjunction with
1341  \ref ArrayOfRegionStatistics to find the sizes of all regions in
1342  a labeled image.
1343 
1344  <b> Traits defined:</b>
1345 
1346  <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
1347  are true (<tt>VigraTrueType</tt>)
1348 
1349  <b> Usage:</b>
1350 
1351  <b>\#include</b> <vigra/inspectimage.hxx><br>
1352  Namespace: vigra
1353 
1354  \code
1355  vigra::BImage img, mask;
1356 
1357  vigra::FindROISize<vigra::BImage::PixelType> roisize; // init functor
1358 
1359  vigra::inspectImageIf(srcImageRange(img), srcImage(mask), roisize);
1360 
1361  cout << "Size of ROI: " << roisize.count;
1362 
1363  \endcode
1364 
1365 */
1366 template <class VALUETYPE>
1368 {
1369  public:
1370 
1371  /** the functor's argument type
1372  */
1373  typedef VALUETYPE argument_type;
1374 
1375  /** the functor's result type
1376  */
1377  typedef unsigned int result_type;
1378 
1379  /** \deprecated use argument_type and result_type
1380  */
1381  typedef VALUETYPE value_type;
1382 
1383  /** init counter to 0
1384  */
1386  : count(0)
1387  {}
1388 
1389  /** (re-)init ROI size with 0
1390  */
1391  void reset()
1392  {
1393  count = 0;
1394  }
1395 
1396  /** update counter
1397  */
1399  {
1400  ++count;
1401  }
1402 
1403  /** return current size
1404  */
1406  {
1407  return count;
1408  }
1409 
1410  /** return current size
1411  */
1413  {
1414  return count;
1415  }
1416 
1417  /** merge two statistics
1418  */
1419  void operator()(FindROISize const & o)
1420  {
1421  count += o.count;
1422  }
1423 
1424  /** the current counter
1425  */
1427 
1428 };
1429 
1430 template <class VALUETYPE>
1431 class FunctorTraits<FindROISize<VALUETYPE> >
1432 : public FunctorTraitsBase<FindROISize<VALUETYPE> >
1433 {
1434  public:
1435  typedef VigraTrueType isInitializer;
1436  typedef VigraTrueType isUnaryAnalyser;
1437 };
1438 
1439 /********************************************************/
1440 /* */
1441 /* FindBoundingRectangle */
1442 /* */
1443 /********************************************************/
1444 
1445 /** \brief Calculate the bounding rectangle of an ROI in an image.
1446 
1447  As always in VIGRA, <TT>roiRect.lowerRight</TT> is <em> just outside the rectangle</em>.
1448  That is, the last pixel actually in the rectangle is <TT>roiRect.lowerRight - Diff2D(1,1)</TT>.
1449  This Functor is often used in conjunction with
1450  \ref ArrayOfRegionStatistics to find the bounding rectangles
1451  of all regions in a labeled image.
1452 
1453  <b> Traits defined:</b>
1454 
1455  <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
1456  are true (<tt>VigraTrueType</tt>)
1457 
1458  <b> Usage:</b>
1459 
1460  <b>\#include</b> <vigra/inspectimage.hxx><br>
1461  Namespace: vigra
1462 
1463  \code
1464  vigra::BImage img, mask;
1465  ...
1466 
1467  vigra::FindBoundingRectangle roiRect; // init functor
1468 
1469  // Diff2D is used as the iterator for the source image. This
1470  // simulates an image where each pixel value equals the pixel's
1471  // coordinates. The image 'mask' determines the ROI.
1472  vigra::inspectImageIf(srcIterRange(Diff2D(0,0), (Diff2D)img.size()),
1473  srcImage(mask), roiRect);
1474 
1475  cout << "Upper left of ROI: " <<
1476  roiRect.upperLeft.x << ", " << roiRect.upperLeft.y << endl;
1477  cout << "Lower right of ROI: " <<
1478  roiRect.lowerRight.x << ", " << roiRect.lowerRight.y << endl;
1479 
1480  \endcode
1481 
1482 */
1484 {
1485  public:
1486 
1487  /** the functor's argument type
1488  */
1490 
1491  /** the functors result type
1492  */
1494 
1495  /** \deprecated use argument_type
1496  */
1498 
1499  /** Upper left of the region as seen so far
1500  */
1502 
1503  /** Lower right of the region as seen so far
1504  */
1506 
1507  /** are the functors contents valid ?
1508  */
1509  bool valid;
1510 
1511  /** init rectangle to invalid values
1512  */
1514  : valid(false)
1515  {}
1516 
1517  /** (re-)init functor to find other bounds
1518  */
1519  void reset()
1520  {
1521  valid = false;
1522  }
1523 
1524  /** update rectangle by including the coordinate coord
1525  */
1526  void operator()(argument_type const & coord)
1527  {
1528  if(!valid)
1529  {
1530  upperLeft = Point2D(coord);
1531  lowerRight = Point2D(coord + Diff2D(1,1));
1532  valid = true;
1533  }
1534  else
1535  {
1536  upperLeft.x = std::min(upperLeft.x, coord.x);
1537  upperLeft.y = std::min(upperLeft.y, coord.y);
1538  lowerRight.x = std::max(lowerRight.x, coord.x + 1);
1539  lowerRight.y = std::max(lowerRight.y, coord.y + 1);
1540  }
1541  }
1542 
1543  /** update rectangle by merging it with another rectangle
1544  */
1545  void operator()(FindBoundingRectangle const & otherRegion)
1546  {
1547  if(!valid)
1548  {
1549  upperLeft = otherRegion.upperLeft;
1550  lowerRight = otherRegion.lowerRight;
1551  valid = otherRegion.valid;
1552  }
1553  else if(otherRegion.valid)
1554  {
1555  upperLeft.x = std::min(upperLeft.x, otherRegion.upperLeft.x);
1556  upperLeft.y = std::min(upperLeft.y, otherRegion.upperLeft.y);
1557  lowerRight.x = std::max(lowerRight.x, otherRegion.lowerRight.x);
1558  lowerRight.y = std::max(lowerRight.y, otherRegion.lowerRight.y);
1559  }
1560  }
1561 
1562  /** Get size of current rectangle.
1563  */
1564  Size2D size() const
1565  {
1566  return lowerRight - upperLeft;
1567  }
1568 
1569  /** Get current rectangle. <TT>result_type::first</TT> is the upper
1570  left corner of the rectangle, <TT>result_type::second</TT>
1571  the lower right.
1572  */
1574  {
1575  return result_type(upperLeft, lowerRight);
1576  }
1577 };
1578 
1579 template <>
1580 class FunctorTraits<FindBoundingRectangle>
1581 : public FunctorTraitsBase<FindBoundingRectangle>
1582 {
1583  public:
1584  typedef VigraTrueType isInitializer;
1585  typedef VigraTrueType isUnaryAnalyser;
1586 };
1587 
1588 /********************************************************/
1589 /* */
1590 /* LastValueFunctor */
1591 /* */
1592 /********************************************************/
1593 
1594 /** \brief Stores and returns the last value it has seen.
1595 
1596  This Functor is best used in conjunction with
1597  \ref ArrayOfRegionStatistics to realize a look-up table.
1598 
1599  <b> Traits defined:</b>
1600 
1601  <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitializer</tt>
1602  are true (<tt>VigraTrueType</tt>)
1603 
1604  <b> Usage:</b>
1605 
1606  <b>\#include</b> <vigra/inspectimage.hxx><br>
1607  Namespace: vigra
1608 
1609  \code
1610  vigra::BImage img;
1611 
1612  vigra::ArrayOfRegionStatistics<LastValueFunctor<unsigned char> > lut(255);
1613 
1614  for(int i=0; i<256; ++i)
1615  {
1616  lut[i] = ...; // init look-up table
1617  }
1618 
1619  vigra::transformImage(srcImageRange(img), destImage(img), lut);
1620 
1621  \endcode
1622 
1623 */
1624 template <class VALUETYPE>
1626 {
1627  public:
1628 
1629  /** the functor's argument type
1630  */
1631  typedef VALUETYPE argument_type;
1632 
1633  /** the functor's result type
1634  */
1635  typedef VALUETYPE result_type;
1636 
1637  /** \deprecated use argument_type and result_type
1638  */
1639  typedef VALUETYPE value_type;
1640 
1641  /** default construction of value (i.e. builtin types will be set to zero)
1642  */
1644  : value(initial)
1645  {}
1646 
1647  /** replace value
1648  */
1649  void operator=(argument_type const & v) { value = v; }
1650 
1651  /** reset to initial value (the same as after default construction)
1652  */
1653  void reset() { value = VALUETYPE(); }
1654 
1655  /** replace value
1656  */
1657  void operator()(argument_type const & v) { value = v; }
1658 
1659  /** return current value
1660  */
1661  result_type const & operator()() const { return value; }
1662 
1663  /** the current value
1664  */
1665  VALUETYPE value;
1666 
1667 };
1668 
1669 template <class VALUETYPE>
1670 class FunctorTraits<LastValueFunctor<VALUETYPE> >
1671 : public FunctorTraitsBase<LastValueFunctor<VALUETYPE> >
1672 {
1673  public:
1674  typedef VigraTrueType isInitializer;
1675  typedef VigraTrueType isUnaryAnalyser;
1676 };
1677 
1678 /********************************************************/
1679 /* */
1680 /* ReduceFunctor */
1681 /* */
1682 /********************************************************/
1683 
1684 /** \brief Apply a functor to reduce the dimensionality of an array.
1685 
1686  This functor can be used to emulate the <tt>reduce</tt> standard function of
1687  functional programming using <tt>std::for_each()</tt> or <tt>inspectImage()</tt>
1688  and similar functions. This functor is initialized with a functor encoding
1689  the expression to be applied, and an accumulator storing the current state
1690  of the reduction. For each element of the array, the embedded functor is called
1691  with the accumulator and the current element(s) of the array. The result
1692  of the reduction is available by calling <tt>reduceFunctor()</tt>.
1693 
1694  <b> Traits defined:</b>
1695 
1696  <tt>FunctorTraits::isUnaryAnalyser</tt>, <tt>FunctorTraits::isBinaryAnalyser</tt>
1697  and <tt>FunctorTraits::isInitializer</tt>
1698  are true (<tt>VigraTrueType</tt>)
1699 
1700  <b> Usage:</b>
1701 
1702  <b>\#include</b> <vigra/inspectimage.hxx><br>
1703  Namespace: vigra
1704 
1705  \code
1706  vigra::BImage img;
1707  ... // fill the image
1708 
1709  // create a functor to sum the elements of the image
1710  vigra::ReduceFunctor<std::plus<int>, int> sumElements(std::plus<int>, 0);
1711 
1712  vigra::inspectImage(srcImageRange(img), sumElements);
1713 
1714  cout << "The sum of the elements " << sumElements() << endl;
1715 
1716  \endcode
1717 
1718  <b> Required Interface:</b>
1719 
1720  \code
1721  FUNCTOR f;
1722  VALUETYPE accumulator, current1, current2;
1723 
1724  f(accumulator, current1); // for inspectImage()
1725  f(accumulator, current1, current2); // for inspectTwoImages()
1726  \endcode
1727 */
1728 template <class FUNCTOR, class VALUETYPE>
1730 {
1731  FUNCTOR f_;
1732  VALUETYPE start_, accumulator_;
1733  public:
1734 
1735  /** the functor's argument type
1736  when used as a unary inspector.
1737  (This is not strictly correct since the argument type
1738  is actually a template parameter.)
1739  */
1740  typedef VALUETYPE argument_type;
1741 
1742  /** the functor's first argument type
1743  when used as a binary inspector.
1744  (This is not strictly correct since the argument type
1745  is actually a template parameter.)
1746  */
1747  typedef VALUETYPE first_argument_type;
1748 
1749  /** the functor's second argument type
1750  when used as a binary inspector.
1751  (This is not strictly correct since the argument type
1752  is actually a template parameter.)
1753  */
1754  typedef VALUETYPE second_argument_type;
1755 
1756  /** the functor's result type
1757  */
1758  typedef VALUETYPE result_type;
1759 
1760  /** create with the given functor and initial value \a initial
1761  for the accumulator.
1762  */
1763  ReduceFunctor(FUNCTOR const & f, VALUETYPE const & initial)
1764  : f_(f),
1765  start_(initial),
1766  accumulator_(initial)
1767  {}
1768 
1769  /** Reset accumulator to the initial value.
1770  */
1771  void reset()
1772  { accumulator_ = start_; }
1773 
1774  /** Use binary functor to connect given value with the accumulator.
1775  The accumulator is used as the first argument, the value \a v
1776  as the second.
1777  */
1778  template <class T>
1779  void operator()(T const & v)
1780  {
1781  accumulator_ = f_(accumulator_, v);
1782  }
1783 
1784  /** Use ternary functor to connect given values with accumulator.
1785  The accumulator is used as the first argument, the values \a v1
1786  ans \a v2 as the second and third.
1787  */
1788  template <class T1, class T2>
1789  void operator()(T1 const & v1, T2 const & v2)
1790  {
1791  accumulator_ = f_(accumulator_, v1, v2);
1792  }
1793 
1794  /** return current value
1795  */
1796  result_type const & operator()() const
1797  { return accumulator_; }
1798 };
1799 
1800 template <class FUNCTOR, class VALUETYPE>
1801 ReduceFunctor<FUNCTOR, VALUETYPE>
1802 reduceFunctor(FUNCTOR const & f, VALUETYPE const & initial)
1803 {
1804  return ReduceFunctor<FUNCTOR, VALUETYPE>(f, initial);
1805 }
1806 
1807 template <class FUNCTOR, class VALUETYPE>
1808 class FunctorTraits<ReduceFunctor<FUNCTOR, VALUETYPE> >
1809 : public FunctorTraitsBase<ReduceFunctor<FUNCTOR, VALUETYPE> >
1810 {
1811  public:
1812  typedef VigraTrueType isInitializer;
1813  typedef VigraTrueType isUnaryAnalyser;
1814  typedef VigraTrueType isBinaryAnalyser;
1815 };
1816 
1817 /********************************************************/
1818 /* */
1819 /* ArrayOfRegionStatistics */
1820 /* */
1821 /********************************************************/
1822 
1823 /** \brief Calculate statistics for all regions of a labeled image.
1824 
1825  This Functor encapsulates an array of statistics functors, one
1826  for each label, and selects the one to be updated according to the
1827  pixel's label.
1828 
1829  <b> Traits defined:</b>
1830 
1831  <tt>FunctorTraits::isBinaryAnalyser</tt> and <tt>FunctorTraits::isUnaryFunctor</tt>
1832  are true (<tt>VigraTrueType</tt>)
1833 
1834  <b> Usage:</b>
1835 
1836  <b>\#include</b> <vigra/inspectimage.hxx><br>
1837  Namespace: vigra
1838 
1839  \code
1840  vigra::BImage img;
1841  vigra::IImage labels;
1842  int max_label;
1843  ...
1844 
1845  // init functor as an array of 'max_label' FindMinMax-Functors
1846  vigra::ArrayOfRegionStatistics<vigra::FindMinMax<vigra::BImage::PixelType> >
1847  minmax(max_label);
1848 
1849  vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), minmax);
1850 
1851  for(int i=0; i<= max_label; ++i)
1852  {
1853  cout << "Max gray level of region " << i << ": "
1854  << minmax.region[i].max << endl;
1855  }
1856 
1857  // init functor as an array of 'max_label' FindAverage-Functors
1858  vigra::ArrayOfRegionStatistics<vigra::FindAverage<vigra::BImage::PixelType> >
1859  average(max_label);
1860 
1861  vigra::inspectTwoImages(srcImageRange(img), srcImage(labels), average);
1862 
1863  // write back the average of each region into the original image
1864  vigra::transformImage(srcImageRange(labels), destImage(img), average);
1865 
1866  \endcode
1867 
1868  <b> Required Interface:</b>
1869 
1870  \code
1871  RegionStatistics region;
1872  RegionStatistics::argument_type a;
1873  RegionStatistics::result_type r;
1874 
1875  region(a); // update statistics
1876  r = region(); // return statistics
1877 
1878  \endcode
1879 */
1880 template <class RegionStatistics, class LabelType = int>
1882  : public detail::get_extra_passes<RegionStatistics>
1883 {
1884  typedef std::vector<RegionStatistics> RegionArray;
1885 
1886  public:
1887  /** argument type of the contained statistics object
1888  becomes first argument of the analyser
1889  */
1890  typedef typename RegionStatistics::argument_type first_argument_type;
1891 
1892  /** label type is used to determine the region to be updated
1893  */
1894  typedef LabelType second_argument_type;
1895 
1896  /** label type is also used to determine the region to be
1897  returned by the 1 argument operator()
1898  */
1899  typedef LabelType argument_type;
1900 
1901  /** result type of the contained statistics object
1902  becomes result type of the analyser
1903  */
1904  typedef typename RegionStatistics::result_type result_type;
1905 
1906  /** the value type of the array: the contained statistics object.
1907  <b>Note:</b> this definition was different in older
1908  VIGRA versions. The old definition was wrong.
1909  */
1910  typedef RegionStatistics value_type;
1911 
1912  /** the array's reference type
1913  */
1914  typedef RegionStatistics & reference;
1915 
1916  /** the array's const reference type
1917  */
1918  typedef RegionStatistics const & const_reference;
1919 
1920  /** type to iterate over the statistics array
1921  */
1922  typedef typename RegionArray::iterator iterator;
1923 
1924  /** type to iterate over a const statistics array
1925  */
1926  typedef typename RegionArray::const_iterator const_iterator;
1927 
1928  /** init array of RegionStatistics with default size 0.
1929  */
1931  {}
1932 
1933  /** init array of RegionStatistics with index domain
1934  0...max_region_label.
1935  */
1936  ArrayOfRegionStatistics(unsigned int max_region_label)
1937  : regions(max_region_label+1)
1938  {}
1939 
1940  /** resize array to new index domain 0...max_region_label.
1941  All bin are re-initialized.
1942  */
1943  void resize(unsigned int max_region_label)
1944  {
1945  RegionArray newRegions(max_region_label+1);
1946  regions.swap(newRegions);
1947  }
1948 
1949  /** reset the contained functors to their initial state.
1950  */
1951  void reset()
1952  {
1953  RegionArray newRegions(regions.size());
1954  regions.swap(newRegions);
1955  }
1956 
1957  /** update regions statistics for region <TT>label</TT>. The label type
1958  is converted to <TT>unsigned int</TT>.
1959  */
1961  regions[static_cast<unsigned int>(label)](v);
1962  }
1963 
1964  /** merge second region into first
1965  */
1966  void merge(argument_type label1, argument_type label2) {
1967  regions[static_cast<unsigned int>(label1)](regions[static_cast<unsigned int>(label2)]);
1968  }
1969 
1970  /** ask for maximal index (label) allowed
1971  */
1972  unsigned int maxRegionLabel() const
1973  { return size() - 1; }
1974 
1975  /** ask for array size (i.e. maxRegionLabel() + 1)
1976  */
1977  unsigned int size() const
1978  { return regions.size(); }
1979 
1980  /** access the statistics for a region via its label. The label type
1981  is converted to <TT>unsigned int</TT>.
1982  */
1984  { return regions[static_cast<unsigned int>(label)](); }
1985 
1986  /** read the statistics functor for a region via its label
1987  */
1989  { return regions[static_cast<unsigned int>(label)]; }
1990 
1991  /** access the statistics functor for a region via its label
1992  */
1994  { return regions[static_cast<unsigned int>(label)]; }
1995 
1996  /** iterator to the begin of the region array
1997  */
1999  { return regions.begin(); }
2000 
2001  /** const iterator to the begin of the region array
2002  */
2004  { return regions.begin(); }
2005 
2006  /** iterator to the end of the region array
2007  */
2009  { return regions.end(); }
2010 
2011  /** const iterator to the end of the region array
2012  */
2014  { return regions.end(); }
2015 
2016  /** prepare next pass for multi-pass RegionStatistics types
2017  */
2018  void calc_sync()
2019  {
2020  for (iterator j = begin(); j != end(); ++j)
2021  this->sync(*j);
2022  }
2023  // update: passes >= 2
2024  struct pass_n_dispatch
2025  {
2027  unsigned pass_number;
2028  pass_n_dispatch(ArrayOfRegionStatistics & a, unsigned n)
2029  : x(a), pass_number(n) {}
2030  template <class S> // instantiate only when used.
2031  void operator()(const first_argument_type & v, S label)
2032  {
2033  x.regions[static_cast<unsigned>(label)].updatePassN(v, pass_number);
2034  }
2035  };
2036  template <class N> // instantiate only when used.
2037  pass_n_dispatch pass_n(N n)
2038  {
2039  if (n < 2 || static_cast<unsigned>(n) > this->max_passes)
2040  vigra_fail("ArrayOfRegionStatistics::pass_n(): inconsistent use.");
2041  return pass_n_dispatch(*this, n);
2042  }
2043 
2044  std::vector<RegionStatistics> regions;
2045 };
2046 
2047 template <class RegionStatistics, class LabelType>
2048 class FunctorTraits<ArrayOfRegionStatistics<RegionStatistics, LabelType> >
2049 : public FunctorTraitsBase<ArrayOfRegionStatistics<RegionStatistics, LabelType> >
2050 {
2051  public:
2052  typedef VigraTrueType isUnaryFunctor;
2053  typedef VigraTrueType isBinaryAnalyser;
2054 };
2055 
2056 //@}
2057 
2058 } // namespace vigra
2059 
2060 #endif // VIGRA_INSPECTIMAGE_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
vigra 1.9.0 (Tue Sep 24 2013)