[ 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 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. */
167 typedef PowerSum<2> SumOfSquares;
168
169 /** \brief Alias. Mean. */
170 typedef DivideByCount<Sum> Mean;
171 /** \brief Alias. Root mean square. */
172 typedef RootDivideByCount<SumOfSquares> RootMeanSquares;
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. */
187 typedef Central<PowerSum<2> > SumOfSquaredDifferences;
188 /** \brief Alias. Sum of squared differences. */
189 typedef SumOfSquaredDifferences SSD;
190
191 /** \brief Alias. Variance. */
192 typedef DivideByCount<Central<PowerSum<2> > > Variance;
193 /** \brief Alias. Standard deviation. */
194 typedef RootDivideByCount<Central<PowerSum<2> > > StdDev;
195 /** \brief Alias. Unbiased variance. */
196 typedef DivideUnbiased<Central<PowerSum<2> > > UnbiasedVariance;
197 /** \brief Alias. Unbiased standard deviation. */
198 typedef RootDivideUnbiased<Central<PowerSum<2> > > UnbiasedStdDev;
199
200 /** \brief Alias. Covariance. */
201 typedef DivideByCount<FlatScatterMatrix> Covariance;
202 /** \brief Alias. Unbiased covariance. */
203 typedef DivideUnbiased<FlatScatterMatrix> UnbiasedCovariance;
204 /** \brief Alias. Covariance eigensystem. */
205 typedef DivideByCount<ScatterMatrixEigensystem> CovarianceEigensystem;
206
207 /** \brief Alias. Absolute sum. */
208 typedef AbsPowerSum<1> AbsSum;
209 /** \brief Alias. Sum of absolute differences. */
210 typedef Central<AbsSum> SumOfAbsDifferences;
211 /** \brief Alias. Mean absolute deviation. */
212 typedef DivideByCount<SumOfAbsDifferences> MeanAbsoluteDeviation;
213
214 /** \brief Alias. Rectangle enclosing the region, as a <tt>std::pair</tt> of coordinates. */
215 typedef Coord<Range> BoundingBox;
216 /** \brief Alias. Anchor point (first point of the region seen by scan-order traversal. */
217 typedef Coord<FirstSeen> RegionAnchor;
218
219 /** \brief Alias. Region center. */
220 typedef Coord<Mean> RegionCenter;
221 /** \brief Alias. Region radii. */
222 typedef Coord<Principal<StdDev> > RegionRadii;
223 /** \brief Alias. Region axes. */
224 typedef Coord<Principal<CoordinateSystem> > RegionAxes;
225
226 /** \brief Alias. Center of mass. */
227 typedef Weighted<RegionCenter> CenterOfMass;
228 /** \brief Alias. Region center weighted by the region intensity (center of mass). */
229 typedef Weighted<RegionCenter> WeightedRegionCenter;
230 /** \brief Alias. Moments of inertia. */
231 typedef Weighted<Coord<Principal<Variance> > > MomentsOfInertia;
232 /** \brief Alias. Region radius weighted by region intensity (square root of the moments of inertia). */
233 typedef Weighted<RegionRadii> WeightedRegionRadii;
234 /** \brief Alias. Axes of inertia. */
235 typedef Weighted<RegionAxes> AxesOfInertia;
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
vigra::acc::ArgMinWeight
Basic statistic. Data value where weight assumes its minimal value.
Definition: accumulator.hxx:5378
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:194
vigra::acc::Count
PowerSum< 0 > Count
Alias. Count.
Definition: accumulator-grammar.hxx:154
vigra::acc::SumOfSquaredDifferences
Central< PowerSum< 2 > > SumOfSquaredDifferences
Alias. Sum of squared differences.
Definition: accumulator-grammar.hxx:184
vigra::acc::Variance
DivideByCount< Central< PowerSum< 2 > > > Variance
Alias. Variance.
Definition: accumulator-grammar.hxx:192
vigra::acc::FirstSeen
Basic statistic. First data value seen of the object.
Definition: accumulator.hxx:5279
vigra::acc::MeanAbsoluteDeviation
DivideByCount< SumOfAbsDifferences > MeanAbsoluteDeviation
Alias. Mean absolute deviation.
Definition: accumulator-grammar.hxx:212
vigra::acc::Maximum
Basic statistic. Maximum value.
Definition: accumulator.hxx:5200
vigra::acc::AbsSum
AbsPowerSum< 1 > AbsSum
Alias. Absolute sum.
Definition: accumulator-grammar.hxx:208
vigra::acc::RegionEccentricity
Compute the eccentricity of a 2D region in terms of its prinipal radii.
Definition: accumulator.hxx:6231
vigra::acc::SumOfSquares
PowerSum< 2 > SumOfSquares
Alias. Sum of squares.
Definition: accumulator-grammar.hxx:167
vigra::acc::Global
Modifier. Compute statistic globally rather than per region.
Definition: accumulator-grammar.hxx:154
vigra::acc::Range
Return both the minimum and maximum in std::pair.
Definition: accumulator.hxx:5347
vigra::acc::Skewness
Basic statistic. Skewness.
Definition: accumulator.hxx:4439
vigra::acc::SSD
SumOfSquaredDifferences SSD
Alias. Sum of squared differences.
Definition: accumulator-grammar.hxx:189
vigra::acc::RegionAnchor
Coord< FirstSeen > RegionAnchor
Alias. Anchor point (first point of the region seen by scan-order traversal.
Definition: accumulator-grammar.hxx:217
vigra::acc::ConvexHull
Compute the contour of a 2D region.
Definition: accumulator.hxx:6268
vigra::acc::CoordinateSystem
Basic statistic. Identity matrix of appropriate size.
Definition: accumulator.hxx:3840
vigra::acc::CovarianceEigensystem
DivideByCount< ScatterMatrixEigensystem > CovarianceEigensystem
Alias. Covariance eigensystem.
Definition: accumulator-grammar.hxx:205
vigra::acc::Kurtosis
Basic statistic. Kurtosis.
Definition: accumulator.hxx:4511
vigra::acc::UnbiasedKurtosis
Basic statistic. Unbiased Kurtosis.
Definition: accumulator.hxx:4547
vigra::acc::Covariance
DivideByCount< FlatScatterMatrix > Covariance
Alias. Covariance.
Definition: accumulator-grammar.hxx:201
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:4643
vigra::acc::Central
Modifier. Substract mean before computing statistic.
Definition: accumulator-grammar.hxx:148
vigra::acc::Weighted
Compute weighted version of the statistic.
Definition: accumulator-grammar.hxx:143
vigra::acc::UnbiasedVariance
DivideUnbiased< Central< PowerSum< 2 > > > UnbiasedVariance
Alias. Unbiased variance.
Definition: accumulator-grammar.hxx:196
vigra::acc::CentralMoment
Alias. CentralMoment<N>.
Definition: accumulator-grammar.hxx:184
vigra::acc::CenterOfMass
Weighted< RegionCenter > CenterOfMass
Alias. Center of mass.
Definition: accumulator-grammar.hxx:227
vigra
Definition: accessor.hxx:43
vigra::acc::MomentsOfInertia
Weighted< Coord< Principal< Variance > > > MomentsOfInertia
Alias. Moments of inertia.
Definition: accumulator-grammar.hxx:231
vigra::acc::Principal< CoordinateSystem >
Specialization (covariance eigenvectors): works in pass 1, operator+=() supported (merging)...
Definition: accumulator.hxx:5092
vigra::acc::RegionContour
Compute the contour of a 2D region.
Definition: accumulator.hxx:6093
vigra::acc::WeightedRegionRadii
Weighted< RegionRadii > WeightedRegionRadii
Alias. Region radius weighted by region intensity (square root of the moments of inertia).
Definition: accumulator-grammar.hxx:233
vigra::acc::Mean
DivideByCount< Sum > Mean
Alias. Mean.
Definition: accumulator-grammar.hxx:170
vigra::acc::UnbiasedSkewness
Basic statistic. Unbiased Skewness.
Definition: accumulator.hxx:4475
vigra::acc::RegionCenter
Coord< Mean > RegionCenter
Alias. Region center.
Definition: accumulator-grammar.hxx:220
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:182
vigra::acc::Sum
PowerSum< 1 > Sum
Alias. Sum.
Definition: accumulator-grammar.hxx:165
vigra::acc::ScatterMatrixEigensystem
Definition: accumulator.hxx:4813
vigra::acc::RootMeanSquares
RootDivideByCount< SumOfSquares > RootMeanSquares
Alias. Root mean square.
Definition: accumulator-grammar.hxx:172
vigra::acc::Principal
Modifier. Project onto PCA eigenvectors.
Definition: accumulator-grammar.hxx:149
vigra::acc::BoundingBox
Coord< Range > BoundingBox
Alias. Rectangle enclosing the region, as a std::pair of coordinates.
Definition: accumulator-grammar.hxx:215
vigra::acc::SumOfAbsDifferences
Central< AbsSum > SumOfAbsDifferences
Alias. Sum of absolute differences.
Definition: accumulator-grammar.hxx:210
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:5453
vigra::acc::RootDivideByCount
Modifier. RootDivideByCount<TAG> = sqrt( TAG/Count )
Definition: accumulator-grammar.hxx:137
vigra::acc::UnbiasedCovariance
DivideUnbiased< FlatScatterMatrix > UnbiasedCovariance
Alias. Unbiased covariance.
Definition: accumulator-grammar.hxx:203
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:6166
vigra::acc::DivideByCount
Modifier. Divide statistic by Count: DivideByCount<TAG> = TAG / Count .
Definition: accumulator-grammar.hxx:136
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:229
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:198
vigra::acc::RegionAxes
Coord< Principal< CoordinateSystem > > RegionAxes
Alias. Region axes.
Definition: accumulator-grammar.hxx:224
vigra::acc::Minimum
Basic statistic. Minimum value.
Definition: accumulator.hxx:5122
vigra::acc::AxesOfInertia
Weighted< RegionAxes > AxesOfInertia
Alias. Axes of inertia.
Definition: accumulator-grammar.hxx:235
vigra::acc::DivideUnbiased
Modifier. Divide statistics by Count-1: DivideUnbiased<TAG> = TAG / (Count-1)
Definition: accumulator-grammar.hxx:138
vigra::acc::RegionCircularity
Compute the circularity of a 2D region.
Definition: accumulator.hxx:6199
vigra::acc::Coord
Modifier. Compute statistic from pixel coordinates rather than from pixel values. ...
Definition: accumulator-grammar.hxx:142
vigra::acc::RegionRadii
Coord< Principal< StdDev > > RegionRadii
Alias. Region radii.
Definition: accumulator-grammar.hxx:222
vigra::acc::RootDivideUnbiased
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