[ 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
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. */
170 typedef PowerSum<2> SumOfSquares;
171
172 /** \brief Alias. Mean. */
173 typedef DivideByCount<Sum> Mean;
174 /** \brief Alias. Root mean square. */
175 typedef RootDivideByCount<SumOfSquares> RootMeanSquares;
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. */
190 typedef Central<PowerSum<2> > SumOfSquaredDifferences;
191 /** \brief Alias. Sum of squared differences. */
192 typedef SumOfSquaredDifferences SSD;
193
194 /** \brief Alias. Variance. */
195 typedef DivideByCount<Central<PowerSum<2> > > Variance;
196 /** \brief Alias. Standard deviation. */
197 typedef RootDivideByCount<Central<PowerSum<2> > > StdDev;
198 /** \brief Alias. Unbiased variance. */
199 typedef DivideUnbiased<Central<PowerSum<2> > > UnbiasedVariance;
200 /** \brief Alias. Unbiased standard deviation. */
201 typedef RootDivideUnbiased<Central<PowerSum<2> > > UnbiasedStdDev;
202
203 /** \brief Alias. Covariance. */
204 typedef DivideByCount<FlatScatterMatrix> Covariance;
205 /** \brief Alias. Unbiased covariance. */
206 typedef DivideUnbiased<FlatScatterMatrix> UnbiasedCovariance;
207 /** \brief Alias. Covariance eigensystem. */
208 typedef DivideByCount<ScatterMatrixEigensystem> CovarianceEigensystem;
209
210 /** \brief Alias. Absolute sum. */
211 typedef AbsPowerSum<1> AbsSum;
212 /** \brief Alias. Sum of absolute differences. */
213 typedef Central<AbsSum> SumOfAbsDifferences;
214 /** \brief Alias. Mean absolute deviation. */
215 typedef DivideByCount<SumOfAbsDifferences> MeanAbsoluteDeviation;
216
217 /** \brief Alias. Rectangle enclosing the region, as a <tt>std::pair</tt> of coordinates. */
218 typedef Coord<Range> BoundingBox;
219 /** \brief Alias. Anchor point (first point of the region seen by scan-order traversal. */
220 typedef Coord<FirstSeen> RegionAnchor;
221
222 /** \brief Alias. Region center. */
223 typedef Coord<Mean> RegionCenter;
224 /** \brief Alias. Region radii. */
225 typedef Coord<Principal<StdDev> > RegionRadii;
226 /** \brief Alias. Region axes. */
227 typedef Coord<Principal<CoordinateSystem> > RegionAxes;
228
229 /** \brief Alias. Center of mass. */
230 typedef Weighted<RegionCenter> CenterOfMass;
231 /** \brief Alias. Region center weighted by the region intensity (center of mass). */
232 typedef Weighted<RegionCenter> WeightedRegionCenter;
233 /** \brief Alias. Moments of inertia. */
234 typedef Weighted<Coord<Principal<Variance> > > MomentsOfInertia;
235 /** \brief Alias. Region radius weighted by region intensity (square root of the moments of inertia). */
236 typedef Weighted<RegionRadii> WeightedRegionRadii;
237 /** \brief Alias. Axes of inertia. */
238 typedef Weighted<RegionAxes> AxesOfInertia;
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
vigra::acc::ArgMinWeight
Basic statistic. Data value where weight assumes its minimal value.
Definition: accumulator.hxx:5384
vigra::acc::UserRangeHistogram
Histogram where user provides bounds for linear range mapping from values to indices.
Definition: accumulator-grammar.hxx:71
vigra::acc::PowerSum
Basic statistic. PowerSum<N> = .
Definition: accumulator-grammar.hxx:59
vigra::acc::StdDev
RootDivideByCount< Central< PowerSum< 2 > > > StdDev
Alias. Standard deviation.
Definition: accumulator-grammar.hxx:197
vigra::acc::Count
PowerSum< 0 > Count
Alias. Count.
Definition: accumulator-grammar.hxx:157
vigra::acc::SumOfSquaredDifferences
Central< PowerSum< 2 > > SumOfSquaredDifferences
Alias. Sum of squared differences.
Definition: accumulator-grammar.hxx:187
vigra::acc::Central< PowerSum< 2 > >
Spezialization: works in pass 1, operator+=() supported (merging supported).
Definition: accumulator.hxx:4270
vigra::acc::Variance
DivideByCount< Central< PowerSum< 2 > > > Variance
Alias. Variance.
Definition: accumulator-grammar.hxx:195
vigra::acc::FirstSeen
Basic statistic. First data value seen of the object.
Definition: accumulator.hxx:5285
vigra::acc::MeanAbsoluteDeviation
DivideByCount< SumOfAbsDifferences > MeanAbsoluteDeviation
Alias. Mean absolute deviation.
Definition: accumulator-grammar.hxx:215
vigra::acc::Maximum
Basic statistic. Maximum value.
Definition: accumulator.hxx:5206
vigra::acc::AbsSum
AbsPowerSum< 1 > AbsSum
Alias. Absolute sum.
Definition: accumulator-grammar.hxx:211
vigra::acc::RegionEccentricity
Compute the eccentricity of a 2D region in terms of its prinipal radii.
Definition: accumulator.hxx:6237
vigra::acc::SumOfSquares
PowerSum< 2 > SumOfSquares
Alias. Sum of squares.
Definition: accumulator-grammar.hxx:170
vigra::acc::Global
Modifier. Compute statistic globally rather than per region.
Definition: accumulator-grammar.hxx:157
vigra::acc::Range
Return both the minimum and maximum in std::pair.
Definition: accumulator.hxx:5353
vigra::acc::Skewness
Basic statistic. Skewness.
Definition: accumulator.hxx:4445
vigra::acc::SSD
SumOfSquaredDifferences SSD
Alias. Sum of squared differences.
Definition: accumulator-grammar.hxx:192
vigra::acc::RegionAnchor
Coord< FirstSeen > RegionAnchor
Alias. Anchor point (first point of the region seen by scan-order traversal.
Definition: accumulator-grammar.hxx:220
vigra::acc::ConvexHull
Compute the convex hull of a region.
Definition: accumulator.hxx:6275
vigra::acc::CoordinateSystem
Basic statistic. Identity matrix of appropriate size.
Definition: accumulator.hxx:3846
vigra::acc::ConvexHullFeatures
Compute object features related to the convex hull.
Definition: accumulator.hxx:6379
vigra::acc::CovarianceEigensystem
DivideByCount< ScatterMatrixEigensystem > CovarianceEigensystem
Alias. Covariance eigensystem.
Definition: accumulator-grammar.hxx:208
vigra::acc::Kurtosis
Basic statistic. Kurtosis.
Definition: accumulator.hxx:4517
vigra::acc::UnbiasedKurtosis
Basic statistic. Unbiased Kurtosis.
Definition: accumulator.hxx:4553
vigra::acc::Covariance
DivideByCount< FlatScatterMatrix > Covariance
Alias. Covariance.
Definition: accumulator-grammar.hxx:204
vigra::acc::AutoRangeHistogram
Histogram where range mapping bounds are defined by minimum and maximum of data.
Definition: accumulator-grammar.hxx:72
vigra::acc::FlatScatterMatrix
Basic statistic. Flattened uppter-triangular part of scatter matrix.
Definition: accumulator.hxx:4649
vigra::acc::Central
Modifier. Substract mean before computing statistic.
Definition: accumulator-grammar.hxx:151
vigra::acc::Weighted
Compute weighted version of the statistic.
Definition: accumulator-grammar.hxx:146
vigra::acc::UnbiasedVariance
DivideUnbiased< Central< PowerSum< 2 > > > UnbiasedVariance
Alias. Unbiased variance.
Definition: accumulator-grammar.hxx:199
vigra::acc::CentralMoment
Alias. CentralMoment<N>.
Definition: accumulator-grammar.hxx:187
vigra::acc::CenterOfMass
Weighted< RegionCenter > CenterOfMass
Alias. Center of mass.
Definition: accumulator-grammar.hxx:230
vigra::acc::MomentsOfInertia
Weighted< Coord< Principal< Variance > > > MomentsOfInertia
Alias. Moments of inertia.
Definition: accumulator-grammar.hxx:234
vigra::acc::RegionContour
Compute the contour of a 2D region.
Definition: accumulator.hxx:6099
vigra::acc::WeightedRegionRadii
Weighted< RegionRadii > WeightedRegionRadii
Alias. Region radius weighted by region intensity (square root of the moments of inertia).
Definition: accumulator-grammar.hxx:236
vigra::acc::Mean
DivideByCount< Sum > Mean
Alias. Mean.
Definition: accumulator-grammar.hxx:173
vigra::acc::UnbiasedSkewness
Basic statistic. Unbiased Skewness.
Definition: accumulator.hxx:4481
vigra::acc::RegionCenter
Coord< Mean > RegionCenter
Alias. Region center.
Definition: accumulator-grammar.hxx:223
vigra::acc::LabelArg
Specifies index of labels in CoupledHandle.
Definition: accumulator-grammar.hxx:97
vigra::acc::WeightArg
Specifies index of data in CoupledHandle.
Definition: accumulator-grammar.hxx:96
vigra::acc::Moment
Alias. Moment<N>.
Definition: accumulator-grammar.hxx:185
vigra::acc::Sum
PowerSum< 1 > Sum
Alias. Sum.
Definition: accumulator-grammar.hxx:168
vigra::acc::ScatterMatrixEigensystem
Definition: accumulator.hxx:4819
vigra::acc::RootMeanSquares
RootDivideByCount< SumOfSquares > RootMeanSquares
Alias. Root mean square.
Definition: accumulator-grammar.hxx:175
vigra::acc::Principal
Modifier. Project onto PCA eigenvectors.
Definition: accumulator-grammar.hxx:152
vigra::acc::BoundingBox
Coord< Range > BoundingBox
Alias. Rectangle enclosing the region, as a std::pair of coordinates.
Definition: accumulator-grammar.hxx:218
vigra::acc::SumOfAbsDifferences
Central< AbsSum > SumOfAbsDifferences
Alias. Sum of absolute differences.
Definition: accumulator-grammar.hxx:213
vigra::acc::IntegerHistogram
Histogram where data values are equal to bin indices.
Definition: accumulator-grammar.hxx:70
vigra::acc::ArgMaxWeight
Basic statistic. Data where weight assumes its maximal value.
Definition: accumulator.hxx:5459
vigra::acc::RootDivideByCount
Modifier. RootDivideByCount<TAG> = sqrt( TAG/Count )
Definition: accumulator-grammar.hxx:140
vigra::acc::UnbiasedCovariance
DivideUnbiased< FlatScatterMatrix > UnbiasedCovariance
Alias. Unbiased covariance.
Definition: accumulator-grammar.hxx:206
vigra::acc::StandardQuantiles
Compute (0%, 10%, 25%, 50%, 75%, 90%, 100%) quantiles from given histogram.
Definition: accumulator-grammar.hxx:79
vigra::acc::RegionPerimeter
Compute the perimeter of a 2D region.
Definition: accumulator.hxx:6172
vigra::acc::DivideByCount
Modifier. Divide statistic by Count: DivideByCount<TAG> = TAG / Count .
Definition: accumulator-grammar.hxx:139
vigra::acc::AbsPowerSum
Basic statistic. AbsPowerSum<N> = .
Definition: accumulator-grammar.hxx:60
vigra::acc::WeightedRegionCenter
Weighted< RegionCenter > WeightedRegionCenter
Alias. Region center weighted by the region intensity (center of mass).
Definition: accumulator-grammar.hxx:232
vigra::acc::DataArg
Specifies index of data in CoupledHandle.
Definition: accumulator-grammar.hxx:95
vigra::acc::GlobalRangeHistogram
Like AutoRangeHistogram, but use global min/max rather than region min/max.
Definition: accumulator-grammar.hxx:73
vigra::acc::UnbiasedStdDev
RootDivideUnbiased< Central< PowerSum< 2 > > > UnbiasedStdDev
Alias. Unbiased standard deviation.
Definition: accumulator-grammar.hxx:201
vigra::acc::RegionAxes
Coord< Principal< CoordinateSystem > > RegionAxes
Alias. Region axes.
Definition: accumulator-grammar.hxx:227
vigra::acc::Minimum
Basic statistic. Minimum value.
Definition: accumulator.hxx:5128
vigra::acc::AxesOfInertia
Weighted< RegionAxes > AxesOfInertia
Alias. Axes of inertia.
Definition: accumulator-grammar.hxx:238
vigra::acc::DivideUnbiased
Modifier. Divide statistics by Count-1: DivideUnbiased<TAG> = TAG / (Count-1)
Definition: accumulator-grammar.hxx:141
vigra::acc::RegionCircularity
Compute the circularity of a 2D region.
Definition: accumulator.hxx:6205
vigra::acc::Coord
Modifier. Compute statistic from pixel coordinates rather than from pixel values. ...
Definition: accumulator-grammar.hxx:145
vigra::acc::RegionRadii
Coord< Principal< StdDev > > RegionRadii
Alias. Region radii.
Definition: accumulator-grammar.hxx:225
vigra::acc::RootDivideUnbiased
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)