[ 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 #ifdef WITH_LEMON
106 class ConvexHull; // base class for convex hull computation
107 class ConvexHullFeatures; // base class for convex hull features
108 #endif
109 
110 /*
111 Quantiles 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
139 template <class A> class DivideByCount; // A / count
140 template <class A> class RootDivideByCount; // sqrt(A / count)
141 template <class A> class DivideUnbiased; // A / (count - 1)
142 template <class A> class RootDivideUnbiased; // sqrt(A / (count - 1))
143 
144  // data access
145 template <class A> class Coord; // use pixel coordinate instead of pixel value (index 0 of CoupledHandle)
146 template <class A> class Weighted; // use (value, weight) pairs (index 1 and 2 of CoupledHandle)
147 template <class A> class CoordWeighted; // use (coord, weight) pairs(index 0 and end of CoupledHandle)
148 template <class A> class DataFromHandle; // extract data from index 1 of a CoupledHandle
149 
150  // data preparation
151 template <class A> class Central; // subtract mean
152 template <class A> class Principal; // subtract mean and rotate to principal coordinates
153 
154  // FIXME: not implemented yet
155 template <class A> class Whitened; // transform to principal coordinates and scale to unit variance
156 
157 template <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. */
166 typedef PowerSum<0> Count;
167 /** \brief Alias. Sum. */
168 typedef PowerSum<1> 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>. */
185 template <unsigned N> class Moment;
186 /** \brief Alias. CentralMoment<N>. */
187 template <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 
246 namespace acc_detail {
247 
248 template <class A>
249 struct ModifierRule
250 {
251  typedef A type;
252 };
253 
254 } // namespace acc_detail
255 
256 template <class A>
257 struct Error___Tag_modifiers_of_same_kind_must_not_be_combined;
258 
259  // apply rules as long as the Tag type changes ...
260 template <class A, class S=typename acc_detail::ModifierRule<A>::type>
261 struct StandardizeTag
262 {
263  typedef typename StandardizeTag<S>::type type;
264 };
265 
266  // ... and stop otherwise ...
267 template <class A>
268 struct StandardizeTag<A, A>
269 {
270  typedef A type;
271 };
272 
273  // ... or fail when the tag spec was non-conforming
274 template <class A, class B>
275 struct 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 
279 namespace 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.
283 enum { 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 
293 template <class A>
294 struct ModifierPriority
295 {
296  static const int value = AccumulatorPriority;
297 };
298 
299 #define VIGRA_MODIFIER_PRIORITY(MODIFIER, VALUE) \
300 template <class A> \
301 struct ModifierPriority<MODIFIER<A> > \
302 { \
303  static const int value = VALUE; \
304 };
305 
306 VIGRA_MODIFIER_PRIORITY(Global, GlobalPriority)
307 
308 VIGRA_MODIFIER_PRIORITY(Weighted, WeightingPriority)
309 
310 VIGRA_MODIFIER_PRIORITY(Coord, AccessDataPriority)
311 VIGRA_MODIFIER_PRIORITY(DataFromHandle, AccessDataPriority)
312 
313 VIGRA_MODIFIER_PRIORITY(DivideByCount, NormalizePriority)
314 VIGRA_MODIFIER_PRIORITY(RootDivideByCount, NormalizePriority)
315 VIGRA_MODIFIER_PRIORITY(DivideUnbiased, NormalizePriority)
316 VIGRA_MODIFIER_PRIORITY(RootDivideUnbiased, NormalizePriority)
317 
318 VIGRA_MODIFIER_PRIORITY(Central, PrepareDataPriority)
319 VIGRA_MODIFIER_PRIORITY(Principal, PrepareDataPriority)
320 VIGRA_MODIFIER_PRIORITY(Whitened, PrepareDataPriority)
321 
322  // explicitly set priority for base accumulators that look like modifiers
323 VIGRA_MODIFIER_PRIORITY(StandardQuantiles, AccumulatorPriority)
324 
325 #undef VIGRA_MODIFIER_PRIORITY
326 
327  // check if the tag A contains a modifier with TARGET_PRIORITY
328 template <class A, int TARGET_PRIORITY, int PRIORITY=ModifierPriority<A>::value>
329 struct HasModifierPriority
330 {
331  typedef VigraFalseType type;
332  static const bool value = false;
333 };
334 
335 template <class A, int TARGET_PRIORITY>
336 struct HasModifierPriority<A, TARGET_PRIORITY, TARGET_PRIORITY>
337 {
338  typedef VigraTrueType type;
339  static const bool value = true;
340 };
341 
342 template <class A, template <class> class B, int TARGET_PRIORITY, int PRIORITY>
343 struct HasModifierPriority<B<A>, TARGET_PRIORITY, PRIORITY>
344 : public HasModifierPriority<A, TARGET_PRIORITY>
345 {};
346 
347 template <class A, template <class> class B, int TARGET_PRIORITY>
348 struct HasModifierPriority<B<A>, TARGET_PRIORITY, TARGET_PRIORITY>
349 {
350  typedef VigraTrueType type;
351  static const bool value = true;
352 };
353 
354  // three-way compare
355 template <class A, class B>
356 struct 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 
367 template <class A>
368 struct ModifierCompareToInner;
369 
370 template <class A, template <class> class B>
371 struct ModifierCompareToInner<B<A> >
372 : public ModifierCompare<B<A>, A>
373 {};
374 
375  // sort modifiers by ascending priority
376 template <class A, int compare=ModifierCompareToInner<A>::value>
377 struct ModifierOrder;
378 
379  // do nothing if the order is correct (compare == -1)
380 template <class A>
381 struct ModifierOrder<A, -1>
382 {
383  typedef A type;
384 };
385 
386  // fail if there are two modifiers with the same priority (compare == 0)
387 template <class A, template <class> class B, template <class> class C>
388 struct 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)
394 template <class A, template <class> class B, template <class> class C>
395 struct ModifierOrder<C<B<A> >, 1>
396 {
397  typedef B<C<A> > type;
398 };
399 
400 #define VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(OUTER, INNER, RESULT) \
401 template <class A> \
402 struct ModifierOrder<OUTER<INNER<A > >, 0> \
403 { \
404  typedef RESULT<A > type; \
405 };
406 
407  // drop duplicates
408 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Central, Central, Central)
409 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Principal, Principal, Principal)
410 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Whitened, Whitened)
411 
412  // the strongest data preparation modifier takes precendence
413 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Principal, Central, Principal)
414 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Central, Whitened)
415 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(Whitened, Principal, Whitened)
416 
417  // Coord takes precendence over DataFromHandle
418 VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS(DataFromHandle, Coord, Coord)
419 
420 #undef VIGRA_CLEANUP_DATA_PREPARATION_MODIFIERS
421 
422  // drop duplicates
423 template <class A, template <class> class B>
424 struct ModifierRule<B<B<A> > >
425 {
426  typedef B<A> type;
427 };
428 
429 template <class A, int PRIORITY=ModifierPriority<A>::value>
430 struct RecurseModifier;
431 
432 template <class A, template <class> class B, int PRIORITY>
433 struct RecurseModifier<B<A>, PRIORITY>
434 {
435  typedef typename ModifierOrder<B<typename StandardizeTag<A>::type> >::type type;
436 };
437 
438 template <class A, template <class> class B>
439 struct 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')
447 template <class A, template <class> class B>
448 struct 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) \
456 template <TEMPLATE > \
457 struct ModifierRule<SOURCE > \
458 { \
459  typedef TARGET type; \
460 };
461 
462 #define VIGRA_VOID
463 
464  // centralizing doesn't change the CoordinateSystem
465 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<CoordinateSystem>, CoordinateSystem)
466  // whitened CoordinateSystem are the same as principal CoordinateSystem
467 VIGRA_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
470 VIGRA_REDUCE_MODFIER(template <class> class A, A<Count>, Count)
471 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Weighted<Count>, Weighted<Count>)
472 VIGRA_REDUCE_MODFIER(VIGRA_VOID, CoordWeighted<Count>, Weighted<Count>)
473 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Global<Count>, Global<Count>)
474 
475  // reduce aliases that typedef can't handle
476 VIGRA_REDUCE_MODFIER(unsigned N, Moment<N>, DivideByCount<PowerSum<N> >)
477 VIGRA_REDUCE_MODFIER(unsigned N, CentralMoment<N>, DivideByCount<Central<PowerSum<N> > >)
478 VIGRA_REDUCE_MODFIER(class A, CoordWeighted<A>, Weighted<Coord<A> >)
479 
480  // reduce statistics that are inherently centered
481 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Centralize>, Centralize)
482 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Skewness>, Skewness)
483 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<Kurtosis>, Kurtosis)
484 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<FlatScatterMatrix>, FlatScatterMatrix)
485 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Central<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
486 
487 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Principal<Centralize>, PrincipalProjection)
488 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<Centralize>, Whiten)
489 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Principal<PrincipalProjection>, PrincipalProjection)
490 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<PrincipalProjection>, Whiten)
491 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Whitened<Whiten>, Whiten)
492 
493  // ignore all modifiers of RegionContour and related features
494 VIGRA_REDUCE_MODFIER(template <class> class A, A<RegionContour>, RegionContour)
495 #ifdef WITH_LEMON
496 VIGRA_REDUCE_MODFIER(template <class> class A, A<ConvexHull>, ConvexHull)
497 VIGRA_REDUCE_MODFIER(template <class> class A, A<ConvexHullFeatures>, ConvexHullFeatures)
498 #endif // WITH_LEMON
499 VIGRA_REDUCE_MODFIER(template <class> class A, A<RegionPerimeter>, RegionPerimeter)
500 VIGRA_REDUCE_MODFIER(template <class> class A, A<RegionCircularity>, RegionCircularity)
501 VIGRA_REDUCE_MODFIER(template <class> class A, A<RegionEccentricity>, RegionEccentricity)
502 VIGRA_REDUCE_MODFIER(VIGRA_VOID, Weighted<RegionEccentricity>, Weighted<RegionEccentricity>)
503 
504  // reduce even absolute powers to plain powers
505 template <unsigned N>
506 struct 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 
514 template <class A>
515 struct ShouldBeWeighted
516 {
517  typedef VigraFalseType type;
518  static const bool value = false;
519 };
520 
521 template <>
522 struct ShouldBeWeighted<ArgMinWeight>
523 {
524  typedef VigraTrueType type;
525  static const bool value = true;
526 };
527 
528 template <>
529 struct ShouldBeWeighted<ArgMaxWeight>
530 {
531  typedef VigraTrueType type;
532  static const bool value = true;
533 };
534 
535 template <class A, template <class> class B>
536 struct ShouldBeWeighted<B<A> >
537 : public ShouldBeWeighted<A>
538 {};
539 
540 } // namespace acc_detail
541 
542 template <class A>
543 struct IsCoordinateFeature
544 {
545  typedef VigraFalseType type;
546  static const bool value = false;
547 };
548 
549 template <class A, template <class> class B>
550 struct IsCoordinateFeature<B<A> >
551 {
552  typedef typename IsCoordinateFeature<A>::type type;
553  static const bool value = IsCoordinateFeature<A>::value;
554 };
555 
556 template <class A>
557 struct IsCoordinateFeature<Coord<A> >
558 {
559  typedef VigraTrueType type;
560  static const bool value = true;
561 };
562 
563 template <class A>
564 struct IsPrincipalFeature
565 {
566  typedef VigraFalseType type;
567  static const bool value = false;
568 };
569 
570 template <class A, template <class> class B>
571 struct IsPrincipalFeature<B<A> >
572 {
573  typedef typename IsPrincipalFeature<A>::type type;
574  static const bool value = IsPrincipalFeature<A>::value;
575 };
576 
577 template <class A>
578 struct IsPrincipalFeature<Principal<A> >
579 {
580  typedef VigraTrueType type;
581  static const bool value = true;
582 };
583 
584 template <class A>
585 struct 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 
597 namespace acc_detail {
598 
599 template <class A>
600 struct DefaultModifier;
601 
602 template <class A>
603 struct ModifierPriority<DefaultModifier<A> >
604 {
605  static const int value = ModifierPriority<A>::value << 1;
606 };
607 
608 template <class A, int TargetPriority, int Priority=ModifierPriority<A>::value>
609 struct InsertDefaultModifier
610 {
611  typedef DefaultModifier<typename InsertDefaultModifier<A, (TargetPriority << 1)>::type> type;
612 };
613 
614 template <class A, int TargetPriority>
615 struct InsertDefaultModifier<A, TargetPriority, TargetPriority>
616 {
617  typedef A type;
618 };
619 
620 template <class A, int TargetPriority, int Priority=ModifierPriority<A>::value>
621 struct TagLongForm;
622 
623 template <class A, int TargetPriority>
624 struct TagLongForm<A, TargetPriority, MaxPriority>
625 {
626  typedef typename InsertDefaultModifier<A, TargetPriority>::type type;
627 };
628 
629 template <class A, template <class> class B, int TargetPriority>
630 struct TagLongForm<B<A>, TargetPriority, MaxPriority>
631 {
632  typedef typename InsertDefaultModifier<B<A>, TargetPriority>::type type;
633 };
634 
635 template <class A, template <class> class B, int TargetPriority, int Priority>
636 struct 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 
642 template <class A, template <class> class B, int TargetPriority>
643 struct TagLongForm<B<A>, TargetPriority, TargetPriority>
644 {
645  typedef typename TagLongForm<A, (TargetPriority << 1)>::type Inner;
646  typedef B<Inner> type;
647 };
648 
649 template <class A>
650 struct LongModifierRule
651 {
652  typedef A type;
653 };
654 
655  // apply rules as long as the Tag type changes ...
656 template <class A, class S=typename LongModifierRule<A>::type>
657 struct StandardizeTagLongForm
658 {
659  typedef typename StandardizeTagLongForm<S>::type type;
660 };
661 
662  // ... and stop otherwise ...
663 template <class A>
664 struct StandardizeTagLongForm<A, A>
665 {
666  typedef A type;
667 };
668 
669 template <class A, template <class> class B>
670 struct LongModifierRule<B<A> >
671 {
672  typedef B<typename LongModifierRule<A>::type> type;
673 };
674 
675 template <class A>
676 struct LongModifierRule<DefaultModifier<A> >
677 {
678  typedef A type;
679 };
680 
681 #define VIGRA_DROP_DATA_PREPARATION_MODIFIERS(SOURCE, TARGET) \
682 template <> \
683 struct LongModifierRule<SOURCE > \
684 { \
685  typedef TARGET type; \
686 };
687 
688 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Central<Sum>, Sum)
689 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<Sum>, Sum)
690 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<Sum>, Sum)
691 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<FlatScatterMatrix>, FlatScatterMatrix)
692 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<FlatScatterMatrix>, FlatScatterMatrix)
693 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Principal<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
694 VIGRA_DROP_DATA_PREPARATION_MODIFIERS(Whitened<ScatterMatrixEigensystem>, ScatterMatrixEigensystem)
695 
696 #undef VIGRA_DROP_DATA_PREPARATION_MODIFIERS
697 
698 template <class A>
699 struct CheckSubstitutionFlag
700 {
701  static const bool value = (ModifierPriority<A>::value & SubstitutionMask) != 0;
702 };
703 
704 template <class A, class B,
705  bool substitute=CheckSubstitutionFlag<A>::value>
706 struct SubstituteModifiers;
707 
708 template <class A, class B>
709 struct SubstituteModifiers<A, B, false>
710 {
711  typedef B type;
712 };
713 
714 template <class A, template <class> class AA, class B, template <class> class BB>
715 struct SubstituteModifiers<AA<A>, BB<B>, true>
716 {
717  typedef AA<typename SubstituteModifiers<A, B>::type> type;
718 };
719 
720 template <class A, class B, template <class> class BB>
721 struct SubstituteModifiers<DefaultModifier<A>, BB<B>, true>
722 {
723  typedef BB<typename SubstituteModifiers<A, B>::type> type;
724 };
725 
726 template <class A, template <class> class AA, class B, template <class> class BB>
727 struct SubstituteModifiers<AA<A>, BB<B>, false>
728 {
729  typedef BB<typename SubstituteModifiers<A, B>::type> type;
730 };
731 
732 } // namespace acc_detail
733 
734 template <class A, class B>
735 struct 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 
746 template <class A, class HEAD, class TAIL>
747 struct TransferModifiers<A, TypeList<HEAD, TAIL> >
748 {
749  typedef TypeList<typename TransferModifiers<A, HEAD>::type,
750  typename TransferModifiers<A, TAIL>::type> type;
751 };
752 
753 template <class A>
754 struct TransferModifiers<A, void>
755 {
756  typedef void type;
757 };
758 
759 template <class TargetTag, class A=typename TargetTag::Dependencies>
760 struct StandardizeDependencies
761 #ifndef DOXYGEN
762 : public StandardizeDependencies<TargetTag, typename A::type>
763 #endif
764 {};
765 
766 template <class TargetTag, class HEAD, class TAIL>
767 struct 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 
773 template <class TargetTag>
774 struct StandardizeDependencies<TargetTag, void>
775 {
776  typedef void type;
777 };
778 
779 }} // namespace vigra::acc
780 
781 #endif // VIGRA_ACCUMULATOR_GRAMMAR_HXX
Basic statistic. Data value where weight assumes its minimal value.
Definition: accumulator.hxx:5384
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:197
PowerSum< 0 > Count
Alias. Count.
Definition: accumulator-grammar.hxx:157
Central< PowerSum< 2 > > SumOfSquaredDifferences
Alias. Sum of squared differences.
Definition: accumulator-grammar.hxx:187
Spezialization: works in pass 1, operator+=() supported (merging supported).
Definition: accumulator.hxx:4270
DivideByCount< Central< PowerSum< 2 > > > Variance
Alias. Variance.
Definition: accumulator-grammar.hxx:195
Basic statistic. First data value seen of the object.
Definition: accumulator.hxx:5285
DivideByCount< SumOfAbsDifferences > MeanAbsoluteDeviation
Alias. Mean absolute deviation.
Definition: accumulator-grammar.hxx:215
Basic statistic. Maximum value.
Definition: accumulator.hxx:5206
AbsPowerSum< 1 > AbsSum
Alias. Absolute sum.
Definition: accumulator-grammar.hxx:211
Compute the eccentricity of a 2D region in terms of its prinipal radii.
Definition: accumulator.hxx:6237
PowerSum< 2 > SumOfSquares
Alias. Sum of squares.
Definition: accumulator-grammar.hxx:170
Modifier. Compute statistic globally rather than per region.
Definition: accumulator-grammar.hxx:157
Return both the minimum and maximum in std::pair.
Definition: accumulator.hxx:5353
Basic statistic. Skewness.
Definition: accumulator.hxx:4445
SumOfSquaredDifferences SSD
Alias. Sum of squared differences.
Definition: accumulator-grammar.hxx:192
Coord< FirstSeen > RegionAnchor
Alias. Anchor point (first point of the region seen by scan-order traversal.
Definition: accumulator-grammar.hxx:220
Compute the convex hull of a region.
Definition: accumulator.hxx:6275
Basic statistic. Identity matrix of appropriate size.
Definition: accumulator.hxx:3846
Compute object features related to the convex hull.
Definition: accumulator.hxx:6379
DivideByCount< ScatterMatrixEigensystem > CovarianceEigensystem
Alias. Covariance eigensystem.
Definition: accumulator-grammar.hxx:208
Basic statistic. Kurtosis.
Definition: accumulator.hxx:4517
Basic statistic. Unbiased Kurtosis.
Definition: accumulator.hxx:4553
DivideByCount< FlatScatterMatrix > Covariance
Alias. Covariance.
Definition: accumulator-grammar.hxx:204
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:4649
Modifier. Substract mean before computing statistic.
Definition: accumulator-grammar.hxx:151
Compute weighted version of the statistic.
Definition: accumulator-grammar.hxx:146
DivideUnbiased< Central< PowerSum< 2 > > > UnbiasedVariance
Alias. Unbiased variance.
Definition: accumulator-grammar.hxx:199
Alias. CentralMoment<N>.
Definition: accumulator-grammar.hxx:187
Weighted< RegionCenter > CenterOfMass
Alias. Center of mass.
Definition: accumulator-grammar.hxx:230
Weighted< Coord< Principal< Variance > > > MomentsOfInertia
Alias. Moments of inertia.
Definition: accumulator-grammar.hxx:234
Compute the contour of a 2D region.
Definition: accumulator.hxx:6099
Weighted< RegionRadii > WeightedRegionRadii
Alias. Region radius weighted by region intensity (square root of the moments of inertia).
Definition: accumulator-grammar.hxx:236
DivideByCount< Sum > Mean
Alias. Mean.
Definition: accumulator-grammar.hxx:173
Basic statistic. Unbiased Skewness.
Definition: accumulator.hxx:4481
Coord< Mean > RegionCenter
Alias. Region center.
Definition: accumulator-grammar.hxx:223
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:185
PowerSum< 1 > Sum
Alias. Sum.
Definition: accumulator-grammar.hxx:168
Definition: accumulator.hxx:4819
RootDivideByCount< SumOfSquares > RootMeanSquares
Alias. Root mean square.
Definition: accumulator-grammar.hxx:175
Modifier. Project onto PCA eigenvectors.
Definition: accumulator-grammar.hxx:152
Coord< Range > BoundingBox
Alias. Rectangle enclosing the region, as a std::pair of coordinates.
Definition: accumulator-grammar.hxx:218
Central< AbsSum > SumOfAbsDifferences
Alias. Sum of absolute differences.
Definition: accumulator-grammar.hxx:213
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:5459
Modifier. RootDivideByCount<TAG> = sqrt( TAG/Count )
Definition: accumulator-grammar.hxx:140
DivideUnbiased< FlatScatterMatrix > UnbiasedCovariance
Alias. Unbiased covariance.
Definition: accumulator-grammar.hxx:206
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:6172
Modifier. Divide statistic by Count: DivideByCount<TAG> = TAG / Count .
Definition: accumulator-grammar.hxx:139
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:232
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:201
Coord< Principal< CoordinateSystem > > RegionAxes
Alias. Region axes.
Definition: accumulator-grammar.hxx:227
Basic statistic. Minimum value.
Definition: accumulator.hxx:5128
Weighted< RegionAxes > AxesOfInertia
Alias. Axes of inertia.
Definition: accumulator-grammar.hxx:238
Modifier. Divide statistics by Count-1: DivideUnbiased<TAG> = TAG / (Count-1)
Definition: accumulator-grammar.hxx:141
Compute the circularity of a 2D region.
Definition: accumulator.hxx:6205
Modifier. Compute statistic from pixel coordinates rather than from pixel values. ...
Definition: accumulator-grammar.hxx:145
Coord< Principal< StdDev > > RegionRadii
Alias. Region radii.
Definition: accumulator-grammar.hxx:225
Modifier. RootDivideUnbiased<TAG> = sqrt( TAG / (Count-1) )
Definition: accumulator-grammar.hxx:142

© 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 (Fri May 19 2017)