37 #ifndef VIGRA_INSPECTIMAGE_HXX
38 #define VIGRA_INSPECTIMAGE_HXX
43 #include "numerictraits.hxx"
44 #include "iteratortraits.hxx"
45 #include "functortraits.hxx"
46 #include "rgbvalue.hxx"
47 #include "inspector_passes.hxx"
48 #include "multi_shape.hxx"
64 template <
class SrcIterator,
class SrcAccessor,
class Functor>
66 inspectLine(SrcIterator s,
67 SrcIterator send, SrcAccessor src,
74 template <
class SrcIterator,
class SrcAccessor,
75 class MaskIterator,
class MaskAccessor,
78 inspectLineIf(SrcIterator s,
79 SrcIterator send, SrcAccessor src,
80 MaskIterator m, MaskAccessor mask,
83 for(; s != send; ++s, ++m)
88 template <
class SrcIterator1,
class SrcAccessor1,
89 class SrcIterator2,
class SrcAccessor2,
92 inspectTwoLines(SrcIterator1 s1,
93 SrcIterator1 s1end, SrcAccessor1 src1,
94 SrcIterator2 s2, SrcAccessor2 src2,
97 for(; s1 != s1end; ++s1, ++s2)
98 f(src1(s1), src2(s2));
101 template <
class SrcIterator1,
class SrcAccessor1,
102 class SrcIterator2,
class SrcAccessor2,
103 class MaskIterator,
class MaskAccessor,
106 inspectTwoLinesIf(SrcIterator1 s1,
107 SrcIterator1 s1end, SrcAccessor1 src1,
108 SrcIterator2 s2, SrcAccessor2 src2,
109 MaskIterator m, MaskAccessor mask,
112 for(; s1 != s1end; ++s1, ++s2, ++m)
114 f(src1(s1), src2(s2));
209 template <
class ImageIterator,
class Accessor>
210 struct inspectImage_binder
212 ImageIterator upperleft;
213 ImageIterator lowerright;
216 inspectImage_binder(ImageIterator ul, ImageIterator lr, Accessor ac)
217 : upperleft(ul), lowerright(lr), a(ac) {}
218 template <
class Functor>
219 void operator()(Functor & f)
221 int w = lowerright.x - upperleft.x;
223 for (ImageIterator t = upperleft; t.y < lowerright.y; ++t.y)
225 inspectLine(t.rowIterator(), t.rowIterator() + w, a, f);
230 template <
class ImageIterator,
class Accessor,
class Functor>
232 inspectImage(ImageIterator upperleft, ImageIterator lowerright,
233 Accessor a, Functor & f)
235 inspectImage_binder<ImageIterator, Accessor> g(upperleft, lowerright, a);
236 detail::extra_passes_select(g, f);
239 template <
class ImageIterator,
class Accessor,
class Functor>
241 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img,
247 template <
class T,
class S,
class Functor>
257 template <
class T>
class UnaryAnalyser;
260 template <
class ImageIterator,
class Accessor,
class Functor>
263 inspectImage(ImageIterator upperleft, ImageIterator lowerright,
264 Accessor a, functor::UnaryAnalyser<Functor>
const & f)
267 const_cast<functor::UnaryAnalyser<Functor> &
>(f));
270 template <
class ImageIterator,
class Accessor,
class Functor>
272 inspectImage(triple<ImageIterator, ImageIterator, Accessor> img,
273 functor::UnaryAnalyser<Functor>
const & f)
276 const_cast<functor::UnaryAnalyser<Functor> &>(f));
279 template <
class T,
class S,
class Functor>
282 functor::UnaryAnalyser<Functor>
const & f)
285 const_cast<functor::UnaryAnalyser<Functor> &
>(f));
392 template <
class ImageIterator,
class Accessor,
393 class MaskImageIterator,
class MaskAccessor>
394 struct inspectImageIf_binder
396 ImageIterator upperleft;
397 ImageIterator lowerright;
399 MaskImageIterator mask_upperleft;
402 inspectImageIf_binder(ImageIterator ul, ImageIterator lr, Accessor ac,
403 MaskImageIterator m_ul, MaskAccessor m_ac)
404 : upperleft(ul), lowerright(lr), a(ac), mask_upperleft(m_ul), ma(m_ac)
406 template <
class Functor>
407 void operator()(Functor & f)
409 int w = lowerright.x - upperleft.x;
411 MaskImageIterator mt = mask_upperleft;
412 for (ImageIterator t = upperleft; t.y < lowerright.y; ++t.y, ++mt.y)
414 inspectLineIf(t.rowIterator(),
415 t.rowIterator() + w, a,
416 mt.rowIterator(), ma, f);
421 template <
class ImageIterator,
class Accessor,
422 class MaskImageIterator,
class MaskAccessor,
class Functor>
425 ImageIterator lowerright, Accessor a,
426 MaskImageIterator mask_upperleft, MaskAccessor ma,
429 inspectImageIf_binder<ImageIterator, Accessor, MaskImageIterator,
431 g(upperleft, lowerright, a, mask_upperleft, ma);
432 detail::extra_passes_select(g, f);
435 template <
class ImageIterator,
class Accessor,
436 class MaskImageIterator,
class MaskAccessor,
class Functor>
439 ImageIterator lowerright, Accessor a,
440 MaskImageIterator mask_upperleft, MaskAccessor ma,
441 functor::UnaryAnalyser<Functor>
const & f)
444 mask_upperleft, ma,
const_cast<functor::UnaryAnalyser<Functor> &
>(f));
447 template <
class ImageIterator,
class Accessor,
448 class MaskImageIterator,
class MaskAccessor,
class Functor>
450 inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
451 pair<MaskImageIterator, MaskAccessor> mask,
455 mask.first, mask.second, f);
458 template <
class ImageIterator,
class Accessor,
459 class MaskImageIterator,
class MaskAccessor,
class Functor>
461 inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
462 pair<MaskImageIterator, MaskAccessor> mask,
463 functor::UnaryAnalyser<Functor>
const & f)
466 mask.first, mask.second, const_cast<functor::UnaryAnalyser<Functor> &>(f));
469 template <
class T,
class S,
470 class TM,
class SM,
class Functor>
473 MultiArrayView<2, TM, SM>
const & mask,
476 vigra_precondition(img.shape() == mask.shape(),
477 "inspectImageIf(): shape mismatch between input and output.");
482 template <
class T,
class S,
483 class TM,
class SM,
class Functor>
486 MultiArrayView<2, TM, SM>
const & mask,
487 functor::UnaryAnalyser<Functor>
const & f)
490 maskImage(mask),
const_cast<functor::UnaryAnalyser<Functor> &
>(f));
593 template <
class ImageIterator1,
class Accessor1,
594 class ImageIterator2,
class Accessor2>
595 struct inspectTwoImages_binder
597 ImageIterator1 upperleft1;
598 ImageIterator1 lowerright1;
600 ImageIterator2 upperleft2;
602 inspectTwoImages_binder(ImageIterator1 u1, ImageIterator1 l1, Accessor1 a1_,
603 ImageIterator2 u2, Accessor2 a2_)
604 : upperleft1(u1), lowerright1(l1), a1(a1_), upperleft2(u2), a2(a2_) {}
605 template <
class Functor>
606 void operator()(Functor & f)
608 int w = lowerright1.x - upperleft1.x;
610 ImageIterator1 t1 = upperleft1;
611 ImageIterator2 t2 = upperleft2;
612 for (; t1.y < lowerright1.y; ++t1.y, ++t2.y)
614 inspectTwoLines(t1.rowIterator(),
615 t1.rowIterator() + w, a1,
616 t2.rowIterator(), a2, f);
621 template <
class ImageIterator1,
class Accessor1,
622 class ImageIterator2,
class Accessor2,
627 ImageIterator2 upperleft2, Accessor2 a2,
630 inspectTwoImages_binder<ImageIterator1, Accessor1,
631 ImageIterator2, Accessor2>
632 g(upperleft1, lowerright1, a1, upperleft2, a2);
633 detail::extra_passes_select(g, f);
636 template <
class ImageIterator1,
class Accessor1,
637 class ImageIterator2,
class Accessor2,
640 inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
641 ImageIterator2 upperleft2, Accessor2 a2,
642 functor::UnaryAnalyser<Functor>
const & f)
645 upperleft2, a2,
const_cast<functor::UnaryAnalyser<Functor> &
>(f));
648 template <
class ImageIterator1,
class Accessor1,
649 class ImageIterator2,
class Accessor2,
653 pair<ImageIterator2, Accessor2> img2,
657 img2.first, img2.second, f);
660 template <
class ImageIterator1,
class Accessor1,
661 class ImageIterator2,
class Accessor2,
665 pair<ImageIterator2, Accessor2> img2,
666 functor::UnaryAnalyser<Functor>
const & f)
669 img2.first, img2.second, const_cast<functor::UnaryAnalyser<Functor> &>(f));
672 template <
class T1,
class S1,
677 MultiArrayView<2, T2, S2>
const & img2,
680 vigra_precondition(img1.shape() == img2.shape(),
681 "inspectTwoImages(): shape mismatch between input and output.");
688 template <
class T1,
class S1,
693 MultiArrayView<2, T2, S2>
const & img2,
694 functor::UnaryAnalyser<Functor>
const & f)
696 vigra_precondition(img1.shape() == img2.shape(),
697 "inspectTwoImages(): shape mismatch between input and output.");
699 srcImage(img2),
const_cast<functor::UnaryAnalyser<Functor> &
>(f));
813 template <
class ImageIterator1,
class Accessor1,
814 class ImageIterator2,
class Accessor2,
815 class MaskImageIterator,
class MaskAccessor>
816 struct inspectTwoImagesIf_binder
818 ImageIterator1 upperleft1;
819 ImageIterator1 lowerright1;
821 ImageIterator2 upperleft2;
823 MaskImageIterator mupperleft;
825 inspectTwoImagesIf_binder(ImageIterator1 u1, ImageIterator1 l1,
826 Accessor1 a1_, ImageIterator2 u2, Accessor2 a2_,
827 MaskImageIterator mu, MaskAccessor ma)
828 : upperleft1(u1), lowerright1(l1), a1(a1_), upperleft2(u2), a2(a2_),
829 mupperleft(mu), mask(ma) {}
830 template <
class Functor>
831 void operator()(Functor & f)
833 int w = lowerright1.x - upperleft1.x;
835 ImageIterator1 t1 = upperleft1;
836 ImageIterator2 t2 = upperleft2;
837 MaskImageIterator mu = mupperleft;
838 for(; t1.y < lowerright1.y; ++t1.y, ++t2.y, ++mu.y)
840 inspectTwoLinesIf(t1.rowIterator(),
841 t1.rowIterator() + w, a1,
842 t2.rowIterator(), a2,
843 mu.rowIterator(), mask, f);
848 template <
class ImageIterator1,
class Accessor1,
849 class ImageIterator2,
class Accessor2,
850 class MaskImageIterator,
class MaskAccessor,
855 ImageIterator2 upperleft2, Accessor2 a2,
856 MaskImageIterator mupperleft, MaskAccessor mask,
859 inspectTwoImagesIf_binder<ImageIterator1, Accessor1,
860 ImageIterator2, Accessor2,
861 MaskImageIterator, MaskAccessor>
862 g(upperleft1, lowerright1, a1, upperleft2, a2, mupperleft, mask);
863 detail::extra_passes_select(g, f);
866 template <
class ImageIterator1,
class Accessor1,
867 class ImageIterator2,
class Accessor2,
868 class MaskImageIterator,
class MaskAccessor,
871 inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Accessor1 a1,
872 ImageIterator2 upperleft2, Accessor2 a2,
873 MaskImageIterator mupperleft, MaskAccessor mask,
874 functor::UnaryAnalyser<Functor>
const & f)
879 const_cast<functor::UnaryAnalyser<Functor> &
>(f));
882 template <
class ImageIterator1,
class Accessor1,
883 class ImageIterator2,
class Accessor2,
884 class MaskImageIterator,
class MaskAccessor,
888 pair<ImageIterator2, Accessor2> img2,
889 pair<MaskImageIterator, MaskAccessor> m,
893 img2.first, img2.second,
898 template <
class ImageIterator1,
class Accessor1,
899 class ImageIterator2,
class Accessor2,
900 class MaskImageIterator,
class MaskAccessor,
904 pair<ImageIterator2, Accessor2> img2,
905 pair<MaskImageIterator, MaskAccessor> m,
906 functor::UnaryAnalyser<Functor>
const & f)
909 img2.first, img2.second,
911 const_cast<functor::UnaryAnalyser<Functor> &>(f));
914 template <
class T1,
class S1,
920 MultiArrayView<2, T2, S2>
const & img2,
921 MultiArrayView<2, TM, SM>
const & mask,
924 vigra_precondition(img1.shape() == img2.shape() && img1.shape() == mask.shape(),
925 "inspectTwoImagesIf(): shape mismatch between input and output.");
932 template <
class T1,
class S1,
938 MultiArrayView<2, T2, S2>
const & img2,
939 MultiArrayView<2, TM, SM>
const & mask,
940 functor::UnaryAnalyser<Functor>
const & f)
942 vigra_precondition(img1.shape() == img2.shape() && img1.shape() == mask.shape(),
943 "inspectTwoImagesIf(): shape mismatch between input and output.");
947 const_cast<functor::UnaryAnalyser<Functor> &
>(f));
1000 template <
class VALUETYPE>
1092 template <
class VALUETYPE>
1094 :
public FunctorTraitsBase<FindMinMax<VALUETYPE> >
1097 typedef VigraTrueType isUnaryAnalyser;
1142 template <
class VALUETYPE>
1144 :
public UnaryReduceFunctorTag
1166 sum_ = NumericTraits<result_type>::zero();
1247 template <
class VALUETYPE>
1270 typedef typename NumericTraits<VALUETYPE>::RealPromote
value_type;
1275 : sum_(NumericTraits<
result_type>::zero()), count_(0)
1283 sum_ = NumericTraits<result_type>::zero();
1324 return sum_ / (double)count_;
1331 return sum_ / (double)count_;
1338 template <
class VALUETYPE>
1339 class FunctorTraits<FindAverage<VALUETYPE> >
1340 :
public FunctorTraitsBase<FindAverage<VALUETYPE> >
1343 typedef VigraTrueType isInitializer;
1344 typedef VigraTrueType isUnaryAnalyser;
1400 template <
class VALUETYPE>
1423 typedef typename NumericTraits<VALUETYPE>::RealPromote
value_type;
1429 sumOfSquaredDifferences_(NumericTraits<
result_type>::zero()),
1438 mean_ = NumericTraits<result_type>::zero();
1439 sumOfSquaredDifferences_ = NumericTraits<result_type>::zero();
1450 sumOfSquaredDifferences_ += (count_-1.0)*t1*t2;
1468 sumOfSquaredDifferences_ +=
1469 (t1 * t1 * weight / count_) * (count_ - weight );
1476 double newCount = count_ + v.count_;
1477 sumOfSquaredDifferences_ += v.sumOfSquaredDifferences_ +
1478 count_ / newCount * v.count_ * (mean_ - v.mean_) * (mean_ - v.mean_);
1479 mean_ = (count_ * mean_ + v.count_ * v.mean_) / newCount;
1487 return (
unsigned int)count_;
1504 ? sumOfSquaredDifferences_ / (count_ - 1.0)
1505 : sumOfSquaredDifferences_ / count_;
1519 template <
class VALUETYPE>
1520 class FunctorTraits<FindAverageAndVariance<VALUETYPE> >
1521 :
public FunctorTraitsBase<FindAverageAndVariance<VALUETYPE> >
1524 typedef VigraTrueType isInitializer;
1525 typedef VigraTrueType isUnaryAnalyser;
1562 template <
class VALUETYPE>
1626 template <
class VALUETYPE>
1628 :
public FunctorTraitsBase<FindROISize<VALUETYPE> >
1631 typedef VigraTrueType isInitializer;
1632 typedef VigraTrueType isUnaryAnalyser;
1749 else if(otherRegion.
valid)
1776 class FunctorTraits<FindBoundingRectangle>
1777 :
public FunctorTraitsBase<FindBoundingRectangle>
1780 typedef VigraTrueType isInitializer;
1781 typedef VigraTrueType isUnaryAnalyser;
1820 template <
class VALUETYPE>
1865 template <
class VALUETYPE>
1867 :
public FunctorTraitsBase<LastValueFunctor<VALUETYPE> >
1870 typedef VigraTrueType isInitializer;
1871 typedef VigraTrueType isUnaryAnalyser;
1924 template <
class FUNCTOR,
class VALUETYPE>
1928 VALUETYPE start_, accumulator_;
1962 accumulator_(initial)
1968 { accumulator_ = start_; }
1977 accumulator_ = f_(accumulator_, v);
1984 template <
class T1,
class T2>
1987 accumulator_ = f_(accumulator_, v1, v2);
1993 {
return accumulator_; }
1996 template <
class FUNCTOR,
class VALUETYPE>
1997 ReduceFunctor<FUNCTOR, VALUETYPE>
1998 reduceFunctor(FUNCTOR
const & f, VALUETYPE
const & initial)
2000 return ReduceFunctor<FUNCTOR, VALUETYPE>(f, initial);
2003 template <
class FUNCTOR,
class VALUETYPE>
2004 class FunctorTraits<ReduceFunctor<FUNCTOR, VALUETYPE> >
2005 :
public FunctorTraitsBase<ReduceFunctor<FUNCTOR, VALUETYPE> >
2008 typedef VigraTrueType isInitializer;
2009 typedef VigraTrueType isUnaryAnalyser;
2010 typedef VigraTrueType isBinaryAnalyser;
2076 template <
class RegionStatistics,
class LabelType =
int>
2078 :
public detail::get_extra_passes<RegionStatistics>
2080 typedef std::vector<RegionStatistics> RegionArray;
2133 : regions(max_region_label+1)
2141 RegionArray newRegions(max_region_label+1);
2142 regions.swap(newRegions);
2149 RegionArray newRegions(regions.size());
2150 regions.swap(newRegions);
2157 regions[static_cast<unsigned int>(label)](v);
2163 regions[static_cast<unsigned int>(label1)](regions[static_cast<unsigned int>(label2)]);
2169 {
return size() - 1; }
2174 {
return regions.size(); }
2180 {
return regions[static_cast<unsigned int>(label)](); }
2185 {
return regions[static_cast<unsigned int>(label)]; }
2190 {
return regions[static_cast<unsigned int>(label)]; }
2195 {
return regions.begin(); }
2200 {
return regions.begin(); }
2205 {
return regions.end(); }
2210 {
return regions.end(); }
2220 struct pass_n_dispatch
2223 unsigned pass_number;
2225 : x(a), pass_number(n) {}
2229 x.regions[static_cast<unsigned>(label)].updatePassN(v, pass_number);
2233 pass_n_dispatch pass_n(N n)
2235 if (n < 2 || static_cast<unsigned>(n) > this->max_passes)
2236 vigra_fail(
"ArrayOfRegionStatistics::pass_n(): inconsistent use.");
2237 return pass_n_dispatch(*
this, n);
2240 std::vector<RegionStatistics> regions;
2243 template <
class RegionStatistics,
class LabelType>
2244 class FunctorTraits<ArrayOfRegionStatistics<RegionStatistics, LabelType> >
2245 :
public FunctorTraitsBase<ArrayOfRegionStatistics<RegionStatistics, LabelType> >
2248 typedef VigraTrueType isUnaryFunctor;
2249 typedef VigraTrueType isBinaryAnalyser;
2256 #endif // VIGRA_INSPECTIMAGE_HXX