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

accumulator-grammar.hxx
1/************************************************************************/
2/* */
3/* Copyright 2011-2012 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#ifndef VIGRA_ACCUMULATOR_GRAMMAR_HXX
37#define VIGRA_ACCUMULATOR_GRAMMAR_HXX
38
39#ifdef _MSC_VER
40#pragma warning (disable: 4503)
41#endif
42
43#include "config.hxx"
44#include "metaprogramming.hxx"
45
46namespace vigra {
47
48namespace acc {
49
50/**************************************************************************/
51/* */
52/* irreducible basic accumulators */
53/* */
54/**************************************************************************/
55
56
57class CoordinateSystem; // returns an identity matrix of appropriate size
58
59template <unsigned N> class PowerSum; // sum over powers of values
60template <unsigned N> class AbsPowerSum; // sum over powers of absolute values
61
62class Skewness; // skewness
63class UnbiasedSkewness; // unbiased estimator for skewness
64class Kurtosis; // excess kurtosis
65class UnbiasedKurtosis; // unbiased estimator for excess kurtosis
66class FlatScatterMatrix; // flattened upper-triangular part of the scatter matrix
67class ScatterMatrixEigensystem; // eigenvalues and eigenvectors of the scatter matrix
68
69 // in all histogram classes: set bin count at runtime if BinCount == 0
70template <int BinCount> class IntegerHistogram; // use data values directly as bin indices
71template <int BinCount> class UserRangeHistogram; // set min/max explicitly at runtime
72template <int BinCount> class AutoRangeHistogram; // get min/max from accumulators
73template <int BinCount> class GlobalRangeHistogram; // like AutoRangeHistogram, but use global min/max rather than region min/max
74
75class FirstSeen; // remember the first value seen
76class Minimum; // minimum
77class Maximum; // maximum
78class Range; // minimum and maximum as a <tt>std::pair</tt>
79template <class Hist> class StandardQuantiles; // compute (min, 10%, 25%, 50%, 75%, 90%, max) quantiles from
80 // min/max accumulators and given histogram
81
82class ArgMinWeight; // store the value (or coordinate) where weight was minimal
83class ArgMaxWeight; // store the value (or coordinate) where weight was maximal
84
85 // FIXME: not yet implemented
86template <unsigned NDim> class MultiHistogram; // multi-dimensional histogram
87 // (always specify number of bins at runtime)
88
89class Centralize; // cache centralized values
90class PrincipalProjection; // cache values after principal projection
91 // FIXME: not yet implemented
92class Whiten; // cache values after whitening
93class RangeMapping; // map value from [min, max] to another range and cache result (e.g. for histogram creation)
94
95template <int INDEX> class DataArg; // specifiy the index of the data member in a CoupledHandle
96template <int INDEX> class WeightArg; // specifiy the index of the weight member in a CoupledHandle
97template <int INDEX> class LabelArg; // specifiy the index of the label member in a CoupledHandle
98template <int INDEX> class CoordArg; // specifiy the index of the coord member in a CoupledHandle
99
100class RegionContour; // compute the contour of a 2D region
101class RegionPerimeter; // compute the perimeter of a 2D region
102class RegionCircularity; // compare perimeter of a 2D region with a circle of same area
103class RegionEccentricity; // ecentricity of a 2D region from major and minor axis
104
105#ifdef WITH_LEMON
106class ConvexHull; // base class for convex hull computation
107class ConvexHullFeatures; // base class for convex hull features
108#endif
109
110/*
111Quantiles other than minimum and maximum require more thought:
112--------------------------------------------------------------
113 * Exact quantiles can be found in time O(n) using recursive partitioning (quickselect),
114 but this requires the data (or an auxiliary index array) to be re-arranged.
115 * Exact quantiles can be found in time O(k*n) using recursive histogram refinement,
116 were k = O(log(n)/log(BinCount)) is the expected number of required passes over the
117 data, provided that bins are filled approximately evenly. If data can be re-arranged,
118 such that we remember the items corresponding to each bin, running time reduces to O(n)
119 (this is Tibshirani's 'binmedian' algorithm). For the median, Tibshirani proves that
120 the initial histogram only needs to cover the interval [Mean-StdDev, Mean+StdDev].
121 * Both strategies can be combined: perform k passes to reduce bin size to about
122 n/(BinCount)^k, and then perform quickselect on an auxiliary array of size
123 O(n/(BinCount)^k) which has been filled during the final pass.
124 * Good approximate results can be obtained by early stopping of histogram refinement
125 (Tibshirani's 'binapprox' algorithm). A 2-pass algorithm for the median achieves
126 accuracy of StdDev/BinCount: Mean and StdDev are computed during pass 1,
127 and a histogram over [Mean-StdDev, Mean+StdDev] during pass 2.
128 * A 1-pass approximation method is described in Chen et al. However, it assumes that
129 samples arrive in random order which is usually not true in image data.
130*/
131
132/**************************************************************************/
133/* */
134/* modifiers for composite accumulators */
135/* */
136/**************************************************************************/
137
138 // data normalization w.r.t. number of samples
139template <class A> class DivideByCount; // A / count
140template <class A> class RootDivideByCount; // sqrt(A / count)
141template <class A> class DivideUnbiased; // A / (count - 1)
142template <class A> class RootDivideUnbiased; // sqrt(A / (count - 1))
143
144 // data access
145template <class A> class Coord; // use pixel coordinate instead of pixel value (index 0 of CoupledHandle)
146template <class A> class Weighted; // use (value, weight) pairs (index 1 and 2 of CoupledHandle)
147template <class A> class CoordWeighted; // use (coord, weight) pairs(index 0 and end of CoupledHandle)
148template <class A> class DataFromHandle; // extract data from index 1 of a CoupledHandle
149
150 // data preparation
151template <class A> class Central; // subtract mean
152template <class A> class Principal; // subtract mean and rotate to principal coordinates
153
154 // FIXME: not implemented yet
155template <class A> class Whitened; // transform to principal coordinates and scale to unit variance
156
157template <class A> class Global; // compute statistic A globally rather than per region
158
159/**************************************************************************/
160/* */
161/* alias names for important features */
162/* */
163/**************************************************************************/
164
165/** \brief Alias. Count. */
167/** \brief Alias. Sum. */
169/** \brief Alias. Sum of squares. */
171
172/** \brief Alias. Mean. */
174/** \brief Alias. Root mean square. */
176
177// desired pseudocode (unfortunately not legal in C++)
178//
179// template <unsigned N>
180// typedef DivideByCount<PowerSum<N> > Moment;
181//
182// actual definition (desired behavior is realised by rules below)
183//
184/** \brief Alias. Moment<N>. */
185template <unsigned N> class Moment;
186/** \brief Alias. CentralMoment<N>. */
187template <unsigned N> class CentralMoment;
188
189/** \brief Alias. Sum of squared differences. */
191/** \brief Alias. Sum of squared differences. */
193
194/** \brief Alias. Variance. */
196/** \brief Alias. Standard deviation. */
198/** \brief Alias. Unbiased variance. */
200/** \brief Alias. Unbiased standard deviation. */
202
203/** \brief Alias. Covariance. */
205/** \brief Alias. Unbiased covariance. */
207/** \brief Alias. Covariance eigensystem. */
209
210/** \brief Alias. Absolute sum. */
212/** \brief Alias. Sum of absolute differences. */
214/** \brief Alias. Mean absolute deviation. */
216
217/** \brief Alias. Rectangle enclosing the region, as a <tt>std::pair</tt> of coordinates. */
219/** \brief Alias. Anchor point (first point of the region seen by scan-order traversal. */
221
222/** \brief Alias. Region center. */
224/** \brief Alias. Region radii. */
226/** \brief Alias. Region axes. */
228
229/** \brief Alias. Center of mass. */
231/** \brief Alias. Region center weighted by the region intensity (center of mass). */
233/** \brief Alias. Moments of inertia. */
235/** \brief Alias. Region radius weighted by region intensity (square root of the moments of inertia). */
237/** \brief Alias. Axes of inertia. */
239
240/**************************************************************************/
241/* */
242/* Tag standardization rules */
243/* */
244/**************************************************************************/
245
246namespace acc_detail {
247
248template <class A>
249struct ModifierRule
250{
251 typedef A type;
252};
253
254} // namespace acc_detail
255
256template <class A>
257struct Error___Tag_modifiers_of_same_kind_must_not_be_combined;
258
259 // apply rules as long as the Tag type changes ...
261struct StandardizeTag
262{
263 typedef typename StandardizeTag<S>::type type;
264};
265
266 // ... and stop otherwise ...
267template <class A>
268struct StandardizeTag<A, A>
269{
270 typedef A type;
271};
272
273 // ... or fail when the tag spec was non-conforming
274template <class A, class B>
275struct StandardizeTag<A, Error___Tag_modifiers_of_same_kind_must_not_be_combined<B> >
276 : public Error___Tag_modifiers_of_same_kind_must_not_be_combined<B>
277{};
278
279namespace acc_detail {
280
281 // Assign priorities to modifiers to determine their standard order (by ascending priority).
282 // SubstitutionMask determines which modifiers must be automatically transferred to dependencies.
283enum { MinPriority = 1,
284 AccumulatorPriority = 32,
285 PrepareDataPriority = 16,
286 NormalizePriority = 8,
287 AccessDataPriority = 4,
288 WeightingPriority = 2,
289 GlobalPriority = 1,
290 MaxPriority = 32,
291 SubstitutionMask = PrepareDataPriority | AccessDataPriority | WeightingPriority | GlobalPriority };
292
293template <class A>
294struct ModifierPriority
295{
296 static const int value = AccumulatorPriority;
297};
298
299#define VIGRA_MODIFIER_PRIORITY(MODIFIER, VALUE) \
300template <class A> \
301struct ModifierPriority<MODIFIER<A> > \
302{ \
303 static const int value = VALUE; \
304};
305
306VIGRA_MODIFIER_PRIORITY(Global, GlobalPriority)
307
308VIGRA_MODIFIER_PRIORITY(Weighted, WeightingPriority)
309
310VIGRA_MODIFIER_PRIORITY(Coord, AccessDataPriority)
311VIGRA_MODIFIER_PRIORITY(DataFromHandle, AccessDataPriority)
312
313VIGRA_MODIFIER_PRIORITY(DivideByCount, NormalizePriority)
314VIGRA_MODIFIER_PRIORITY(RootDivideByCount, NormalizePriority)
315VIGRA_MODIFIER_PRIORITY(DivideUnbiased, NormalizePriority)
316VIGRA_MODIFIER_PRIORITY(RootDivideUnbiased, NormalizePriority)
317
318VIGRA_MODIFIER_PRIORITY(Central, PrepareDataPriority)
319VIGRA_MODIFIER_PRIORITY(Principal, PrepareDataPriority)
320VIGRA_MODIFIER_PRIORITY(Whitened, PrepareDataPriority)
321
322 // explicitly set priority for base accumulators that look like modifiers
323VIGRA_MODIFIER_PRIORITY(StandardQuantiles, AccumulatorPriority)
324
325#undef VIGRA_MODIFIER_PRIORITY
326
327 // check if the tag A contains a modifier with TARGET_PRIORITY
328template <class A, int TARGET_PRIORITY, int PRIORITY=ModifierPriority<A>::value>
329struct HasModifierPriority
330{
331 typedef VigraFalseType type;
332 static const bool value = false;
333};
334
335template <class A, int TARGET_PRIORITY>
336struct HasModifierPriority<A, TARGET_PRIORITY, TARGET_PRIORITY>
337{
338 typedef VigraTrueType type;
339 static const bool value = true;
340};
341
342template <class A, template <class> class B, int TARGET_PRIORITY, int PRIORITY>
343struct HasModifierPriority<B<A>, TARGET_PRIORITY, PRIORITY>
344: public HasModifierPriority<A, TARGET_PRIORITY>
345{};
346
347template <class A, template <class> class B, int TARGET_PRIORITY>
348struct HasModifierPriority<B<A>, TARGET_PRIORITY, TARGET_PRIORITY>
349{
350 typedef VigraTrueType type;
351 static const bool value = true;
352};
353
354 // three-way compare
355template <class A, class B>
356struct ModifierCompare
357{
358 static const int p1 = ModifierPriority<A>::value;
359 static const int p2 = ModifierPriority<B>::value;
360 static const int value = p1 < p2
361 ? -1
362 : p2 < p1
363 ? 1
364 : 0;
365};
366
367template <class A>
368struct ModifierCompareToInner;
369
370template <class A, template <class> class B>
371struct ModifierCompareToInner<B<A> >
372: public ModifierCompare<B<A>, A>
373{};
374
375 // sort modifiers by ascending priority
376template <class A, int compare=ModifierCompareToInner<A>::value>
377struct ModifierOrder;
378
379 // do nothing if the order is correct (compare == -1)
380template <class A>
381struct ModifierOrder<A, -1>
382{
383 typedef A type;
384};
385
386 // fail if there are two modifiers with the same priority (compare == 0)
387template <class A, template <class> class B, template <class> class C>
388struct ModifierOrder<C<B<A> >, 0>
389{
390 typedef Error___Tag_modifiers_of_same_kind_must_not_be_combined<C<B<A> > > type;
391};
392
393 // sort if the order is reversed (compare == 1)
394template <class A, template <class> class B, template <class> class C>
395struct ModifierOrder<C<B<A> >, 1>
396{
397 typedef B<C<A> > type;
398};
399
400#define VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(OUTER, INNER, RESULT) \
401template <class A> \
402struct ModifierOrder<OUTER<INNER<A > >, 0> \
403{ \
404 typedef RESULT<A > type; \
405};
406
407 // drop duplicates
408VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Central, Central, Central)
409VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Principal, Principal, Principal)
410VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Whitened, Whitened)
411
412 // the strongest data preparation modifier takes precendence
413VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Principal, Central, Principal)
414VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Central, Whitened)
415VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Principal, Whitened)
416
417 // Coord takes precendence over DataFromHandle
418VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(DataFromHandle, Coord, Coord)
419
420#undef VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS
421
422 // drop duplicates
423template <class A, template <class> class B>
424struct ModifierRule<B<B<A> > >
425{
426 typedef B<A> type;
427};
428
429template <class A, int PRIORITY=ModifierPriority<A>::value>
430struct RecurseModifier;
431
432template <class A, template <class> class B, int PRIORITY>
433struct RecurseModifier<B<A>, PRIORITY>
434{
435 typedef typename ModifierOrder<B<typename StandardizeTag<A>::type> >::type type;
436};
437
438template <class A, template <class> class B>
439struct RecurseModifier<B<A>, AccumulatorPriority>
440{
441 typedef B<A> type;
442};
443
444 // recurse down the modifier chain, but only of B is actually a modifier,
445 // and not a templated base accumulator (i.e. do not recurse if B's
446 // priority is 'AccumulatorPriority')
447template <class A, template <class> class B>
448struct ModifierRule<B<A> >
449: public RecurseModifier<B<A> >
450{};
451
452 // reduce the SOURCE modifier to the TARGET modifier,
453 // using the given TEMPLATE arguments
454 // (this is a work-around for the lack of templated typedef in C++)
455#define VIGRA_REDUCE_MODFIER(TEMPLATE, SOURCE, TARGET) \
456template <TEMPLATE > \
457struct ModifierRule<SOURCE > \
458{ \
459 typedef TARGET type; \
460};
461
462#define VIGRA_VOID
463
464 // centralizing doesn't change the CoordinateSystem
465VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<CoordinateSystem>, CoordinateSystem)
466 // whitened CoordinateSystem are the same as principal CoordinateSystem
467VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<CoordinateSystem>, Principal<CoordinateSystem>)
468
469 // counting modified data is the same as counting data, except for weighted data and global counting
470VIGRA_REDUCE_MODFIER(template <class> class A, A<Count>, Count)
471VIGRA_REDUCE_MODFIER(VIGRA_VOID, Weighted<Count>, Weighted<Count>)
472VIGRA_REDUCE_MODFIER(VIGRA_VOID, CoordWeighted<Count>, Weighted<Count>)
473VIGRA_REDUCE_MODFIER(VIGRA_VOID, Global<Count>, Global<Count>)
474
475 // reduce aliases that typedef can't handle
476VIGRA_REDUCE_MODFIER(unsigned N, Moment<N>, DivideByCount<PowerSum<N> >)
477VIGRA_REDUCE_MODFIER(unsigned N, CentralMoment<N>, DivideByCount<Central<PowerSum<N> > >)
478VIGRA_REDUCE_MODFIER(class A, CoordWeighted<A>, Weighted<Coord<A> >)
479
480 // reduce statistics that are inherently centered
481VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Centralize>, Centralize)
482VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Skewness>, Skewness)
483VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Kurtosis>, Kurtosis)
484VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<FlatScatterMatrix>, FlatScatterMatrix)
485VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
486
487VIGRA_REDUCE_MODFIER(VIGRA_VOID, Principal<Centralize>, PrincipalProjection)
488VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<Centralize>, Whiten)
489VIGRA_REDUCE_MODFIER(VIGRA_VOID, Principal<PrincipalProjection>, PrincipalProjection)
490VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<PrincipalProjection>, Whiten)
491VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<Whiten>, Whiten)
492
493 // ignore all modifiers of RegionContour and related features
494VIGRA_REDUCE_MODFIER(template <class> class A, A<RegionContour>, RegionContour)
495#ifdef WITH_LEMON
496VIGRA_REDUCE_MODFIER(template <class> class A, A<ConvexHull>, ConvexHull)
497VIGRA_REDUCE_MODFIER(template <class> class A, A<ConvexHullFeatures>, ConvexHullFeatures)
498#endif // WITH_LEMON
499VIGRA_REDUCE_MODFIER(template <class> class A, A<RegionPerimeter>, RegionPerimeter)
500VIGRA_REDUCE_MODFIER(template <class> class A, A<RegionCircularity>, RegionCircularity)
501VIGRA_REDUCE_MODFIER(template <class> class A, A<RegionEccentricity>, RegionEccentricity)
502VIGRA_REDUCE_MODFIER(VIGRA_VOID, Weighted<RegionEccentricity>, Weighted<RegionEccentricity>)
503
504 // reduce even absolute powers to plain powers
505template <unsigned N>
506struct ModifierRule<AbsPowerSum<N> >
507{
508 typedef typename IfBool<(N % 2 == 0), PowerSum<N>, AbsPowerSum<N> >::type type;
509};
510
511#undef VIGRA_VOID
512#undef VIGRA_REDUCE_MODFIER
513
514template <class A>
515struct ShouldBeWeighted
516{
517 typedef VigraFalseType type;
518 static const bool value = false;
519};
520
521template <>
522struct ShouldBeWeighted<ArgMinWeight>
523{
524 typedef VigraTrueType type;
525 static const bool value = true;
526};
527
528template <>
529struct ShouldBeWeighted<ArgMaxWeight>
530{
531 typedef VigraTrueType type;
532 static const bool value = true;
533};
534
535template <class A, template <class> class B>
536struct ShouldBeWeighted<B<A> >
537: public ShouldBeWeighted<A>
538{};
539
540} // namespace acc_detail
541
542template <class A>
543struct IsCoordinateFeature
544{
545 typedef VigraFalseType type;
546 static const bool value = false;
547};
548
549template <class A, template <class> class B>
550struct IsCoordinateFeature<B<A> >
551{
552 typedef typename IsCoordinateFeature<A>::type type;
553 static const bool value = IsCoordinateFeature<A>::value;
554};
555
556template <class A>
557struct IsCoordinateFeature<Coord<A> >
558{
559 typedef VigraTrueType type;
560 static const bool value = true;
561};
562
563template <class A>
564struct IsPrincipalFeature
565{
566 typedef VigraFalseType type;
567 static const bool value = false;
568};
569
570template <class A, template <class> class B>
571struct IsPrincipalFeature<B<A> >
572{
573 typedef typename IsPrincipalFeature<A>::type type;
574 static const bool value = IsPrincipalFeature<A>::value;
575};
576
577template <class A>
578struct IsPrincipalFeature<Principal<A> >
579{
580 typedef VigraTrueType type;
581 static const bool value = true;
582};
583
584template <class A>
585struct IsPrincipalFeature<Whitened<A> >
586{
587 typedef VigraTrueType type;
588 static const bool value = true;
589};
590
591/**************************************************************************/
592/* */
593/* Tag transfer rules */
594/* */
595/**************************************************************************/
596
597namespace acc_detail {
598
599template <class A>
600struct DefaultModifier;
601
602template <class A>
603struct ModifierPriority<DefaultModifier<A> >
604{
605 static const int value = ModifierPriority<A>::value << 1;
606};
607
608template <class A, int TargetPriority, int Priority=ModifierPriority<A>::value>
609struct InsertDefaultModifier
610{
611 typedef DefaultModifier<typename InsertDefaultModifier<A, (TargetPriority << 1)>::type> type;
612};
613
614template <class A, int TargetPriority>
615struct InsertDefaultModifier<A, TargetPriority, TargetPriority>
616{
617 typedef A type;
618};
619
620template <class A, int TargetPriority, int Priority=ModifierPriority<A>::value>
621struct TagLongForm;
622
623template <class A, int TargetPriority>
624struct TagLongForm<A, TargetPriority, MaxPriority>
625{
626 typedef typename InsertDefaultModifier<A, TargetPriority>::type type;
627};
628
629template <class A, template <class> class B, int TargetPriority>
630struct TagLongForm<B<A>, TargetPriority, MaxPriority>
631{
632 typedef typename InsertDefaultModifier<B<A>, TargetPriority>::type type;
633};
634
635template <class A, template <class> class B, int TargetPriority, int Priority>
636struct TagLongForm<B<A>, TargetPriority, Priority>
637{
638 typedef typename TagLongForm<A, (Priority << 1)>::type Inner;
639 typedef typename InsertDefaultModifier<B<Inner>, TargetPriority>::type type;
640};
641
642template <class A, template <class> class B, int TargetPriority>
643struct TagLongForm<B<A>, TargetPriority, TargetPriority>
644{
645 typedef typename TagLongForm<A, (TargetPriority << 1)>::type Inner;
646 typedef B<Inner> type;
647};
648
649template <class A>
650struct LongModifierRule
651{
652 typedef A type;
653};
654
655 // apply rules as long as the Tag type changes ...
656template <class A, class S=typename LongModifierRule<A>::type>
657struct StandardizeTagLongForm
658{
659 typedef typename StandardizeTagLongForm<S>::type type;
660};
661
662 // ... and stop otherwise ...
663template <class A>
664struct StandardizeTagLongForm<A, A>
665{
666 typedef A type;
667};
668
669template <class A, template <class> class B>
670struct LongModifierRule<B<A> >
671{
672 typedef B<typename LongModifierRule<A>::type> type;
673};
674
675template <class A>
676struct LongModifierRule<DefaultModifier<A> >
677{
678 typedef A type;
679};
680
681#define VIGRA_DROP_DATA_PREPARATION_MODIFIERS(SOURCE, TARGET) \
682template <> \
683struct LongModifierRule<SOURCE > \
684{ \
685 typedef TARGET type; \
686};
687
688VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Central<Sum>, Sum)
689VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<Sum>, Sum)
690VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<Sum>, Sum)
691VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<FlatScatterMatrix>, FlatScatterMatrix)
692VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<FlatScatterMatrix>, FlatScatterMatrix)
693VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
694VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
695
696#undef VIGRA_DROP_DATA_PREPARATION_MODIFIERS
697
698template <class A>
699struct CheckSubstitutionFlag
700{
701 static const bool value = (ModifierPriority<A>::value & SubstitutionMask) != 0;
702};
703
704template <class A, class B,
705 bool substitute=CheckSubstitutionFlag<A>::value>
706struct SubstituteModifiers;
707
708template <class A, class B>
709struct SubstituteModifiers<A, B, false>
710{
711 typedef B type;
712};
713
714template <class A, template <class> class AA, class B, template <class> class BB>
715struct SubstituteModifiers<AA<A>, BB<B>, true>
716{
717 typedef AA<typename SubstituteModifiers<A, B>::type> type;
718};
719
720template <class A, class B, template <class> class BB>
721struct SubstituteModifiers<DefaultModifier<A>, BB<B>, true>
722{
723 typedef BB<typename SubstituteModifiers<A, B>::type> type;
724};
725
726template <class A, template <class> class AA, class B, template <class> class BB>
727struct SubstituteModifiers<AA<A>, BB<B>, false>
728{
729 typedef BB<typename SubstituteModifiers<A, B>::type> type;
730};
731
732} // namespace acc_detail
733
734template <class A, class B>
735struct TransferModifiers
736{
737 typedef typename StandardizeTag<A>::type StdA;
738 typedef typename StandardizeTag<B>::type StdB;
739 typedef typename acc_detail::TagLongForm<StdA, acc_detail::MinPriority>::type AA;
740 typedef typename acc_detail::TagLongForm<StdB, acc_detail::MinPriority>::type BB;
741 typedef typename acc_detail::SubstituteModifiers<AA, BB>::type AB;
742 typedef typename acc_detail::StandardizeTagLongForm<AB>::type StdAB;
743 typedef typename StandardizeTag<StdAB>::type type;
744};
745
746template <class A, class HEAD, class TAIL>
747struct TransferModifiers<A, TypeList<HEAD, TAIL> >
748{
749 typedef TypeList<typename TransferModifiers<A, HEAD>::type,
750 typename TransferModifiers<A, TAIL>::type> type;
751};
752
753template <class A>
754struct TransferModifiers<A, void>
755{
756 typedef void type;
757};
758
759template <class TargetTag, class A=typename TargetTag::Dependencies>
760struct StandardizeDependencies
761#ifndef DOXYGEN
762: public StandardizeDependencies<TargetTag, typename A::type>
763#endif
764{};
765
766template <class TargetTag, class HEAD, class TAIL>
767struct StandardizeDependencies<TargetTag, TypeList<HEAD, TAIL> >
768{
769 typedef typename StandardizeTag<TargetTag>::type Target;
770 typedef typename TransferModifiers<Target, TypeList<HEAD, TAIL> >::type type;
771};
772
773template <class TargetTag>
774struct StandardizeDependencies<TargetTag, void>
775{
776 typedef void type;
777};
778
779}} // namespace vigra::acc
780
781#endif // VIGRA_ACCUMULATOR_GRAMMAR_HXX
Class for a single RGB value.
Definition rgbvalue.hxx:128
Basic statistic. AbsPowerSum<N> = .
Definition accumulator.hxx:4062
Basic statistic. Data where weight assumes its maximal value.
Definition accumulator.hxx:5460
Basic statistic. Data value where weight assumes its minimal value.
Definition accumulator.hxx:5385
Histogram where range mapping bounds are defined by minimum and maximum of data.
Definition accumulator.hxx:5953
Alias. CentralMoment<N>.
Definition accumulator-grammar.hxx:187
Spezialization: works in pass 1, operator+=() supported (merging supported).
Definition accumulator.hxx:4271
Modifier. Substract mean before computing statistic.
Definition accumulator.hxx:3627
Compute object features related to the convex hull.
Definition accumulator.hxx:6380
Compute the convex hull of a region.
Definition accumulator.hxx:6276
Modifier. Compute statistic from pixel coordinates rather than from pixel values.
Definition accumulator.hxx:3419
Basic statistic. Identity matrix of appropriate size.
Definition accumulator.hxx:3847
Specifies index of data in CoupledHandle.
Definition accumulator.hxx:3268
Modifier. Divide statistic by Count: DivideByCount<TAG> = TAG / Count .
Definition accumulator.hxx:4138
Modifier. Divide statistics by Count-1: DivideUnbiased<TAG> = TAG / (Count-1)
Definition accumulator.hxx:4174
Basic statistic. First data value seen of the object.
Definition accumulator.hxx:5286
Basic statistic. Flattened uppter-triangular part of scatter matrix.
Definition accumulator.hxx:4650
Like AutoRangeHistogram, but use global min/max rather than region min/max.
Definition accumulator.hxx:5997
Modifier. Compute statistic globally rather than per region.
Definition accumulator.hxx:3249
Histogram where data values are equal to bin indices.
Definition accumulator.hxx:5798
Basic statistic. Kurtosis.
Definition accumulator.hxx:4518
Specifies index of labels in CoupledHandle.
Definition accumulator.hxx:466
Basic statistic. Maximum value.
Definition accumulator.hxx:5207
Basic statistic. Minimum value.
Definition accumulator.hxx:5129
Alias. Moment<N>.
Definition accumulator-grammar.hxx:185
Basic statistic. PowerSum<N> = .
Definition accumulator.hxx:3996
Modifier. Project onto PCA eigenvectors.
Definition accumulator.hxx:3779
Return both the minimum and maximum in std::pair.
Definition accumulator.hxx:5354
Compute the circularity of a 2D region.
Definition accumulator.hxx:6206
Compute the contour of a 2D region.
Definition accumulator.hxx:6100
Compute the eccentricity of a 2D region in terms of its prinipal radii.
Definition accumulator.hxx:6238
Compute the perimeter of a 2D region.
Definition accumulator.hxx:6173
Modifier. RootDivideByCount<TAG> = sqrt( TAG/Count )
Definition accumulator.hxx:4206
Modifier. RootDivideUnbiased<TAG> = sqrt( TAG / (Count-1) )
Definition accumulator.hxx:4239
Definition accumulator.hxx:4820
Basic statistic. Skewness.
Definition accumulator.hxx:4446
Compute (0%, 10%, 25%, 50%, 75%, 90%, 100%) quantiles from given histogram.
Definition accumulator.hxx:6053
Basic statistic. Unbiased Kurtosis.
Definition accumulator.hxx:4554
Basic statistic. Unbiased Skewness.
Definition accumulator.hxx:4482
Histogram where user provides bounds for linear range mapping from values to indices.
Definition accumulator.hxx:5911
Specifies index of data in CoupledHandle.
Definition accumulator.hxx:3481
Compute weighted version of the statistic.
Definition accumulator.hxx:3509
DivideUnbiased< FlatScatterMatrix > UnbiasedCovariance
Alias. Unbiased covariance.
Definition accumulator-grammar.hxx:206
Coord< Principal< StdDev > > RegionRadii
Alias. Region radii.
Definition accumulator-grammar.hxx:225
PowerSum< 1 > Sum
Alias. Sum.
Definition accumulator-grammar.hxx:168
SumOfSquaredDifferences SSD
Alias. Sum of squared differences.
Definition accumulator-grammar.hxx:192
DivideByCount< ScatterMatrixEigensystem > CovarianceEigensystem
Alias. Covariance eigensystem.
Definition accumulator-grammar.hxx:208
Weighted< RegionCenter > WeightedRegionCenter
Alias. Region center weighted by the region intensity (center of mass).
Definition accumulator-grammar.hxx:232
Coord< FirstSeen > RegionAnchor
Alias. Anchor point (first point of the region seen by scan-order traversal.
Definition accumulator-grammar.hxx:220
RootDivideByCount< SumOfSquares > RootMeanSquares
Alias. Root mean square.
Definition accumulator-grammar.hxx:175
DivideByCount< FlatScatterMatrix > Covariance
Alias. Covariance.
Definition accumulator-grammar.hxx:204
Weighted< RegionCenter > CenterOfMass
Alias. Center of mass.
Definition accumulator-grammar.hxx:230
PowerSum< 2 > SumOfSquares
Alias. Sum of squares.
Definition accumulator-grammar.hxx:170
Coord< Mean > RegionCenter
Alias. Region center.
Definition accumulator-grammar.hxx:223
Weighted< Coord< Principal< Variance > > > MomentsOfInertia
Alias. Moments of inertia.
Definition accumulator-grammar.hxx:234
Coord< Range > BoundingBox
Alias. Rectangle enclosing the region, as a std::pair of coordinates.
Definition accumulator-grammar.hxx:218
Central< PowerSum< 2 > > SumOfSquaredDifferences
Alias. Sum of squared differences.
Definition accumulator-grammar.hxx:190
Weighted< RegionAxes > AxesOfInertia
Alias. Axes of inertia.
Definition accumulator-grammar.hxx:238
DivideByCount< SumOfAbsDifferences > MeanAbsoluteDeviation
Alias. Mean absolute deviation.
Definition accumulator-grammar.hxx:215
PowerSum< 0 > Count
Alias. Count.
Definition accumulator-grammar.hxx:166
Weighted< RegionRadii > WeightedRegionRadii
Alias. Region radius weighted by region intensity (square root of the moments of inertia).
Definition accumulator-grammar.hxx:236
Central< AbsSum > SumOfAbsDifferences
Alias. Sum of absolute differences.
Definition accumulator-grammar.hxx:213
DivideUnbiased< Central< PowerSum< 2 > > > UnbiasedVariance
Alias. Unbiased variance.
Definition accumulator-grammar.hxx:199
DivideByCount< Sum > Mean
Alias. Mean.
Definition accumulator-grammar.hxx:173
AbsPowerSum< 1 > AbsSum
Alias. Absolute sum.
Definition accumulator-grammar.hxx:211
RootDivideByCount< Central< PowerSum< 2 > > > StdDev
Alias. Standard deviation.
Definition accumulator-grammar.hxx:197
RootDivideUnbiased< Central< PowerSum< 2 > > > UnbiasedStdDev
Alias. Unbiased standard deviation.
Definition accumulator-grammar.hxx:201
DivideByCount< Central< PowerSum< 2 > > > Variance
Alias. Variance.
Definition accumulator-grammar.hxx:195
Coord< Principal< CoordinateSystem > > RegionAxes
Alias. Region axes.
Definition accumulator-grammar.hxx:227

© 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.11.1