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

accumulator-grammar.hxx VIGRA

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

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