36 #ifndef VIGRA_ACCUMULATOR_HXX
37 #define VIGRA_ACCUMULATOR_HXX
40 #pragma warning (disable: 4503)
43 #include "accumulator-grammar.hxx"
45 #include "metaprogramming.hxx"
46 #include "bit_array.hxx"
47 #include "static_assert.hxx"
48 #include "mathutil.hxx"
50 #include "multi_iterator_coupled.hxx"
52 #include "multi_math.hxx"
53 #include "eigensystem.hxx"
54 #include "histogram.hxx"
55 #include "polygon.hxx"
56 #include "functorexpression.hxx"
57 #include "labelimage.hxx"
388 template <
class T01=void,
class T02=void,
class T03=void,
class T04=void,
class T05=void,
389 class T06=void,
class T07=void,
class T08=void,
class T09=void,
class T10=void,
390 class T11=void,
class T12=void,
class T13=void,
class T14=void,
class T15=void,
391 class T16=void,
class T17=void,
class T18=void,
class T19=void,
class T20=
void>
393 :
public MakeTypeList<
394 typename StandardizeTag<T01>::type, typename StandardizeTag<T02>::type, typename StandardizeTag<T03>::type,
395 typename StandardizeTag<T04>::type, typename StandardizeTag<T05>::type, typename StandardizeTag<T06>::type,
396 typename StandardizeTag<T07>::type, typename StandardizeTag<T08>::type, typename StandardizeTag<T09>::type,
397 typename StandardizeTag<T10>::type, typename StandardizeTag<T11>::type, typename StandardizeTag<T12>::type,
398 typename StandardizeTag<T13>::type, typename StandardizeTag<T14>::type, typename StandardizeTag<T15>::type,
399 typename StandardizeTag<T16>::type, typename StandardizeTag<T17>::type, typename StandardizeTag<T18>::type,
400 typename StandardizeTag<T19>::type, typename StandardizeTag<T20>::type
405 template <
class T01,
class T02,
class T03,
class T04,
class T05,
406 class T06,
class T07,
class T08,
class T09,
class T10,
407 class T11,
class T12,
class T13,
class T14,
class T15,
408 class T16,
class T17,
class T18,
class T19,
class T20>
409 struct StandardizeTag<
Select<T01, T02, T03, T04, T05,
410 T06, T07, T08, T09, T10,
411 T11, T12, T13, T14, T15,
412 T16, T17, T18, T19, T20>,
413 Select<T01, T02, T03, T04, T05,
414 T06, T07, T08, T09, T10,
415 T11, T12, T13, T14, T15,
416 T16, T17, T18, T19, T20> >
418 typedef typename Select<T01, T02, T03, T04, T05,
419 T06, T07, T08, T09, T10,
420 T11, T12, T13, T14, T15,
421 T16, T17, T18, T19, T20>::type type;
424 struct AccumulatorBegin
426 typedef Select<> Dependencies;
428 static std::string name()
430 return "AccumulatorBegin (internal)";
435 template <
class T,
class BASE>
442 struct AccumulatorEnd;
447 struct LabelDispatchTag;
449 template <
class T,
class TAG,
class CHAIN>
450 struct HandleArgSelector;
452 struct Error__Global_statistics_are_only_defined_for_AccumulatorChainArray;
462 typedef Select<> Dependencies;
464 static std::string name()
466 return std::string(
"LabelArg<") +
asString(INDEX) +
"> (internal)";
471 template <
class T,
class BASE>
475 typedef LabelArgTag Tag;
476 typedef void value_type;
477 typedef void result_type;
479 static const int value = INDEX;
480 static const unsigned int workInPass = 0;
488 typedef Select<> Dependencies;
490 static std::string name()
492 return std::string(
"CoordArg<") +
asString(INDEX) +
"> (internal)";
497 template <
class T,
class BASE>
501 typedef CoordArgTag Tag;
502 typedef void value_type;
503 typedef void result_type;
505 static const int value = INDEX;
506 static const unsigned int workInPass = 0;
510 template <
class T,
class TAG,
class NEXT=AccumulatorEnd>
511 struct AccumulatorBase;
513 template <
class Tag,
class A>
516 template <
class Tag,
class A,
class TargetTag=
typename A::Tag>
517 struct LookupDependency;
519 #ifndef _MSC_VER // compiler bug? (causes 'ambiguous overload error')
521 template <
class TAG,
class A>
522 typename LookupTag<TAG, A>::reference
525 template <
class TAG,
class A>
526 typename LookupDependency<TAG, A>::result_type
527 getDependency(A
const & a);
531 namespace acc_detail {
542 struct PushArgTagToTail
547 #define VIGRA_PUSHARGTAG(TAG) \
548 template <int INDEX, class TAIL> \
549 struct PushArgTagToTail<TypeList<TAG<INDEX>, TAIL> > \
551 typedef typename Push<TAIL, TypeList<TAG<INDEX> > >::type type; \
554 VIGRA_PUSHARGTAG(DataArg)
555 VIGRA_PUSHARGTAG(WeightArg)
556 VIGRA_PUSHARGTAG(CoordArg)
557 VIGRA_PUSHARGTAG(LabelArg)
559 #undef VIGRA_PUSHARGTAG
565 struct AddDependencies;
567 template <
class HEAD,
class TAIL>
568 struct AddDependencies<TypeList<HEAD, TAIL> >
570 typedef typename AddDependencies<TAIL>::type TailWithDependencies;
571 typedef typename StandardizeDependencies<HEAD>::type HeadDependencies;
572 typedef typename AddDependencies<HeadDependencies>::type TransitiveHeadDependencies;
573 typedef TypeList<HEAD, TransitiveHeadDependencies> HeadWithDependencies;
574 typedef typename PushUnique<HeadWithDependencies, TailWithDependencies>::type UnsortedDependencies;
575 typedef typename PushArgTagToTail<UnsortedDependencies>::type type;
579 struct AddDependencies<void>
586 template <
class Dependencies>
587 struct ActivateDependencies;
589 template <
class HEAD,
class TAIL>
590 struct ActivateDependencies<TypeList<HEAD, TAIL> >
592 template <
class Chain,
class ActiveFlags>
593 static void exec(ActiveFlags & flags)
595 LookupTag<HEAD, Chain>::type::activateImpl(flags);
596 ActivateDependencies<TAIL>::template exec<Chain>(flags);
599 template <
class Chain,
class ActiveFlags,
class GlobalFlags>
600 static void exec(ActiveFlags & flags, GlobalFlags & gflags)
602 LookupTag<HEAD, Chain>::type::template activateImpl<Chain>(flags, gflags);
603 ActivateDependencies<TAIL>::template exec<Chain>(flags, gflags);
607 template <
class HEAD,
class TAIL>
608 struct ActivateDependencies<TypeList<Global<HEAD>, TAIL> >
610 template <
class Chain,
class ActiveFlags,
class GlobalFlags>
611 static void exec(ActiveFlags & flags, GlobalFlags & gflags)
613 LookupTag<Global<HEAD>, Chain>::type::activateImpl(gflags);
614 ActivateDependencies<TAIL>::template exec<Chain>(flags, gflags);
619 struct ActivateDependencies<void>
621 template <
class Chain,
class ActiveFlags>
622 static void exec(ActiveFlags &)
625 template <
class Chain,
class ActiveFlags,
class GlobalFlags>
626 static void exec(ActiveFlags &, GlobalFlags &)
630 template <
class List>
631 struct SeparateGlobalAndRegionTags;
633 template <
class HEAD,
class TAIL>
634 struct SeparateGlobalAndRegionTags<TypeList<HEAD, TAIL> >
636 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
637 typedef TypeList<HEAD, typename Inner::RegionTags> RegionTags;
638 typedef typename Inner::GlobalTags GlobalTags;
641 template <
class HEAD,
class TAIL>
642 struct SeparateGlobalAndRegionTags<TypeList<Global<HEAD>, TAIL> >
644 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
645 typedef typename Inner::RegionTags RegionTags;
646 typedef TypeList<HEAD, typename Inner::GlobalTags> GlobalTags;
649 template <
int INDEX,
class TAIL>
650 struct SeparateGlobalAndRegionTags<TypeList<DataArg<INDEX>, TAIL> >
652 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
653 typedef TypeList<DataArg<INDEX>,
typename Inner::RegionTags> RegionTags;
654 typedef TypeList<DataArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
657 template <
int INDEX,
class TAIL>
658 struct SeparateGlobalAndRegionTags<TypeList<LabelArg<INDEX>, TAIL> >
660 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
661 typedef TypeList<LabelArg<INDEX>,
typename Inner::RegionTags> RegionTags;
662 typedef TypeList<LabelArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
665 template <
int INDEX,
class TAIL>
666 struct SeparateGlobalAndRegionTags<TypeList<WeightArg<INDEX>, TAIL> >
668 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
669 typedef TypeList<WeightArg<INDEX>,
typename Inner::RegionTags> RegionTags;
670 typedef TypeList<WeightArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
673 template <
int INDEX,
class TAIL>
674 struct SeparateGlobalAndRegionTags<TypeList<CoordArg<INDEX>, TAIL> >
676 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
677 typedef TypeList<CoordArg<INDEX>,
typename Inner::RegionTags> RegionTags;
678 typedef TypeList<CoordArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
682 struct SeparateGlobalAndRegionTags<void>
684 typedef void RegionTags;
685 typedef void GlobalTags;
694 template <
class Accumulators>
695 struct CollectAccumulatorNames;
697 template <
class HEAD,
class TAIL>
698 struct CollectAccumulatorNames<TypeList<HEAD, TAIL> >
700 template <
class BackInsertable>
701 static void exec(BackInsertable & a,
bool skipInternals=
true)
703 if(!skipInternals || HEAD::name().find(
"internal") == std::string::npos)
704 a.push_back(HEAD::name());
705 CollectAccumulatorNames<TAIL>::exec(a, skipInternals);
710 struct CollectAccumulatorNames<void>
712 template <
class BackInsertable>
713 static void exec(BackInsertable &,
bool =
true)
718 struct ApplyVisitorToTag;
720 template <
class HEAD,
class TAIL>
721 struct ApplyVisitorToTag<TypeList<HEAD, TAIL> >
723 template <
class Accu,
class Visitor>
724 static bool exec(Accu & a, std::string
const & tag, Visitor
const & v)
726 static std::string * name = VIGRA_SAFE_STATIC(name,
new std::string(
normalizeString(HEAD::name())));
729 v.template exec<HEAD>(a);
734 return ApplyVisitorToTag<TAIL>::exec(a, tag, v);
740 struct ApplyVisitorToTag<void>
742 template <
class Accu,
class Visitor>
743 static bool exec(Accu &, std::string
const &, Visitor
const &)
749 struct ActivateTag_Visitor
751 template <
class TAG,
class Accu>
752 void exec(Accu & a)
const
754 a.template activate<TAG>();
758 struct TagIsActive_Visitor
762 template <
class TAG,
class Accu>
763 void exec(Accu & a)
const
765 result = a.template isActive<TAG>();
776 struct SetHistogramBincount
778 template <
class Accu>
779 static void exec(Accu &, HistogramOptions
const &)
783 template <
template <
int>
class Histogram>
784 struct SetHistogramBincount<Histogram<0> >
786 template <
class Accu>
787 static void exec(Accu & a, HistogramOptions
const & options)
789 a.setBinCount(options.binCount);
794 struct ApplyHistogramOptions
796 template <
class Accu>
797 static void exec(Accu &, HistogramOptions
const &)
802 struct ApplyHistogramOptions<StandardQuantiles<TAG> >
804 template <
class Accu>
805 static void exec(Accu &, HistogramOptions
const &)
809 template <
class TAG,
template <
class>
class MODIFIER>
810 struct ApplyHistogramOptions<MODIFIER<TAG> >
811 :
public ApplyHistogramOptions<TAG>
815 struct ApplyHistogramOptions<IntegerHistogram<0> >
817 template <
class Accu>
818 static void exec(Accu & a, HistogramOptions
const & options)
820 SetHistogramBincount<IntegerHistogram<0> >::exec(a, options);
824 template <
int BinCount>
825 struct ApplyHistogramOptions<UserRangeHistogram<BinCount> >
827 template <
class Accu>
828 static void exec(Accu & a, HistogramOptions
const & options)
830 SetHistogramBincount<UserRangeHistogram<BinCount> >::exec(a, options);
831 if(a.scale_ == 0.0 && options.validMinMax())
832 a.setMinMax(options.minimum, options.maximum);
836 template <
int BinCount>
837 struct ApplyHistogramOptions<AutoRangeHistogram<BinCount> >
839 template <
class Accu>
840 static void exec(Accu & a, HistogramOptions
const & options)
842 SetHistogramBincount<AutoRangeHistogram<BinCount> >::exec(a, options);
843 if(a.scale_ == 0.0 && options.validMinMax())
844 a.setMinMax(options.minimum, options.maximum);
848 template <
int BinCount>
849 struct ApplyHistogramOptions<GlobalRangeHistogram<BinCount> >
851 template <
class Accu>
852 static void exec(Accu & a, HistogramOptions
const & options)
854 SetHistogramBincount<GlobalRangeHistogram<BinCount> >::exec(a, options);
857 if(options.validMinMax())
858 a.setMinMax(options.minimum, options.maximum);
860 a.setRegionAutoInit(options.local_auto_init);
877 template <
unsigned LEVEL,
class GlobalAccumulatorHandle>
878 struct AccumulatorEndImpl
880 typedef typename GlobalAccumulatorHandle::type GlobalAccumulatorType;
882 typedef AccumulatorEnd Tag;
883 typedef void value_type;
884 typedef bool result_type;
885 typedef BitArray<LEVEL> AccumulatorFlags;
887 static const unsigned int workInPass = 0;
888 static const int index = -1;
889 static const unsigned level = LEVEL;
891 AccumulatorFlags active_accumulators_;
892 mutable AccumulatorFlags is_dirty_;
893 GlobalAccumulatorHandle globalAccumulator_;
895 template <
class GlobalAccumulator>
896 void setGlobalAccumulator(GlobalAccumulator
const * a)
898 globalAccumulator_.pointer_ = a;
901 static std::string name()
903 return "AccumulatorEnd (internal)";
906 bool operator()()
const {
return false; }
907 bool get()
const {
return false; }
909 template <
unsigned,
class U>
913 template <
unsigned,
class U>
914 void pass(U
const &,
double)
918 void mergeImpl(U
const &)
922 void resize(U
const &)
926 void setCoordinateOffsetImpl(U
const &)
937 template <
class Flags>
938 static void activateImpl(Flags &)
941 template <
class Accu,
class Flags1,
class Flags2>
942 static void activateImpl(Flags1 &, Flags2 &)
945 template <
class Flags>
946 static bool isActiveImpl(Flags
const &)
951 void applyHistogramOptions(HistogramOptions
const &)
954 static unsigned int passesRequired()
959 static unsigned int passesRequired(AccumulatorFlags
const &)
966 active_accumulators_.clear();
971 void setDirtyImpl()
const
973 is_dirty_.template set<which>();
977 void setCleanImpl()
const
979 is_dirty_.template reset<which>();
983 bool isDirtyImpl()
const
985 return is_dirty_.template test<which>();
990 template <
class A,
unsigned CurrentPass,
bool allowRuntimeActivation,
unsigned WorkPass=A::workInPass>
994 static void exec(A &, T
const &)
998 static void exec(A &, T
const &,
double)
1002 template <
class A,
unsigned CurrentPass>
1003 struct DecoratorImpl<A, CurrentPass, false, CurrentPass>
1006 static void exec(A & a, T
const & t)
1012 static void exec(A & a, T
const & t,
double weight)
1014 a.update(t, weight);
1017 static typename A::result_type
get(A
const & a)
1022 static void mergeImpl(A & a, A
const & o)
1028 static void resize(A & a, T
const & t)
1033 static void applyHistogramOptions(A & a, HistogramOptions
const & options)
1035 ApplyHistogramOptions<typename A::Tag>::exec(a, options);
1038 static unsigned int passesRequired()
1040 static const unsigned int A_workInPass = A::workInPass;
1041 return std::max(A_workInPass, A::InternalBaseType::passesRequired());
1045 template <
class A,
unsigned CurrentPass>
1046 struct DecoratorImpl<A, CurrentPass, true, CurrentPass>
1050 return A::isActiveImpl(getAccumulator<AccumulatorEnd>(a).active_accumulators_);
1054 static void exec(A & a, T
const & t)
1061 static void exec(A & a, T
const & t,
double weight)
1064 a.update(t, weight);
1067 static typename A::result_type
get(A
const & a)
1071 std::string message = std::string(
"get(accumulator): attempt to access inactive statistic '") +
1072 A::Tag::name() +
"'.";
1073 vigra_precondition(
false, message);
1078 static void mergeImpl(A & a, A
const & o)
1085 static void resize(A & a, T
const & t)
1091 static void applyHistogramOptions(A & a, HistogramOptions
const & options)
1094 ApplyHistogramOptions<typename A::Tag>::exec(a, options);
1097 template <
class ActiveFlags>
1098 static unsigned int passesRequired(ActiveFlags
const & flags)
1100 static const unsigned int A_workInPass = A::workInPass;
1101 return A::isActiveImpl(flags)
1102 ? std::max(A_workInPass, A::InternalBaseType::passesRequired(flags))
1103 : A::InternalBaseType::passesRequired(flags);
1109 template <
class T,
class Shape>
1110 void reshapeImpl(T &, Shape
const &)
1113 template <
class T,
class Shape,
class Initial>
1114 void reshapeImpl(T &, Shape
const &, Initial
const & = T())
1117 template <
unsigned int N,
class T,
class Alloc,
class Shape>
1118 void reshapeImpl(MultiArray<N, T, Alloc> & a, Shape
const & s, T
const & initial = T())
1120 MultiArray<N, T, Alloc>(s, initial).swap(a);
1123 template <
class T,
class Alloc,
class Shape>
1124 void reshapeImpl(Matrix<T, Alloc> & a, Shape
const & s, T
const & initial = T())
1126 Matrix<T, Alloc>(s, initial).swap(a);
1129 template <
class T,
class U>
1130 void copyShapeImpl(T
const &, U
const &)
1133 template <
unsigned int N,
class T,
class Alloc,
class U>
1134 void copyShapeImpl(MultiArray<N, T, Alloc>
const & from, U & to)
1136 to.reshape(from.shape());
1139 template <
class T,
class Alloc,
class U>
1140 void copyShapeImpl(Matrix<T, Alloc>
const & from, U & to)
1142 to.reshape(from.shape());
1145 template <
class T,
class U>
1146 bool hasDataImpl(T
const &)
1151 template <
unsigned int N,
class T,
class Str
ide>
1152 bool hasDataImpl(MultiArrayView<N, T, Stride>
const & a)
1158 template <
unsigned int N,
class T,
class Str
ide>
1159 inline typename MultiArrayShape<N>::type
1160 shapeOf(MultiArrayView<N, T, Stride>
const & a)
1165 template <
class T,
int N>
1167 shapeOf(TinyVector<T, N>
const &)
1172 template <
class T,
class NEXT>
1173 inline CoupledHandle<T, NEXT>
const &
1174 shapeOf(CoupledHandle<T, NEXT>
const & t)
1179 #define VIGRA_SHAPE_OF(type) \
1186 VIGRA_SHAPE_OF(
unsigned char)
1187 VIGRA_SHAPE_OF(
signed char)
1188 VIGRA_SHAPE_OF(
unsigned short)
1189 VIGRA_SHAPE_OF(
short)
1190 VIGRA_SHAPE_OF(
unsigned int)
1192 VIGRA_SHAPE_OF(
unsigned long)
1193 VIGRA_SHAPE_OF(
long)
1194 VIGRA_SHAPE_OF(
unsigned long long)
1195 VIGRA_SHAPE_OF(
long long)
1196 VIGRA_SHAPE_OF(
float)
1197 VIGRA_SHAPE_OF(
double)
1198 VIGRA_SHAPE_OF(
long double)
1200 #undef VIGRA_SHAPE_OF
1209 template <
class T,
class GlobalAccumulators,
class RegionAccumulators>
1210 struct LabelDispatch
1212 typedef LabelDispatchTag Tag;
1213 typedef GlobalAccumulators GlobalAccumulatorChain;
1214 typedef RegionAccumulators RegionAccumulatorChain;
1215 typedef typename LookupTag<AccumulatorEnd, RegionAccumulatorChain>::type::AccumulatorFlags ActiveFlagsType;
1216 typedef ArrayVector<RegionAccumulatorChain> RegionAccumulatorArray;
1218 typedef LabelDispatch type;
1219 typedef LabelDispatch & reference;
1220 typedef LabelDispatch
const & const_reference;
1221 typedef GlobalAccumulatorChain InternalBaseType;
1223 typedef T
const & argument_type;
1224 typedef argument_type first_argument_type;
1225 typedef double second_argument_type;
1226 typedef RegionAccumulatorChain & result_type;
1228 static const int index = GlobalAccumulatorChain::index + 1;
1230 template <
class IndexDefinition,
class TagFound=
typename IndexDefinition::Tag>
1231 struct CoordIndexSelector
1233 static const int value = 0;
1236 template <
class IndexDefinition>
1237 struct CoordIndexSelector<IndexDefinition, CoordArgTag>
1239 static const int value = IndexDefinition::value;
1242 static const int coordIndex = CoordIndexSelector<typename LookupTag<CoordArgTag, GlobalAccumulatorChain>::type>::value;
1243 static const int coordSize = CoupledHandleCast<coordIndex, T>::type::value_type::static_size;
1244 typedef TinyVector<double, coordSize> CoordinateType;
1246 GlobalAccumulatorChain next_;
1247 RegionAccumulatorArray regions_;
1248 HistogramOptions region_histogram_options_;
1250 ActiveFlagsType active_region_accumulators_;
1251 CoordinateType coordinateOffset_;
1253 template <
class TAG>
1256 typedef typename LookupTag<TAG, type>::type TargetAccumulator;
1258 static void activate(GlobalAccumulatorChain & globals, RegionAccumulatorArray & regions,
1259 ActiveFlagsType & flags)
1261 TargetAccumulator::template activateImpl<LabelDispatch>(
1262 flags, getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
1263 for(
unsigned int k=0; k<regions.size(); ++k)
1264 getAccumulator<AccumulatorEnd>(regions[k]).active_accumulators_ = flags;
1267 static bool isActive(GlobalAccumulatorChain
const &, ActiveFlagsType
const & flags)
1269 return TargetAccumulator::isActiveImpl(flags);
1273 template <
class TAG>
1274 struct ActivateImpl<Global<TAG> >
1276 static void activate(GlobalAccumulatorChain & globals, RegionAccumulatorArray &, ActiveFlagsType &)
1278 LookupTag<TAG, GlobalAccumulatorChain>::type::activateImpl(getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
1281 static bool isActive(GlobalAccumulatorChain
const & globals, ActiveFlagsType
const &)
1283 return LookupTag<TAG, GlobalAccumulatorChain>::type::isActiveImpl(getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
1287 template <
int INDEX>
1288 struct ActivateImpl<LabelArg<INDEX> >
1290 static void activate(GlobalAccumulatorChain &, RegionAccumulatorArray &, ActiveFlagsType &)
1293 static bool isActive(GlobalAccumulatorChain
const & globals, ActiveFlagsType
const &)
1295 return getAccumulator<LabelArg<INDEX> >(globals).
isActive();
1302 region_histogram_options_(),
1304 active_region_accumulators_()
1307 LabelDispatch(LabelDispatch
const & o)
1309 regions_(o.regions_),
1310 region_histogram_options_(o.region_histogram_options_),
1311 ignore_label_(o.ignore_label_),
1312 active_region_accumulators_(o.active_region_accumulators_)
1314 for(
unsigned int k=0; k<regions_.size(); ++k)
1316 getAccumulator<AccumulatorEnd>(regions_[k]).setGlobalAccumulator(&next_);
1325 void setMaxRegionLabel(
unsigned maxlabel)
1329 unsigned int oldSize = regions_.size();
1330 regions_.resize(maxlabel + 1);
1331 for(
unsigned int k=oldSize; k<regions_.size(); ++k)
1333 getAccumulator<AccumulatorEnd>(regions_[k]).setGlobalAccumulator(&next_);
1334 getAccumulator<AccumulatorEnd>(regions_[k]).active_accumulators_ = active_region_accumulators_;
1335 regions_[k].applyHistogramOptions(region_histogram_options_);
1336 regions_[k].setCoordinateOffsetImpl(coordinateOffset_);
1347 return ignore_label_;
1350 void applyHistogramOptions(HistogramOptions
const & options)
1352 applyHistogramOptions(options, options);
1355 void applyHistogramOptions(HistogramOptions
const & regionoptions,
1356 HistogramOptions
const & globaloptions)
1358 region_histogram_options_ = regionoptions;
1359 for(
unsigned int k=0; k<regions_.size(); ++k)
1361 regions_[k].applyHistogramOptions(region_histogram_options_);
1363 next_.applyHistogramOptions(globaloptions);
1366 void setCoordinateOffsetImpl(CoordinateType
const & offset)
1368 coordinateOffset_ = offset;
1369 for(
unsigned int k=0; k<regions_.size(); ++k)
1371 regions_[k].setCoordinateOffsetImpl(coordinateOffset_);
1373 next_.setCoordinateOffsetImpl(coordinateOffset_);
1376 void setCoordinateOffsetImpl(
MultiArrayIndex k, CoordinateType
const & offset)
1379 "Accumulator::setCoordinateOffset(k, offset): region k does not exist.");
1380 regions_[k].setCoordinateOffsetImpl(offset);
1384 void resize(U
const & t)
1386 if(regions_.size() == 0)
1388 typedef HandleArgSelector<U, LabelArgTag, GlobalAccumulatorChain> LabelHandle;
1389 typedef typename LabelHandle::value_type LabelType;
1390 typedef MultiArrayView<LabelHandle::size, LabelType, StridedArrayTag> LabelArray;
1391 LabelArray labelArray(t.shape(), LabelHandle::getHandle(t).strides(),
1392 const_cast<LabelType *
>(LabelHandle::getHandle(t).ptr()));
1394 LabelType minimum, maximum;
1395 labelArray.minmax(&minimum, &maximum);
1396 setMaxRegionLabel(maximum);
1400 for(
unsigned int k=0; k<regions_.size(); ++k)
1401 regions_[k].resize(t);
1404 template <
unsigned N>
1405 void pass(T
const & t)
1407 typedef HandleArgSelector<T, LabelArgTag, GlobalAccumulatorChain> LabelHandle;
1408 if(LabelHandle::getValue(t) != ignore_label_)
1410 next_.template pass<N>(t);
1411 regions_[LabelHandle::getValue(t)].template pass<N>(t);
1415 template <
unsigned N>
1416 void pass(T
const & t,
double weight)
1418 typedef HandleArgSelector<T, LabelArgTag, GlobalAccumulatorChain> LabelHandle;
1419 if(LabelHandle::getValue(t) != ignore_label_)
1421 next_.template pass<N>(t, weight);
1422 regions_[LabelHandle::getValue(t)].template pass<N>(t, weight);
1426 static unsigned int passesRequired()
1428 return std::max(GlobalAccumulatorChain::passesRequired(), RegionAccumulatorChain::passesRequired());
1431 unsigned int passesRequiredDynamic()
const
1433 return std::max(GlobalAccumulatorChain::passesRequired(getAccumulator<AccumulatorEnd>(next_).active_accumulators_),
1434 RegionAccumulatorChain::passesRequired(active_region_accumulators_));
1441 active_region_accumulators_.clear();
1442 RegionAccumulatorArray().swap(regions_);
1448 template <
class TAG>
1451 ActivateImpl<TAG>::activate(next_, regions_, active_region_accumulators_);
1456 getAccumulator<AccumulatorEnd>(next_).active_accumulators_.set();
1457 active_region_accumulators_.set();
1458 for(
unsigned int k=0; k<regions_.size(); ++k)
1459 getAccumulator<AccumulatorEnd>(regions_[k]).active_accumulators_.set();
1462 template <
class TAG>
1465 return ActivateImpl<TAG>::isActive(next_, active_region_accumulators_);
1468 void mergeImpl(LabelDispatch
const & o)
1470 for(
unsigned int k=0; k<regions_.size(); ++k)
1471 regions_[k].mergeImpl(o.regions_[k]);
1472 next_.mergeImpl(o.next_);
1475 void mergeImpl(
unsigned i,
unsigned j)
1477 regions_[i].mergeImpl(regions_[j]);
1478 regions_[j].reset();
1479 getAccumulator<AccumulatorEnd>(regions_[j]).active_accumulators_ = active_region_accumulators_;
1482 template <
class ArrayLike>
1483 void mergeImpl(LabelDispatch
const & o, ArrayLike
const & labelMapping)
1485 MultiArrayIndex newMaxLabel = std::max<MultiArrayIndex>(maxRegionLabel(), *
argMax(labelMapping.begin(), labelMapping.end()));
1486 setMaxRegionLabel(newMaxLabel);
1487 for(
unsigned int k=0; k<labelMapping.size(); ++k)
1488 regions_[labelMapping[k]].mergeImpl(o.regions_[k]);
1489 next_.mergeImpl(o.next_);
1493 template <
class TargetTag,
class TagList>
1496 template <
class TargetTag,
class HEAD,
class TAIL>
1497 struct FindNextTag<TargetTag, TypeList<HEAD, TAIL> >
1499 typedef typename FindNextTag<TargetTag, TAIL>::type type;
1502 template <
class TargetTag,
class TAIL>
1503 struct FindNextTag<TargetTag, TypeList<TargetTag, TAIL> >
1505 typedef typename TAIL::Head type;
1508 template <
class TargetTag>
1509 struct FindNextTag<TargetTag, TypeList<TargetTag, void> >
1514 template <
class TargetTag>
1515 struct FindNextTag<TargetTag, void>
1521 template <
class TAG,
class CONFIG,
unsigned LEVEL=0>
1522 struct AccumulatorFactory
1524 typedef typename FindNextTag<TAG, typename CONFIG::TagList>::type NextTag;
1525 typedef typename AccumulatorFactory<NextTag, CONFIG, LEVEL+1>::type NextType;
1526 typedef typename CONFIG::InputType InputType;
1537 template <
class T,
class NEXT>
1538 struct ConfigureTag<CoupledHandle<T, NEXT> >
1540 typedef typename StandardizeTag<DataFromHandle<TAG> >::type WrappedTag;
1541 typedef typename IfBool<(!HasModifierPriority<WrappedTag, WeightingPriority>::value && ShouldBeWeighted<WrappedTag>::value),
1542 Weighted<WrappedTag>, WrappedTag>::type type;
1545 typedef typename ConfigureTag<InputType>::type UseTag;
1549 struct AccumulatorBase
1551 typedef AccumulatorBase ThisType;
1553 typedef NextType InternalBaseType;
1554 typedef InputType input_type;
1555 typedef input_type
const & argument_type;
1556 typedef argument_type first_argument_type;
1557 typedef double second_argument_type;
1558 typedef void result_type;
1560 static const unsigned int workInPass = 1;
1561 static const int index = InternalBaseType::index + 1;
1563 InternalBaseType next_;
1565 static std::string name()
1570 template <
class ActiveFlags>
1571 static void activateImpl(ActiveFlags & flags)
1573 flags.template set<index>();
1574 typedef typename StandardizeDependencies<Tag>::type StdDeps;
1575 acc_detail::ActivateDependencies<StdDeps>::template exec<ThisType>(flags);
1578 template <
class Accu,
class ActiveFlags,
class GlobalFlags>
1579 static void activateImpl(ActiveFlags & flags, GlobalFlags & gflags)
1581 flags.template set<index>();
1582 typedef typename StandardizeDependencies<Tag>::type StdDeps;
1583 acc_detail::ActivateDependencies<StdDeps>::template exec<Accu>(flags, gflags);
1586 template <
class ActiveFlags>
1587 static bool isActiveImpl(ActiveFlags & flags)
1589 return flags.template test<index>();
1592 void setDirty()
const
1594 next_.template setDirtyImpl<index>();
1597 template <
int INDEX>
1598 void setDirtyImpl()
const
1600 next_.template setDirtyImpl<INDEX>();
1603 void setClean()
const
1605 next_.template setCleanImpl<index>();
1608 template <
int INDEX>
1609 void setCleanImpl()
const
1611 next_.template setCleanImpl<INDEX>();
1614 bool isDirty()
const
1616 return next_.template isDirtyImpl<index>();
1619 template <
int INDEX>
1620 bool isDirtyImpl()
const
1622 return next_.template isDirtyImpl<INDEX>();
1628 template <
class Shape>
1629 void setCoordinateOffset(Shape
const &)
1632 template <
class Shape>
1633 void reshape(Shape
const &)
1640 void update(U
const &)
1644 void update(U
const &,
double)
1647 template <
class TargetTag>
1648 typename LookupDependency<TargetTag, ThisType>::result_type
1649 call_getDependency()
const
1651 return getDependency<TargetTag>(*this);
1656 typedef typename UseTag::template Impl<InputType, AccumulatorBase> AccumulatorImpl;
1663 :
public AccumulatorImpl
1665 typedef Accumulator type;
1666 typedef Accumulator & reference;
1667 typedef Accumulator
const & const_reference;
1668 typedef AccumulatorImpl A;
1670 static const unsigned int workInPass = A::workInPass;
1671 static const bool allowRuntimeActivation = CONFIG::allowRuntimeActivation;
1674 void resize(T
const & t)
1676 this->next_.resize(t);
1677 DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::resize(*
this, t);
1682 this->next_.reset();
1686 typename A::result_type
get()
const
1691 template <
unsigned N,
class T>
1692 void pass(T
const & t)
1694 this->next_.template pass<N>(t);
1695 DecoratorImpl<Accumulator, N, allowRuntimeActivation>::exec(*
this, t);
1698 template <
unsigned N,
class T>
1699 void pass(T
const & t,
double weight)
1701 this->next_.template pass<N>(t, weight);
1702 DecoratorImpl<Accumulator, N, allowRuntimeActivation>::exec(*
this, t, weight);
1705 void mergeImpl(Accumulator
const & o)
1707 DecoratorImpl<Accumulator, Accumulator::workInPass, allowRuntimeActivation>::mergeImpl(*
this, o);
1708 this->next_.mergeImpl(o.next_);
1711 void applyHistogramOptions(HistogramOptions
const & options)
1713 DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::applyHistogramOptions(*
this, options);
1714 this->next_.applyHistogramOptions(options);
1717 template <
class SHAPE>
1718 void setCoordinateOffsetImpl(SHAPE
const & offset)
1720 this->setCoordinateOffset(offset);
1721 this->next_.setCoordinateOffsetImpl(offset);
1724 static unsigned int passesRequired()
1726 return DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::passesRequired();
1729 template <
class ActiveFlags>
1730 static unsigned int passesRequired(ActiveFlags
const & flags)
1732 return DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::passesRequired(flags);
1736 typedef Accumulator type;
1739 template <
class CONFIG,
unsigned LEVEL>
1740 struct AccumulatorFactory<void, CONFIG, LEVEL>
1742 typedef AccumulatorEndImpl<LEVEL, typename CONFIG::GlobalAccumulatorHandle> type;
1745 struct InvalidGlobalAccumulatorHandle
1747 typedef Error__Global_statistics_are_only_defined_for_AccumulatorChainArray type;
1749 InvalidGlobalAccumulatorHandle()
1753 type
const * pointer_;
1759 template <
class T,
class Selected,
bool dynamic=false,
class GlobalHandle=Inval
idGlobalAccumulatorHandle>
1760 struct ConfigureAccumulatorChain
1762 :
public ConfigureAccumulatorChain<T, typename AddDependencies<typename Selected::type>::type, dynamic>
1766 template <
class T,
class HEAD,
class TAIL,
bool dynamic,
class GlobalHandle>
1767 struct ConfigureAccumulatorChain<T, TypeList<HEAD, TAIL>, dynamic, GlobalHandle>
1769 typedef TypeList<HEAD, TAIL> TagList;
1770 typedef T InputType;
1771 static const bool allowRuntimeActivation = dynamic;
1772 typedef GlobalHandle GlobalAccumulatorHandle;
1774 typedef typename AccumulatorFactory<HEAD, ConfigureAccumulatorChain>::type type;
1777 template <
class T,
class Selected,
bool dynamic=false>
1778 struct ConfigureAccumulatorChainArray
1780 :
public ConfigureAccumulatorChainArray<T, typename AddDependencies<typename Selected::type>::type, dynamic>
1784 template <
class T,
class HEAD,
class TAIL,
bool dynamic>
1785 struct ConfigureAccumulatorChainArray<T, TypeList<HEAD, TAIL>, dynamic>
1787 typedef TypeList<HEAD, TAIL> TagList;
1788 typedef SeparateGlobalAndRegionTags<TagList> TagSeparator;
1789 typedef typename TagSeparator::GlobalTags GlobalTags;
1790 typedef typename TagSeparator::RegionTags RegionTags;
1791 typedef typename ConfigureAccumulatorChain<T, GlobalTags, dynamic>::type GlobalAccumulatorChain;
1793 struct GlobalAccumulatorHandle
1795 typedef GlobalAccumulatorChain type;
1797 GlobalAccumulatorHandle()
1801 type
const * pointer_;
1804 typedef typename ConfigureAccumulatorChain<T, RegionTags, dynamic, GlobalAccumulatorHandle>::type RegionAccumulatorChain;
1806 typedef LabelDispatch<T, GlobalAccumulatorChain, RegionAccumulatorChain> type;
1818 template <
class T,
class NEXT>
1819 class AccumulatorChainImpl
1822 typedef NEXT InternalBaseType;
1823 typedef AccumulatorBegin Tag;
1824 typedef typename InternalBaseType::argument_type argument_type;
1825 typedef typename InternalBaseType::first_argument_type first_argument_type;
1826 typedef typename InternalBaseType::second_argument_type second_argument_type;
1827 typedef void value_type;
1828 typedef typename InternalBaseType::result_type result_type;
1830 static const int staticSize = InternalBaseType::index;
1832 InternalBaseType next_;
1836 unsigned int current_pass_;
1838 AccumulatorChainImpl()
1844 void setHistogramOptions(HistogramOptions
const & options)
1846 next_.applyHistogramOptions(options);
1852 void setHistogramOptions(HistogramOptions
const & regionoptions, HistogramOptions
const & globaloptions)
1854 next_.applyHistogramOptions(regionoptions, globaloptions);
1863 template <
class SHAPE>
1864 void setCoordinateOffset(SHAPE
const & offset)
1866 next_.setCoordinateOffsetImpl(offset);
1871 void reset(
unsigned int reset_to_pass = 0)
1873 current_pass_ = reset_to_pass;
1874 if(reset_to_pass == 0)
1878 template <
unsigned N>
1879 void update(T
const & t)
1881 if(current_pass_ == N)
1883 next_.template pass<N>(t);
1885 else if(current_pass_ < N)
1889 next_.resize(acc_detail::shapeOf(t));
1890 next_.template pass<N>(t);
1894 std::string message(
"AccumulatorChain::update(): cannot return to pass ");
1895 message << N <<
" after working on pass " << current_pass_ <<
".";
1896 vigra_precondition(
false, message);
1900 template <
unsigned N>
1901 void update(T
const & t,
double weight)
1903 if(current_pass_ == N)
1905 next_.template pass<N>(t, weight);
1907 else if(current_pass_ < N)
1911 next_.resize(acc_detail::shapeOf(t));
1912 next_.template pass<N>(t, weight);
1916 std::string message(
"AccumulatorChain::update(): cannot return to pass ");
1917 message << N <<
" after working on pass " << current_pass_ <<
".";
1918 vigra_precondition(
false, message);
1924 void operator+=(AccumulatorChainImpl
const & o)
1931 void merge(AccumulatorChainImpl
const & o)
1933 next_.mergeImpl(o.next_);
1936 result_type operator()()
const
1941 void operator()(T
const & t)
1946 void operator()(T
const & t,
double weight)
1948 update<1>(t, weight);
1951 void updatePass2(T
const & t)
1956 void updatePass2(T
const & t,
double weight)
1958 update<2>(t, weight);
1963 void updatePassN(T
const & t,
unsigned int N)
1967 case 1: update<1>(t);
break;
1968 case 2: update<2>(t);
break;
1969 case 3: update<3>(t);
break;
1970 case 4: update<4>(t);
break;
1971 case 5: update<5>(t);
break;
1973 vigra_precondition(
false,
1974 "AccumulatorChain::updatePassN(): 0 < N < 6 required.");
1980 void updatePassN(T
const & t,
double weight,
unsigned int N)
1984 case 1: update<1>(t, weight);
break;
1985 case 2: update<2>(t, weight);
break;
1986 case 3: update<3>(t, weight);
break;
1987 case 4: update<4>(t, weight);
break;
1988 case 5: update<5>(t, weight);
break;
1990 vigra_precondition(
false,
1991 "AccumulatorChain::updatePassN(): 0 < N < 6 required.");
1997 unsigned int passesRequired()
const
1999 return InternalBaseType::passesRequired();
2035 template <
class T,
class Selected,
bool dynamic=false>
2038 :
public AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChain<T, Selected, dynamic>::type>
2043 typedef typename acc_detail::ConfigureAccumulatorChain<T, Selected, dynamic>::TagList AccumulatorTags;
2047 template <
class U,
int N>
2050 vigra_precondition(this->current_pass_ == 0,
2051 "AccumulatorChain::reshape(): cannot reshape after seeing data. Call AccumulatorChain::reset() first.");
2052 this->next_.resize(s);
2053 this->current_pass_ = 1;
2065 #ifdef DOXYGEN // hide AccumulatorChainImpl from documentation
2077 template <
class SHAPE>
2081 void reset(
unsigned int reset_to_pass = 0);
2084 void operator+=(AccumulatorChainImpl
const & o);
2088 void merge(AccumulatorChainImpl
const & o);
2096 void updatePassN(T
const & t,
double weight,
unsigned int N);
2108 acc_detail::CollectAccumulatorNames<AccumulatorTags>::exec(n);
2114 template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected,
bool dynamic>
2115 class AccumulatorChain<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected, dynamic>
2116 :
public AccumulatorChain<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected, dynamic>
2150 template <
class T,
class Selected>
2156 typedef typename DynamicAccumulatorChain::AccumulatorTags AccumulatorTags;
2162 vigra_precondition(activateImpl(tag),
2163 std::string(
"DynamicAccumulatorChain::activate(): Tag '") + tag +
"' not found.");
2168 template <
class TAG>
2171 LookupTag<TAG, DynamicAccumulatorChain>::type::activateImpl(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
2178 getAccumulator<AccumulatorEnd>(*this).active_accumulators_.set();
2184 acc_detail::TagIsActive_Visitor v;
2185 vigra_precondition(isActiveImpl(tag, v),
2186 std::string(
"DynamicAccumulatorChain::isActive(): Tag '") + tag +
"' not found.");
2192 template <
class TAG>
2195 return LookupTag<TAG, DynamicAccumulatorChain>::type::isActiveImpl(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
2213 return InternalBaseType::passesRequired(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
2218 bool activateImpl(std::string tag)
2220 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(*
this,
2224 bool isActiveImpl(std::string tag, acc_detail::TagIsActive_Visitor & v)
const
2226 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(*
this,
normalizeString(tag), v);
2230 template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected>
2231 class DynamicAccumulatorChain<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected>
2232 :
public DynamicAccumulatorChain<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected>
2261 template<
unsigned int N,
class T,
class SELECT>
2267 typedef typename CoupledHandleType<N, T>::type HandleType;
2268 typedef typename HandleType::base_type CoordHandle;
2269 typedef typename CoordHandle::value_type CoordType;
2270 typedef SELECT SelectType;
2275 handle_((T
const *)0, CoordType(), CoordHandle(CoordType()))
2278 void updatePassN(
const T & val,
const CoordType & coord,
unsigned int p)
2280 cast<0>(handle_).internal_reset(coord);
2281 cast<1>(handle_).internal_reset(&val);
2311 template<
unsigned int N,
class SELECT>
2317 typedef typename CoupledHandleType<N>::type HandleType;
2318 typedef typename HandleType::value_type CoordType;
2320 typedef SELECT SelectType;
2325 handle_(CoordType())
2328 template<
class IGNORED_DATA>
2330 updatePassN(
const IGNORED_DATA &,
2331 const CoordType & coord,
2334 this->updatePassN(coord, p);
2338 void updatePassN(
const CoordType & coord,
unsigned int p)
2340 handle_.internal_reset(coord);
2372 template <
class T,
class Selected,
bool dynamic=false>
2375 :
public AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic>::type>
2379 typedef AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic>::type> base_type;
2380 typedef typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic> Creator;
2381 typedef typename Creator::TagList AccumulatorTags;
2382 typedef typename Creator::GlobalTags GlobalTags;
2383 typedef typename Creator::RegionTags RegionTags;
2389 this->next_.ignoreLabel(l);
2396 return this->next_.ignoredLabel();
2403 this->next_.setMaxRegionLabel(label);
2410 return this->next_.maxRegionLabel();
2417 return this->next_.regions_.size();
2432 "AccumulatorChainArray::merge(): region labels out of range.");
2433 this->next_.mergeImpl(i, j);
2443 "AccumulatorChainArray::merge(): maxRegionLabel must be equal.");
2444 this->next_.mergeImpl(o.next_);
2449 template <
class ArrayLike>
2452 vigra_precondition(labelMapping.size() == o.
regionCount(),
2453 "AccumulatorChainArray::merge(): labelMapping.size() must match regionCount() of RHS.");
2454 this->next_.mergeImpl(o.next_, labelMapping);
2465 using base_type::setCoordinateOffset;
2473 template <
class SHAPE>
2476 this->next_.setCoordinateOffsetImpl(k, offset);
2479 #ifdef DOXYGEN // hide AccumulatorChainImpl from documentation
2490 template <
class SHAPE>
2494 void reset(
unsigned int reset_to_pass = 0);
2497 void operator+=(AccumulatorChainImpl
const & o);
2503 void updatePassN(T
const & t,
double weight,
unsigned int N);
2511 acc_detail::CollectAccumulatorNames<AccumulatorTags>::exec(n);
2517 template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected,
bool dynamic>
2518 class AccumulatorChainArray<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected, dynamic>
2519 :
public AccumulatorChainArray<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected, dynamic>
2543 template <
class T,
class Selected>
2548 typedef typename DynamicAccumulatorChainArray::AccumulatorTags AccumulatorTags;
2553 vigra_precondition(activateImpl(tag),
2554 std::string(
"DynamicAccumulatorChainArray::activate(): Tag '") + tag +
"' not found.");
2558 template <
class TAG>
2561 this->next_.template activate<TAG>();
2567 this->next_.activateAll();
2574 acc_detail::TagIsActive_Visitor v;
2575 vigra_precondition(isActiveImpl(tag, v),
2576 std::string(
"DynamicAccumulatorChainArray::isActive(): Tag '") + tag +
"' not found.");
2582 template <
class TAG>
2585 return this->next_.template isActive<TAG>();
2601 return this->next_.passesRequiredDynamic();
2606 bool activateImpl(std::string tag)
2608 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(this->next_,
2612 bool isActiveImpl(std::string tag, acc_detail::TagIsActive_Visitor & v)
const
2614 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(this->next_,
normalizeString(tag), v);
2618 template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected>
2619 class DynamicAccumulatorChainArray<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected>
2620 :
public DynamicAccumulatorChainArray<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected>
2629 template <
class TAG>
2630 struct Error__Attempt_to_access_inactive_statistic;
2632 namespace acc_detail {
2637 template <
class TAG,
class A,
class FromTag=
typename A::Tag>
2638 struct LookupTagImpl
2640 :
public LookupTagImpl<TAG, typename A::InternalBaseType>
2645 template <
class TAG,
class A,
class FromTag>
2646 struct LookupTagImpl<TAG, A const, FromTag>
2647 :
public LookupTagImpl<TAG, A>
2649 typedef typename LookupTagImpl<TAG, A>::type
const & reference;
2650 typedef typename LookupTagImpl<TAG, A>::type
const * pointer;
2654 template <
class TAG,
class A>
2655 struct LookupTagImpl<TAG, A, TAG>
2659 typedef A & reference;
2660 typedef A * pointer;
2661 typedef typename A::value_type value_type;
2662 typedef typename A::result_type result_type;
2666 template <
class TAG,
class A>
2667 struct LookupTagImpl<TAG, A const, TAG>
2668 :
public LookupTagImpl<TAG, A, TAG>
2670 typedef typename LookupTagImpl<TAG, A, TAG>::type
const & reference;
2671 typedef typename LookupTagImpl<TAG, A, TAG>::type
const * pointer;
2676 template <
class TAG,
class A>
2677 struct LookupTagImpl<TAG, A, AccumulatorEnd>
2681 typedef A & reference;
2682 typedef A * pointer;
2683 typedef Error__Attempt_to_access_inactive_statistic<TAG> value_type;
2684 typedef Error__Attempt_to_access_inactive_statistic<TAG> result_type;
2689 struct LookupTagImpl<AccumulatorEnd, A, AccumulatorEnd>
2691 typedef AccumulatorEnd Tag;
2693 typedef A & reference;
2694 typedef A * pointer;
2695 typedef void value_type;
2696 typedef void result_type;
2702 template <
class TAG,
class A>
2703 struct LookupTagImpl<Global<TAG>, A, AccumulatorEnd>
2704 :
public LookupTagImpl<TAG, typename A::GlobalAccumulatorType>
2706 typedef Global<TAG> Tag;
2711 template <
class TAG,
class A>
2712 struct LookupTagImpl<TAG, A, LabelDispatchTag>
2713 :
public LookupTagImpl<TAG, typename A::RegionAccumulatorChain>
2719 template <
class TAG,
class A>
2720 struct LookupTagImpl<Global<TAG>, A, LabelDispatchTag>
2721 :
public LookupTagImpl<TAG, typename A::GlobalAccumulatorChain>
2723 typedef Global<TAG> Tag;
2728 struct LookupTagImpl<LabelDispatchTag, A, LabelDispatchTag>
2730 typedef LabelDispatchTag Tag;
2732 typedef A & reference;
2733 typedef A * pointer;
2734 typedef void value_type;
2735 typedef void result_type;
2741 template <
class Tag,
class A>
2743 :
public acc_detail::LookupTagImpl<typename StandardizeTag<Tag>::type, A>
2750 template <
class Tag,
class A,
class TargetTag>
2751 struct LookupDependency
2752 :
public acc_detail::LookupTagImpl<
2753 typename TransferModifiers<TargetTag, typename StandardizeTag<Tag>::type>::type, A>
2757 namespace acc_detail {
2761 template <
class Tag,
class FromTag,
class reference>
2765 static reference exec(A & a)
2767 return CastImpl<Tag, typename A::InternalBaseType::Tag, reference>::exec(a.next_);
2773 return CastImpl<Tag, typename A::InternalBaseType::Tag, reference>::exec(a.next_, label);
2777 template <
class Tag,
class reference>
2778 struct CastImpl<Tag, Tag, reference>
2781 static reference exec(A & a)
2783 return const_cast<reference
>(a);
2789 vigra_precondition(
false,
2790 "getAccumulator(): region accumulators can only be queried for AccumulatorChainArray.");
2795 template <
class Tag,
class reference>
2796 struct CastImpl<Tag, AccumulatorEnd, reference>
2799 static reference exec(A & a)
2811 template <
class Tag,
class reference>
2812 struct CastImpl<Global<Tag>, AccumulatorEnd, reference>
2815 static reference exec(A & a)
2817 return CastImpl<Tag, typename A::GlobalAccumulatorType::Tag, reference>::exec(*a.globalAccumulator_.pointer_);
2821 template <
class reference>
2822 struct CastImpl<AccumulatorEnd, AccumulatorEnd, reference>
2825 static reference exec(A & a)
2837 template <
class Tag,
class reference>
2838 struct CastImpl<Tag, LabelDispatchTag, reference>
2841 static reference exec(A & a)
2843 vigra_precondition(
false,
2844 "getAccumulator(): a region label is required when a region accumulator is queried.");
2845 return CastImpl<Tag, typename A::RegionAccumulatorChain::Tag, reference>::exec(a.regions_[0]);
2851 return CastImpl<Tag, typename A::RegionAccumulatorChain::Tag, reference>::exec(a.regions_[label]);
2855 template <
class Tag,
class reference>
2856 struct CastImpl<Global<Tag>, LabelDispatchTag, reference>
2859 static reference exec(A & a)
2861 return CastImpl<Tag, typename A::GlobalAccumulatorChain::Tag, reference>::exec(a.next_);
2865 template <
class reference>
2866 struct CastImpl<LabelDispatchTag, LabelDispatchTag, reference>
2869 static reference exec(A & a)
2902 template <
class TAG,
class A>
2903 inline typename LookupTag<TAG, A>::reference
2906 typedef typename LookupTag<TAG, A>::Tag StandardizedTag;
2907 typedef typename LookupTag<TAG, A>::reference reference;
2908 return acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a);
2914 template <
class TAG,
class A>
2915 inline typename LookupTag<TAG, A>::reference
2918 typedef typename LookupTag<TAG, A>::Tag StandardizedTag;
2919 typedef typename LookupTag<TAG, A>::reference reference;
2920 return acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a, label);
2934 template <
class TAG,
class A>
2935 inline typename LookupTag<TAG, A>::result_type
2938 return getAccumulator<TAG>(a).
get();
2962 template <
class TAG,
class A>
2963 inline typename LookupTag<TAG, A>::result_type
2966 return getAccumulator<TAG>(a, label).
get();
2973 template <
class TAG,
class A>
2974 inline typename LookupDependency<TAG, A>::result_type
2975 getDependency(A
const & a)
2977 typedef typename LookupDependency<TAG, A>::Tag StandardizedTag;
2978 typedef typename LookupDependency<TAG, A>::reference reference;
2979 return acc_detail::CastImpl<StandardizedTag, typename A::Tag, reference>::exec(a)();
2986 template <
class Tag,
class A>
2990 a.template activate<Tag>();
2997 template <
class Tag,
class A>
3001 return a.template isActive<Tag>();
3079 template <
class ITERATOR,
class ACCUMULATOR>
3082 for(
unsigned int k=1; k <= a.passesRequired(); ++k)
3083 for(ITERATOR i=start; i < end; ++i)
3084 a.updatePassN(*i, k);
3087 template <
unsigned int N,
class T1,
class S1,
3092 typedef typename CoupledIteratorType<N, T1>::type Iterator;
3093 Iterator start = createCoupledIterator(a1),
3094 end = start.getEndIterator();
3098 template <
unsigned int N,
class T1,
class S1,
3102 MultiArrayView<N, T2, S2>
const & a2,
3105 typedef typename CoupledIteratorType<N, T1, T2>::type Iterator;
3106 Iterator start = createCoupledIterator(a1, a2),
3107 end = start.getEndIterator();
3111 template <
unsigned int N,
class T1,
class S1,
3116 MultiArrayView<N, T2, S2>
const & a2,
3117 MultiArrayView<N, T3, S3>
const & a3,
3120 typedef typename CoupledIteratorType<N, T1, T2, T3>::type Iterator;
3121 Iterator start = createCoupledIterator(a1, a2, a3),
3122 end = start.getEndIterator();
3126 template <
unsigned int N,
class T1,
class S1,
3132 MultiArrayView<N, T2, S2>
const & a2,
3133 MultiArrayView<N, T3, S3>
const & a3,
3134 MultiArrayView<N, T4, S4>
const & a4,
3137 typedef typename CoupledIteratorType<N, T1, T2, T3, T4>::type Iterator;
3138 Iterator start = createCoupledIterator(a1, a2, a3, a4),
3139 end = start.getEndIterator();
3143 template <
unsigned int N,
class T1,
class S1,
3150 MultiArrayView<N, T2, S2>
const & a2,
3151 MultiArrayView<N, T3, S3>
const & a3,
3152 MultiArrayView<N, T4, S4>
const & a4,
3153 MultiArrayView<N, T5, S5>
const & a5,
3156 typedef typename CoupledIteratorType<N, T1, T2, T3, T4, T5>::type Iterator;
3157 Iterator start = createCoupledIterator(a1, a2, a3, a4, a5),
3158 end = start.getEndIterator();
3169 struct AccumulatorResultTraits
3172 typedef T element_type;
3173 typedef double element_promote_type;
3174 typedef T MinmaxType;
3175 typedef element_promote_type SumType;
3176 typedef element_promote_type FlatCovarianceType;
3177 typedef element_promote_type CovarianceType;
3180 template <
class T,
int N>
3181 struct AccumulatorResultTraits<TinyVector<T, N> >
3183 typedef TinyVector<T, N> type;
3184 typedef T element_type;
3185 typedef double element_promote_type;
3186 typedef TinyVector<T, N> MinmaxType;
3187 typedef TinyVector<element_promote_type, N> SumType;
3188 typedef TinyVector<element_promote_type, N*(N+1)/2> FlatCovarianceType;
3189 typedef Matrix<element_promote_type> CovarianceType;
3193 template <
class T,
unsigned int RED_IDX,
unsigned int GREEN_IDX,
unsigned int BLUE_IDX>
3194 struct AccumulatorResultTraits<RGBValue<T, RED_IDX, GREEN_IDX, BLUE_IDX> >
3196 typedef RGBValue<T> type;
3197 typedef T element_type;
3198 typedef double element_promote_type;
3199 typedef RGBValue<T> MinmaxType;
3200 typedef RGBValue<element_promote_type> SumType;
3201 typedef TinyVector<element_promote_type, 3*(3+1)/2> FlatCovarianceType;
3202 typedef Matrix<element_promote_type> CovarianceType;
3207 template <
unsigned int N,
class T,
class Str
ide>
3208 struct AccumulatorResultTraits<MultiArrayView<N, T, Stride> >
3210 typedef MultiArrayView<N, T, Stride> type;
3211 typedef T element_type;
3212 typedef double element_promote_type;
3213 typedef MultiArray<N, T> MinmaxType;
3214 typedef MultiArray<N, element_promote_type> SumType;
3215 typedef MultiArray<1, element_promote_type> FlatCovarianceType;
3216 typedef Matrix<element_promote_type> CovarianceType;
3219 template <
unsigned int N,
class T,
class Alloc>
3220 struct AccumulatorResultTraits<MultiArray<N, T, Alloc> >
3222 typedef MultiArrayView<N, T, Alloc> type;
3223 typedef T element_type;
3224 typedef double element_promote_type;
3225 typedef MultiArray<N, T> MinmaxType;
3226 typedef MultiArray<N, element_promote_type> SumType;
3227 typedef MultiArray<1, element_promote_type> FlatCovarianceType;
3228 typedef Matrix<element_promote_type> CovarianceType;
3241 template <
class TAG>
3245 typedef typename StandardizeTag<TAG>::type TargetTag;
3246 typedef typename TargetTag::Dependencies Dependencies;
3248 static std::string name()
3250 return std::string(
"Global<") + TargetTag::name() +
" >";
3260 template <
int INDEX>
3264 typedef Select<> Dependencies;
3266 static std::string name()
3268 return std::string(
"DataArg<") +
asString(INDEX) +
"> (internal)";
3273 template <
class T,
class BASE>
3277 typedef DataArgTag Tag;
3278 typedef void value_type;
3279 typedef void result_type;
3281 static const int value = INDEX;
3282 static const unsigned int workInPass = 0;
3286 namespace acc_detail {
3288 template <
class T,
int DEFAULT,
class TAG,
class IndexDefinition,
3289 class TagFound=
typename IndexDefinition::Tag>
3290 struct HandleArgSelectorImpl
3292 static const int value = DEFAULT;
3293 typedef typename CoupledHandleCast<value, T>::type type;
3294 typedef typename CoupledHandleCast<value, T>::value_type value_type;
3295 static const int size = type::dimensions;
3297 template <
class U,
class NEXT>
3298 static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type
const &
3299 getHandle(CoupledHandle<U, NEXT>
const & t)
3301 return vigra::cast<value>(t);
3304 template <
class U,
class NEXT>
3305 static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type::const_reference
3306 getValue(CoupledHandle<U, NEXT>
const & t)
3308 return vigra::get<value>(t);
3312 template <
class T,
int DEFAULT,
class TAG,
class IndexDefinition>
3313 struct HandleArgSelectorImpl<T, DEFAULT, TAG, IndexDefinition, TAG>
3315 static const int value = IndexDefinition::value;
3316 typedef typename CoupledHandleCast<value, T>::type type;
3317 typedef typename CoupledHandleCast<value, T>::value_type value_type;
3318 static const int size = type::dimensions;
3320 template <
class U,
class NEXT>
3321 static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type
const &
3322 getHandle(CoupledHandle<U, NEXT>
const & t)
3324 return vigra::cast<value>(t);
3327 template <
class U,
class NEXT>
3328 static typename CoupledHandleCast<value, CoupledHandle<U, NEXT> >::type::const_reference
3329 getValue(CoupledHandle<U, NEXT>
const & t)
3331 return vigra::get<value>(t);
3337 template <
class T,
class CHAIN>
3338 struct HandleArgSelector<T, LabelArgTag, CHAIN>
3339 :
public acc_detail::HandleArgSelectorImpl<T, 2, LabelArgTag,
3340 typename LookupTag<LabelArgTag, CHAIN>::type>
3343 template <
class T,
class CHAIN>
3344 struct HandleArgSelector<T, DataArgTag, CHAIN>
3345 :
public acc_detail::HandleArgSelectorImpl<T, 1, DataArgTag,
3346 typename LookupTag<DataArgTag, CHAIN>::type>
3349 template <
class T,
class CHAIN>
3350 struct HandleArgSelector<T, CoordArgTag, CHAIN>
3351 :
public acc_detail::HandleArgSelectorImpl<T, 0, CoordArgTag,
3352 typename LookupTag<CoordArgTag, CHAIN>::type>
3354 typedef acc_detail::HandleArgSelectorImpl<T, 0, CoordArgTag,
3355 typename LookupTag<CoordArgTag, CHAIN>::type> base_type;
3356 typedef TinyVector<double, base_type::size> value_type;
3360 template <
class TAG>
3361 class DataFromHandle
3364 typedef typename StandardizeTag<TAG>::type TargetTag;
3365 typedef typename TargetTag::Dependencies Dependencies;
3367 static std::string name()
3369 return std::string(
"DataFromHandle<") + TargetTag::name() +
" > (internal)";
3374 template <
class T,
class BASE>
3376 :
public TargetTag::template Impl<typename HandleArgSelector<T, DataArgTag, BASE>::value_type, BASE>
3378 typedef HandleArgSelector<T, DataArgTag, BASE> DataHandle;
3379 typedef typename DataHandle::value_type input_type;
3380 typedef input_type
const & argument_type;
3381 typedef argument_type first_argument_type;
3383 typedef typename TargetTag::template Impl<input_type, BASE> ImplType;
3385 using ImplType::reshape;
3387 template <
class U,
class NEXT>
3388 void reshape(CoupledHandle<U, NEXT>
const & t)
3390 ImplType::reshape(acc_detail::shapeOf(DataHandle::getValue(t)));
3393 template <
class U,
class NEXT>
3394 void update(CoupledHandle<U, NEXT>
const & t)
3396 ImplType::update(DataHandle::getValue(t));
3399 template <
class U,
class NEXT>
3400 void update(CoupledHandle<U, NEXT>
const & t,
double weight)
3402 ImplType::update(DataHandle::getValue(t), weight);
3411 template <
class TAG>
3415 typedef typename StandardizeTag<TAG>::type TargetTag;
3416 typedef typename TargetTag::Dependencies Dependencies;
3418 static std::string name()
3420 return std::string(
"Coord<") + TargetTag::name() +
" >";
3425 template <
class T,
class BASE>
3427 :
public TargetTag::template Impl<typename HandleArgSelector<T, CoordArgTag, BASE>::value_type, BASE>
3429 typedef HandleArgSelector<T, CoordArgTag, BASE> CoordHandle;
3430 typedef typename CoordHandle::value_type input_type;
3431 typedef input_type
const & argument_type;
3432 typedef argument_type first_argument_type;
3434 typedef typename TargetTag::template Impl<input_type, BASE> ImplType;
3442 void setCoordinateOffset(input_type
const & offset)
3447 using ImplType::reshape;
3449 template <
class U,
class NEXT>
3450 void reshape(CoupledHandle<U, NEXT>
const & t)
3452 ImplType::reshape(acc_detail::shapeOf(CoordHandle::getValue(t)));
3455 template <
class U,
class NEXT>
3456 void update(CoupledHandle<U, NEXT>
const & t)
3458 ImplType::update(CoordHandle::getValue(t)+offset_);
3461 template <
class U,
class NEXT>
3462 void update(CoupledHandle<U, NEXT>
const & t,
double weight)
3464 ImplType::update(CoordHandle::getValue(t)+offset_, weight);
3473 template <
int INDEX>
3477 typedef Select<> Dependencies;
3479 static std::string name()
3481 return std::string(
"WeightArg<") +
asString(INDEX) +
"> (internal)";
3486 template <
class T,
class BASE>
3490 typedef WeightArgTag Tag;
3491 typedef void value_type;
3492 typedef void result_type;
3494 static const int value = INDEX;
3495 static const unsigned int workInPass = 0;
3501 template <
class TAG>
3505 typedef typename StandardizeTag<TAG>::type TargetTag;
3506 typedef typename TargetTag::Dependencies Dependencies;
3508 static std::string name()
3510 return std::string(
"Weighted<") + TargetTag::name() +
" >";
3515 template <
class IndexDefinition,
class TagFound=
typename IndexDefinition::Tag>
3516 struct WeightIndexSelector
3518 template <
class U,
class NEXT>
3519 static double exec(CoupledHandle<U, NEXT>
const & t)
3525 template <
class IndexDefinition>
3526 struct WeightIndexSelector<IndexDefinition, WeightArgTag>
3528 template <
class U,
class NEXT>
3529 static double exec(CoupledHandle<U, NEXT>
const & t)
3531 return (
double)get<IndexDefinition::value>(t);
3535 template <
class T,
class BASE>
3537 :
public TargetTag::template Impl<T, BASE>
3539 typedef typename TargetTag::template Impl<T, BASE> ImplType;
3541 typedef typename LookupTag<WeightArgTag, BASE>::type FindWeightIndex;
3543 template <
class U,
class NEXT>
3544 void update(CoupledHandle<U, NEXT>
const & t)
3546 ImplType::update(t, WeightIndexSelector<FindWeightIndex>::exec(t));
3555 typedef Select<Mean> Dependencies;
3557 static std::string name()
3559 return "Centralize (internal)";
3564 template <
class U,
class BASE>
3568 static const unsigned int workInPass = 2;
3570 typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
3571 typedef typename AccumulatorResultTraits<U>::SumType value_type;
3572 typedef value_type
const & result_type;
3574 mutable value_type value_;
3582 value_ = element_type();
3585 template <
class Shape>
3586 void reshape(Shape
const & s)
3588 acc_detail::reshapeImpl(value_, s);
3591 void update(U
const & t)
const
3593 using namespace vigra::multi_math;
3594 value_ = t - getDependency<Mean>(*this);
3597 void update(U
const & t,
double)
const
3602 result_type operator()(U
const & t)
const
3608 result_type operator()()
const
3619 template <
class TAG>
3623 typedef typename StandardizeTag<TAG>::type TargetTag;
3624 typedef Select<Centralize, typename TargetTag::Dependencies> Dependencies;
3626 static std::string name()
3628 return std::string(
"Central<") + TargetTag::name() +
" >";
3633 template <
class U,
class BASE>
3635 :
public TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE>
3637 typedef typename TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE> ImplType;
3639 static const unsigned int workInPass = 2;
3643 vigra_precondition(
false,
3644 "Central<...>::operator+=(): not supported.");
3648 void update(T
const &)
3650 ImplType::update(getDependency<Centralize>(*
this));
3654 void update(T
const &,
double weight)
3656 ImplType::update(getDependency<Centralize>(*
this), weight);
3699 class PrincipalProjection
3702 typedef Select<Centralize, Principal<CoordinateSystem> > Dependencies;
3704 static std::string name()
3706 return "PrincipalProjection (internal)";
3711 template <
class U,
class BASE>
3715 static const unsigned int workInPass = 2;
3717 typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
3718 typedef typename AccumulatorResultTraits<U>::SumType value_type;
3719 typedef value_type
const & result_type;
3721 mutable value_type value_;
3729 value_ = element_type();
3732 template <
class Shape>
3733 void reshape(Shape
const & s)
3735 acc_detail::reshapeImpl(value_, s);
3738 void update(U
const & t)
const
3740 for(
unsigned int k=0; k<t.size(); ++k)
3742 value_[k] = getDependency<Principal<CoordinateSystem> >(*this)(0, k)*getDependency<Centralize>(*
this)[0];
3743 for(
unsigned int d=1; d<t.size(); ++d)
3744 value_[k] += getDependency<Principal<CoordinateSystem> >(*
this)(d, k)*getDependency<Centralize>(*
this)[d];
3748 void update(U
const & t,
double)
const
3753 result_type operator()(U
const & t)
const
3755 getAccumulator<Centralize>(*this).update(t);
3760 result_type operator()()
const
3771 template <
class TAG>
3775 typedef typename StandardizeTag<TAG>::type TargetTag;
3776 typedef Select<PrincipalProjection, typename TargetTag::Dependencies> Dependencies;
3778 static std::string name()
3780 return std::string(
"Principal<") + TargetTag::name() +
" >";
3785 template <
class U,
class BASE>
3787 :
public TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE>
3789 typedef typename TargetTag::template Impl<typename AccumulatorResultTraits<U>::SumType, BASE> ImplType;
3791 static const unsigned int workInPass = 2;
3795 vigra_precondition(
false,
3796 "Principal<...>::operator+=(): not supported.");
3800 void update(T
const &)
3802 ImplType::update(getDependency<PrincipalProjection>(*
this));
3806 void update(T
const &,
double weight)
3808 ImplType::update(getDependency<PrincipalProjection>(*
this), weight);
3845 static std::string name()
3847 return "CoordinateSystem";
3852 template <
class U,
class BASE>
3856 typedef double element_type;
3857 typedef Matrix<double> value_type;
3858 typedef value_type
const & result_type;
3868 value_ = element_type();
3871 template <
class Shape>
3872 void reshape(Shape
const & s)
3874 acc_detail::reshapeImpl(value_, s);
3877 result_type operator()()
const
3884 template <
class BASE,
class T,
3885 class ElementType=
typename AccumulatorResultTraits<T>::element_promote_type,
3886 class SumType=
typename AccumulatorResultTraits<T>::SumType>
3890 typedef ElementType element_type;
3891 typedef SumType value_type;
3892 typedef value_type
const & result_type;
3902 value_ = element_type();
3905 template <
class Shape>
3906 void reshape(Shape
const & s)
3908 acc_detail::reshapeImpl(value_, s);
3916 result_type operator()()
const
3927 typedef Select<> Dependencies;
3929 static std::string name()
3931 return "PowerSum<0>";
3936 template <
class T,
class BASE>
3938 :
public SumBaseImpl<BASE, T, double, double>
3940 void update(T
const &)
3945 void update(T
const &,
double weight)
3947 this->value_ += weight;
3957 typedef Select<> Dependencies;
3959 static std::string name()
3961 return "PowerSum<1>";
3966 template <
class U,
class BASE>
3968 :
public SumBaseImpl<BASE, U>
3970 void update(U
const & t)
3975 void update(U
const & t,
double weight)
3977 using namespace multi_math;
3979 this->value_ += weight*t;
3988 template <
unsigned N>
3992 typedef Select<> Dependencies;
3994 static std::string name()
3996 return std::string(
"PowerSum<") +
asString(N) +
">";
4001 template <
class U,
class BASE>
4003 :
public SumBaseImpl<BASE, U>
4005 void update(U
const & t)
4007 using namespace vigra::multi_math;
4008 this->value_ += pow(t, (
int)N);
4011 void update(U
const & t,
double weight)
4013 using namespace vigra::multi_math;
4014 this->value_ += weight*pow(t, (
int)N);
4020 class AbsPowerSum<1>
4023 typedef Select<> Dependencies;
4025 static std::string name()
4027 return "AbsPowerSum<1>";
4032 template <
class U,
class BASE>
4034 :
public SumBaseImpl<BASE, U>
4036 void update(U
const & t)
4038 using namespace vigra::multi_math;
4039 this->value_ +=
abs(t);
4042 void update(U
const & t,
double weight)
4044 using namespace vigra::multi_math;
4045 this->value_ += weight*
abs(t);
4054 template <
unsigned N>
4058 typedef Select<> Dependencies;
4060 static std::string name()
4062 return std::string(
"AbsPowerSum<") +
asString(N) +
">";
4067 template <
class U,
class BASE>
4069 :
public SumBaseImpl<BASE, U>
4071 void update(U
const & t)
4073 using namespace vigra::multi_math;
4074 this->value_ += pow(
abs(t), (
int)N);
4077 void update(U
const & t,
double weight)
4079 using namespace vigra::multi_math;
4080 this->value_ += weight*pow(
abs(t), (
int)N);
4085 template <
class BASE,
class VALUE_TYPE,
class U>
4086 struct CachedResultBase
4089 typedef typename AccumulatorResultTraits<U>::element_type element_type;
4090 typedef VALUE_TYPE value_type;
4091 typedef value_type
const & result_type;
4093 mutable value_type value_;
4101 value_ = element_type();
4105 template <
class Shape>
4106 void reshape(Shape
const & s)
4108 acc_detail::reshapeImpl(value_, s);
4116 void update(U
const &)
4121 void update(U
const &,
double)
4130 template <
class TAG>
4134 typedef typename StandardizeTag<TAG>::type TargetTag;
4135 typedef Select<TargetTag, Count> Dependencies;
4137 static std::string name()
4139 return std::string(
"DivideByCount<") + TargetTag::name() +
" >";
4144 template <
class U,
class BASE>
4146 :
public CachedResultBase<BASE, typename LookupDependency<TargetTag, BASE>::value_type, U>
4148 typedef typename CachedResultBase<BASE, typename LookupDependency<TargetTag, BASE>::value_type, U>::result_type result_type;
4150 result_type operator()()
const
4154 using namespace multi_math;
4155 this->value_ = getDependency<TargetTag>(*this) / getDependency<Count>(*this);
4158 return this->value_;
4166 template <
class TAG>
4167 class DivideUnbiased
4170 typedef typename StandardizeTag<TAG>::type TargetTag;
4171 typedef Select<TargetTag, Count> Dependencies;
4173 static std::string name()
4175 return std::string(
"DivideUnbiased<") + TargetTag::name() +
" >";
4180 template <
class U,
class BASE>
4184 typedef typename LookupDependency<TargetTag, BASE>::value_type value_type;
4185 typedef value_type result_type;
4187 result_type operator()()
const
4189 using namespace multi_math;
4190 return getDependency<TargetTag>(*this) / (getDependency<Count>(*this) - 1.0);
4198 template <
class TAG>
4199 class RootDivideByCount
4202 typedef typename StandardizeTag<DivideByCount<TAG> >::type TargetTag;
4203 typedef Select<TargetTag> Dependencies;
4205 static std::string name()
4207 typedef typename StandardizeTag<TAG>::type InnerTag;
4208 return std::string(
"RootDivideByCount<") + InnerTag::name() +
" >";
4213 template <
class U,
class BASE>
4217 typedef typename LookupDependency<TargetTag, BASE>::value_type value_type;
4218 typedef value_type result_type;
4220 result_type operator()()
const
4222 using namespace multi_math;
4223 return sqrt(getDependency<TargetTag>(*
this));
4231 template <
class TAG>
4232 class RootDivideUnbiased
4235 typedef typename StandardizeTag<DivideUnbiased<TAG> >::type TargetTag;
4236 typedef Select<TargetTag> Dependencies;
4238 static std::string name()
4240 typedef typename StandardizeTag<TAG>::type InnerTag;
4241 return std::string(
"RootDivideUnbiased<") + InnerTag::name() +
" >";
4246 template <
class U,
class BASE>
4250 typedef typename LookupDependency<TargetTag, BASE>::value_type value_type;
4251 typedef value_type result_type;
4253 result_type operator()()
const
4255 using namespace multi_math;
4256 return sqrt(getDependency<TargetTag>(*
this));
4269 static std::string name()
4271 return "Central<PowerSum<2> >";
4276 template <
class U,
class BASE>
4278 :
public SumBaseImpl<BASE, U>
4282 using namespace vigra::multi_math;
4283 double n1 = getDependency<Count>(*this), n2 = getDependency<Count>(o);
4286 this->value_ = o.value_;
4290 this->value_ += o.value_ + n1 * n2 / (n1 + n2) *
sq(getDependency<Mean>(*
this) - getDependency<Mean>(o));
4294 void update(U
const & t)
4296 double n = getDependency<Count>(*this);
4299 using namespace vigra::multi_math;
4300 this->value_ += n / (n - 1.0) *
sq(getDependency<Mean>(*
this) - t);
4304 void update(U
const & t,
double weight)
4306 double n = getDependency<Count>(*this);
4309 using namespace vigra::multi_math;
4310 this->value_ += n / (n - weight) *
sq(getDependency<Mean>(*
this) - t);
4324 static std::string name()
4326 return "Central<PowerSum<3> >";
4331 template <
class U,
class BASE>
4333 :
public SumBaseImpl<BASE, U>
4335 typedef typename SumBaseImpl<BASE, U>::value_type value_type;
4337 static const unsigned int workInPass = 2;
4343 using namespace vigra::multi_math;
4344 double n1 = getDependency<Count>(*this), n2 = getDependency<Count>(o);
4347 this->value_ = o.value_;
4352 double weight = n1 * n2 * (n1 - n2) /
sq(n);
4353 value_type delta = getDependency<Mean>(o) - getDependency<Mean>(*
this);
4354 this->value_ += o.value_ + weight * pow(delta, 3) +
4355 3.0 / n * delta * (n1 * getDependency<Sum2Tag>(o) - n2 * getDependency<Sum2Tag>(*
this));
4359 void update(U
const &)
4361 using namespace vigra::multi_math;
4362 this->value_ += pow(getDependency<Centralize>(*
this), 3);
4365 void update(U
const &,
double weight)
4367 using namespace vigra::multi_math;
4368 this->value_ += weight*pow(getDependency<Centralize>(*
this), 3);
4380 static std::string name()
4382 return "Central<PowerSum<4> >";
4387 template <
class U,
class BASE>
4389 :
public SumBaseImpl<BASE, U>
4391 typedef typename SumBaseImpl<BASE, U>::value_type value_type;
4393 static const unsigned int workInPass = 2;
4400 using namespace vigra::multi_math;
4401 double n1 = getDependency<Count>(*this), n2 = getDependency<Count>(o);
4404 this->value_ = o.value_;
4409 double n1_2 =
sq(n1);
4410 double n2_2 =
sq(n2);
4412 double weight = n1 * n2 * (n1_2 - n1*n2 + n2_2) / n_2 / n;
4413 value_type delta = getDependency<Mean>(o) - getDependency<Mean>(*
this);
4414 this->value_ += o.value_ + weight * pow(delta, 4) +
4415 6.0 / n_2 *
sq(delta) * (n1_2 * getDependency<Sum2Tag>(o) + n2_2 * getDependency<Sum2Tag>(*
this)) +
4416 4.0 / n * delta * (n1 * getDependency<Sum3Tag>(o) - n2 * getDependency<Sum3Tag>(*this));
4420 void update(U
const &)
4422 using namespace vigra::multi_math;
4423 this->value_ += pow(getDependency<Centralize>(*
this), 4);
4426 void update(U
const &,
double weight)
4428 using namespace vigra::multi_math;
4429 this->value_ += weight*pow(getDependency<Centralize>(*
this), 4);
4444 static std::string name()
4451 template <
class U,
class BASE>
4455 static const unsigned int workInPass = 2;
4457 typedef typename LookupDependency<Central<PowerSum<3> >, BASE>::value_type value_type;
4458 typedef value_type result_type;
4460 result_type operator()()
const
4465 using namespace multi_math;
4466 return sqrt(getDependency<Count>(*
this)) * getDependency<Sum3>(*this) / pow(getDependency<Sum2>(*
this), 1.5);
4480 static std::string name()
4482 return "UnbiasedSkewness";
4487 template <
class U,
class BASE>
4491 static const unsigned int workInPass = 2;
4493 typedef typename LookupDependency<Central<PowerSum<3> >, BASE>::value_type value_type;
4494 typedef value_type result_type;
4496 result_type operator()()
const
4498 using namespace multi_math;
4499 double n = getDependency<Count>(*this);
4500 return sqrt(n*(n-1.0)) / (n - 2.0) * getDependency<Skewness>(*this);
4516 static std::string name()
4523 template <
class U,
class BASE>
4527 static const unsigned int workInPass = 2;
4529 typedef typename LookupDependency<Central<PowerSum<4> >, BASE>::value_type value_type;
4530 typedef value_type result_type;
4532 result_type operator()()
const
4537 using namespace multi_math;
4538 return getDependency<Count>(*this) * getDependency<Sum4>(*this) /
sq(getDependency<Sum2>(*
this)) - 3.0;
4552 static std::string name()
4554 return "UnbiasedKurtosis";
4559 template <
class U,
class BASE>
4563 static const unsigned int workInPass = 2;
4565 typedef typename LookupDependency<Central<PowerSum<4> >, BASE>::value_type value_type;
4566 typedef value_type result_type;
4568 result_type operator()()
const
4570 using namespace multi_math;
4571 double n = getDependency<Count>(*this);
4572 return (n-1.0)/((n-2.0)*(n-3.0))*((n+1.0)*getDependency<Kurtosis>(*this) + value_type(6.0));
4577 namespace acc_detail {
4579 template <
class Scatter,
class Sum>
4580 void updateFlatScatterMatrix(Scatter & sc,
Sum const & s,
double w)
4582 int size = s.size();
4585 sc[k] += w*s[i]*s[j];
4588 template <
class Sum>
4589 void updateFlatScatterMatrix(
double & sc,
Sum const & s,
double w)
4594 template <
class Cov,
class Scatter>
4595 void flatScatterMatrixToScatterMatrix(Cov & cov, Scatter
const & sc)
4597 int size = cov.shape(0), k=0;
4604 cov(j,i) = cov(i,j);
4609 template <
class Scatter>
4610 void flatScatterMatrixToScatterMatrix(
double & cov, Scatter
const & sc)
4615 template <
class Cov,
class Scatter>
4616 void flatScatterMatrixToCovariance(Cov & cov, Scatter
const & sc,
double n)
4618 int size = cov.shape(0), k=0;
4621 cov(j,j) = sc[k++] / n;
4624 cov(i,j) = sc[k++] / n;
4625 cov(j,i) = cov(i,j);
4630 template <
class Scatter>
4631 void flatScatterMatrixToCovariance(
double & cov, Scatter
const & sc,
double n)
4648 static std::string name()
4650 return "FlatScatterMatrix";
4655 template <
class U,
class BASE>
4659 typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
4660 typedef typename AccumulatorResultTraits<U>::FlatCovarianceType value_type;
4661 typedef value_type
const & result_type;
4663 typedef typename AccumulatorResultTraits<U>::SumType SumType;
4675 value_ = element_type();
4678 template <
class Shape>
4679 void reshape(Shape
const & s)
4682 acc_detail::reshapeImpl(value_,
Shape1(size*(size+1)/2));
4683 acc_detail::reshapeImpl(diff_, s);
4688 double n1 = getDependency<Count>(*this), n2 = getDependency<Count>(o);
4695 using namespace vigra::multi_math;
4696 diff_ = getDependency<Mean>(*this) - getDependency<Mean>(o);
4697 acc_detail::updateFlatScatterMatrix(value_, diff_, n1 * n2 / (n1 + n2));
4702 void update(U
const & t)
4707 void update(U
const & t,
double weight)
4712 result_type operator()()
const
4718 void compute(U
const & t,
double weight = 1.0)
4720 double n = getDependency<Count>(*this);
4723 using namespace vigra::multi_math;
4724 diff_ = getDependency<Mean>(*this) - t;
4725 acc_detail::updateFlatScatterMatrix(value_, diff_, n * weight / (n - weight));
4738 static std::string name()
4740 return "DivideByCount<FlatScatterMatrix>";
4745 template <
class U,
class BASE>
4747 :
public CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U>
4749 typedef CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U> BaseType;
4750 typedef typename BaseType::result_type result_type;
4752 template <
class Shape>
4753 void reshape(Shape
const & s)
4756 acc_detail::reshapeImpl(this->value_, Shape2(size,size));
4759 result_type operator()()
const
4763 acc_detail::flatScatterMatrixToCovariance(this->value_, getDependency<FlatScatterMatrix>(*
this), getDependency<Count>(*
this));
4766 return this->value_;
4773 class DivideUnbiased<FlatScatterMatrix>
4776 typedef Select<FlatScatterMatrix, Count> Dependencies;
4778 static std::string name()
4780 return "DivideUnbiased<FlatScatterMatrix>";
4785 template <
class U,
class BASE>
4787 :
public CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U>
4789 typedef CachedResultBase<BASE, typename AccumulatorResultTraits<U>::CovarianceType, U> BaseType;
4790 typedef typename BaseType::result_type result_type;
4792 template <
class Shape>
4793 void reshape(Shape
const & s)
4796 acc_detail::reshapeImpl(this->value_, Shape2(size,size));
4799 result_type operator()()
const
4803 acc_detail::flatScatterMatrixToCovariance(this->value_, getDependency<FlatScatterMatrix>(*
this), getDependency<Count>(*
this) - 1.0);
4806 return this->value_;
4818 static std::string name()
4820 return "ScatterMatrixEigensystem";
4825 template <
class U,
class BASE>
4829 typedef typename AccumulatorResultTraits<U>::element_promote_type element_type;
4830 typedef typename AccumulatorResultTraits<U>::SumType EigenvalueType;
4831 typedef typename AccumulatorResultTraits<U>::CovarianceType EigenvectorType;
4832 typedef std::pair<EigenvalueType, EigenvectorType> value_type;
4833 typedef value_type
const & result_type;
4835 mutable value_type value_;
4843 if(!acc_detail::hasDataImpl(value_.second))
4845 acc_detail::copyShapeImpl(o.value_.first, value_.first);
4846 acc_detail::copyShapeImpl(o.value_.second, value_.second);
4851 void update(U
const &)
4856 void update(U
const &,
double)
4863 value_.first = element_type();
4864 value_.second = element_type();
4868 template <
class Shape>
4869 void reshape(Shape
const & s)
4872 acc_detail::reshapeImpl(value_.first,
Shape1(size));
4873 acc_detail::reshapeImpl(value_.second, Shape2(size,size));
4876 result_type operator()()
const
4880 compute(getDependency<FlatScatterMatrix>(*
this), value_.first, value_.second);
4887 template <
class Flat,
class EW,
class EV>
4888 static void compute(Flat
const & flatScatter, EW & ew, EV & ev)
4890 EigenvectorType scatter(ev.shape());
4891 acc_detail::flatScatterMatrixToScatterMatrix(scatter, flatScatter);
4897 static void compute(
double v,
double & ew,
double & ev)
4912 static std::string name()
4914 return "DivideByCount<ScatterMatrixEigensystem>";
4919 template <
class U,
class BASE>
4923 typedef typename LookupDependency<ScatterMatrixEigensystem, BASE>::type SMImpl;
4924 typedef typename SMImpl::element_type element_type;
4925 typedef typename SMImpl::EigenvalueType EigenvalueType;
4926 typedef typename SMImpl::EigenvectorType EigenvectorType;
4927 typedef std::pair<EigenvalueType, EigenvectorType const &> value_type;
4928 typedef value_type
const & result_type;
4930 mutable value_type value_;
4933 : value_(EigenvalueType(), BASE::template call_getDependency<ScatterMatrixEigensystem>().second)
4941 void update(U
const &)
4946 void update(U
const &,
double)
4953 value_.first = element_type();
4957 template <
class Shape>
4958 void reshape(Shape
const & s)
4961 acc_detail::reshapeImpl(value_.first, Shape2(size,1));
4964 result_type operator()()
const
4968 value_.first = getDependency<ScatterMatrixEigensystem>(*this).first / getDependency<Count>(*this);
5066 static std::string name()
5068 return "Principal<PowerSum<2> >";
5073 template <
class U,
class BASE>
5077 typedef typename LookupDependency<ScatterMatrixEigensystem, BASE>::type::EigenvalueType value_type;
5078 typedef value_type
const & result_type;
5080 result_type operator()()
const
5082 return getDependency<ScatterMatrixEigensystem>(*this).first;
5097 static std::string name()
5099 return "Principal<CoordinateSystem>";
5104 template <
class U,
class BASE>
5108 typedef typename LookupDependency<ScatterMatrixEigensystem, BASE>::type::EigenvectorType value_type;
5109 typedef value_type
const & result_type;
5111 result_type operator()()
const
5113 return getDependency<ScatterMatrixEigensystem>(*this).second;
5127 static std::string name()
5134 template <
class U,
class BASE>
5138 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5139 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5140 typedef value_type
const & result_type;
5146 value_ = NumericTraits<element_type>::max();
5151 value_ = NumericTraits<element_type>::max();
5154 template <
class Shape>
5155 void reshape(Shape
const & s)
5157 acc_detail::reshapeImpl(value_, s, NumericTraits<element_type>::max());
5162 updateImpl(o.value_);
5165 void update(U
const & t)
5170 void update(U
const & t,
double)
5175 result_type operator()()
const
5182 void updateImpl(T
const & o)
5184 using namespace multi_math;
5185 value_ = min(value_, o);
5188 template <
class T,
class Alloc>
5191 value_ = multi_math::min(value_, o);
5205 static std::string name()
5212 template <
class U,
class BASE>
5216 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5217 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5218 typedef value_type
const & result_type;
5224 value_ = NumericTraits<element_type>::min();
5229 value_ = NumericTraits<element_type>::min();
5232 template <
class Shape>
5233 void reshape(Shape
const & s)
5235 acc_detail::reshapeImpl(value_, s, NumericTraits<element_type>::min());
5240 updateImpl(o.value_);
5243 void update(U
const & t)
5248 void update(U
const & t,
double)
5253 result_type operator()()
const
5260 void updateImpl(T
const & o)
5262 using namespace multi_math;
5263 value_ = max(value_, o);
5266 template <
class T,
class Alloc>
5269 value_ = multi_math::max(value_, o);
5284 static std::string name()
5291 template <
class U,
class BASE>
5295 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5296 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5297 typedef value_type
const & result_type;
5307 value_ = element_type();
5310 template <
class Shape>
5311 void reshape(Shape
const & s)
5313 acc_detail::reshapeImpl(value_, s);
5319 if(reverse(o.value_) < reverse(value_))
5323 void update(U
const & t)
5325 if(getDependency<Count>(*
this) == 1)
5329 void update(U
const & t,
double)
5334 result_type operator()()
const
5352 static std::string name()
5359 template <
class U,
class BASE>
5363 typedef typename AccumulatorResultTraits<U>::MinmaxType minmax_type;
5364 typedef std::pair<minmax_type, minmax_type> value_type;
5365 typedef value_type result_type;
5367 result_type operator()()
const
5369 return value_type(getDependency<Minimum>(*
this), getDependency<Maximum>(*
this));
5383 static std::string name()
5385 return "ArgMinWeight";
5390 template <
class U,
class BASE>
5394 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5395 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5396 typedef value_type
const & result_type;
5402 : min_weight_(NumericTraits<double>::max()),
5408 min_weight_ = NumericTraits<double>::max();
5409 value_ = element_type();
5412 template <
class Shape>
5413 void reshape(Shape
const & s)
5415 acc_detail::reshapeImpl(value_, s);
5420 using namespace multi_math;
5421 if(o.min_weight_ < min_weight_)
5423 min_weight_ = o.min_weight_;
5428 void update(U
const &)
5430 vigra_precondition(
false,
"ArgMinWeight::update() needs weights.");
5433 void update(U
const & t,
double weight)
5435 if(weight < min_weight_)
5437 min_weight_ = weight;
5442 result_type operator()()
const
5458 static std::string name()
5460 return "ArgMaxWeight";
5465 template <
class U,
class BASE>
5469 typedef typename AccumulatorResultTraits<U>::element_type element_type;
5470 typedef typename AccumulatorResultTraits<U>::MinmaxType value_type;
5471 typedef value_type
const & result_type;
5477 : max_weight_(NumericTraits<double>::min()),
5483 max_weight_ = NumericTraits<double>::min();
5484 value_ = element_type();
5487 template <
class Shape>
5488 void reshape(Shape
const & s)
5490 acc_detail::reshapeImpl(value_, s);
5495 using namespace multi_math;
5496 if(o.max_weight_ > max_weight_)
5498 max_weight_ = o.max_weight_;
5503 void update(U
const &)
5505 vigra_precondition(
false,
"ArgMaxWeight::update() needs weights.");
5508 void update(U
const & t,
double weight)
5510 if(weight > max_weight_)
5512 max_weight_ = weight;
5517 result_type operator()()
const
5525 template <
class BASE,
int BinCount>
5531 typedef double element_type;
5533 typedef value_type
const & result_type;
5536 double left_outliers, right_outliers;
5546 value_ = element_type();
5547 left_outliers = 0.0;
5548 right_outliers = 0.0;
5554 left_outliers += o.left_outliers;
5555 right_outliers += o.right_outliers;
5558 result_type operator()()
const
5564 template <
class BASE>
5565 class HistogramBase<BASE, 0>
5570 typedef double element_type;
5571 typedef MultiArray<1, double> value_type;
5572 typedef value_type
const & result_type;
5575 double left_outliers, right_outliers;
5585 value_ = element_type();
5586 left_outliers = 0.0;
5587 right_outliers = 0.0;
5592 if(value_.size() == 0)
5596 else if(o.value_.size() > 0)
5598 vigra_precondition(value_.size() == o.value_.size(),
5599 "HistogramBase::operator+=(): bin counts must be equal.");
5602 left_outliers += o.left_outliers;
5603 right_outliers += o.right_outliers;
5606 void setBinCount(
int binCount)
5608 vigra_precondition(binCount > 0,
5609 "HistogramBase:.setBinCount(): binCount > 0 required.");
5610 value_type(Shape1(binCount)).swap(value_);
5613 result_type operator()()
const
5619 template <
class BASE,
int BinCount,
class U=
typename BASE::input_type>
5620 class RangeHistogramBase
5621 :
public HistogramBase<BASE, BinCount>
5624 double scale_, offset_, inverse_scale_;
5626 RangeHistogramBase()
5636 inverse_scale_ = 0.0;
5637 HistogramBase<BASE, BinCount>::reset();
5640 void operator+=(RangeHistogramBase
const & o)
5642 vigra_precondition(scale_ == 0.0 || o.scale_ == 0.0 || (scale_ == o.scale_ && offset_ == o.offset_),
5643 "RangeHistogramBase::operator+=(): cannot merge histograms with different data mapping.");
5649 offset_ = o.offset_;
5650 inverse_scale_ = o.inverse_scale_;
5654 void update(U
const & t)
5659 void update(U
const & t,
double weight)
5661 double m = mapItem(t);
5662 int index = (m == (double)this->value_.size())
5666 this->left_outliers += weight;
5667 else if(index >= (
int)this->value_.size())
5668 this->right_outliers += weight;
5670 this->value_[index] += weight;
5673 void setMinMax(
double mi,
double ma)
5675 vigra_precondition(this->value_.size() > 0,
5676 "RangeHistogramBase::setMinMax(...): setBinCount(...) has not been called.");
5677 vigra_precondition(mi <= ma,
5678 "RangeHistogramBase::setMinMax(...): min <= max required.");
5680 ma += this->value_.size() * NumericTraits<double>::epsilon();
5682 scale_ = (double)this->value_.size() / (ma - mi);
5683 inverse_scale_ = 1.0 / scale_;
5686 double mapItem(
double t)
const
5688 return scale_ * (t - offset_);
5691 double mapItemInverse(
double t)
const
5693 return inverse_scale_ * t + offset_;
5696 template <
class ArrayLike>
5697 void computeStandardQuantiles(
double minimum,
double maximum,
double count,
5698 ArrayLike
const & desiredQuantiles, ArrayLike & res)
const
5704 ArrayVector<double> keypoints, cumhist;
5705 double mappedMinimum = mapItem(minimum);
5706 double mappedMaximum = mapItem(maximum);
5708 keypoints.push_back(mappedMinimum);
5709 cumhist.push_back(0.0);
5711 if(this->left_outliers > 0.0)
5713 keypoints.push_back(0.0);
5714 cumhist.push_back(this->left_outliers);
5717 int size = (int)this->value_.size();
5718 double cumulative = this->left_outliers;
5719 for(
int k=0; k<size; ++k)
5721 if(this->value_[k] > 0.0)
5723 if(keypoints.back() <= k)
5725 keypoints.push_back(k);
5726 cumhist.push_back(cumulative);
5728 cumulative += this->value_[k];
5729 keypoints.push_back(k+1);
5730 cumhist.push_back(cumulative);
5734 if(this->right_outliers > 0.0)
5736 if(keypoints.back() != size)
5738 keypoints.push_back(size);
5739 cumhist.push_back(cumulative);
5741 keypoints.push_back(mappedMaximum);
5742 cumhist.push_back(count);
5746 keypoints.back() = mappedMaximum;
5747 cumhist.back() = count;
5750 int quantile = 0, end = (int)desiredQuantiles.size();
5752 if(desiredQuantiles[0] == 0.0)
5757 if(desiredQuantiles[end-1] == 1.0)
5759 res[end-1] = maximum;
5764 double qcount = count * desiredQuantiles[quantile];
5765 while(quantile < end)
5767 if(cumhist[point] < qcount && cumhist[point+1] >= qcount)
5769 double t = (qcount - cumhist[point]) / (cumhist[point+1] - cumhist[point]) * (keypoints[point+1] - keypoints[point]);
5770 res[quantile] = mapItemInverse(t + keypoints[point]);
5772 qcount = count * desiredQuantiles[quantile];
5790 template <
int BinCount>
5791 class IntegerHistogram
5795 typedef Select<> Dependencies;
5797 static std::string name()
5799 return std::string(
"IntegerHistogram<") +
asString(BinCount) +
">";
5804 template <
class U,
class BASE>
5806 :
public HistogramBase<BASE, BinCount>
5808 void update(
int index)
5811 ++this->left_outliers;
5812 else if(index >= (
int)this->value_.size())
5813 ++this->right_outliers;
5815 ++this->value_[index];
5818 void update(
int,
double)
5822 vigra_precondition(
false,
"IntegerHistogram::update(): weighted histograms not supported, use another histogram type.");
5825 template <
class ArrayLike>
5826 void computeStandardQuantiles(
double minimum,
double maximum,
double count,
5827 ArrayLike
const & desiredQuantiles, ArrayLike & res)
const
5829 int quantile = 0, end = (int)desiredQuantiles.size();
5831 if(desiredQuantiles[0] == 0.0)
5836 if(desiredQuantiles[end-1] == 1.0)
5838 res[end-1] = maximum;
5843 int currentBin = 0, size = (int)this->value_.size();
5844 double cumulative1 = this->left_outliers,
5845 cumulative2 = this->value_[currentBin] + cumulative1;
5849 double qcount = desiredQuantiles[quantile]*count + 1.0;
5851 while(quantile < end)
5853 if(cumulative2 == qcount)
5855 res[quantile] = currentBin;
5857 qcount = desiredQuantiles[quantile]*count + 1.0;
5859 else if(cumulative2 > qcount)
5861 if(cumulative1 > qcount)
5863 res[quantile] = minimum;
5865 if(cumulative1 + 1.0 > qcount)
5867 res[quantile] = currentBin - 1 + qcount -
std::floor(qcount);
5871 res[quantile] = currentBin;
5874 qcount = desiredQuantiles[quantile]*count + 1.0;
5876 else if(currentBin == size-1)
5878 res[quantile] = maximum;
5880 qcount = desiredQuantiles[quantile]*count + 1.0;
5885 cumulative1 = cumulative2;
5886 cumulative2 += this->value_[currentBin];
5903 template <
int BinCount>
5904 class UserRangeHistogram
5908 typedef Select<> Dependencies;
5910 static std::string name()
5912 return std::string(
"UserRangeHistogram<") +
asString(BinCount) +
">";
5917 template <
class U,
class BASE>
5919 :
public RangeHistogramBase<BASE, BinCount, U>
5921 void update(U
const & t)
5926 void update(U
const & t,
double weight)
5928 vigra_precondition(this->scale_ != 0.0,
5929 "UserRangeHistogram::update(): setMinMax(...) has not been called.");
5931 RangeHistogramBase<BASE, BinCount, U>::update(t, weight);
5945 template <
int BinCount>
5946 class AutoRangeHistogram
5950 typedef Select<Minimum, Maximum> Dependencies;
5952 static std::string name()
5954 return std::string(
"AutoRangeHistogram<") +
asString(BinCount) +
">";
5959 template <
class U,
class BASE>
5961 :
public RangeHistogramBase<BASE, BinCount, U>
5963 static const unsigned int workInPass = LookupDependency<Minimum, BASE>::type::workInPass + 1;
5965 void update(U
const & t)
5970 void update(U
const & t,
double weight)
5972 if(this->scale_ == 0.0)
5973 this->setMinMax(getDependency<Minimum>(*
this), getDependency<Maximum>(*
this));
5975 RangeHistogramBase<BASE, BinCount, U>::update(t, weight);
5989 template <
int BinCount>
5990 class GlobalRangeHistogram
5994 typedef Select<Global<Minimum>, Global<Maximum>, Minimum, Maximum> Dependencies;
5996 static std::string name()
5998 return std::string(
"GlobalRangeHistogram<") +
asString(BinCount) +
">";
6003 template <
class U,
class BASE>
6005 :
public RangeHistogramBase<BASE, BinCount, U>
6007 static const unsigned int workInPass = LookupDependency<Minimum, BASE>::type::workInPass + 1;
6009 bool useLocalMinimax_;
6012 : useLocalMinimax_(false)
6015 void setRegionAutoInit(
bool locally)
6018 useLocalMinimax_ = locally;
6021 void update(U
const & t)
6026 void update(U
const & t,
double weight)
6028 if(this->scale_ == 0.0)
6030 if(useLocalMinimax_)
6031 this->setMinMax(getDependency<Minimum>(*
this), getDependency<Maximum>(*
this));
6033 this->setMinMax(getDependency<Global<Minimum> >(*
this), getDependency<Global<Maximum> >(*
this));
6036 RangeHistogramBase<BASE, BinCount, U>::update(t, weight);
6045 template <
class HistogramAccumulator>
6046 class StandardQuantiles
6050 typedef typename StandardizeTag<HistogramAccumulator>::type HistogramTag;
6051 typedef Select<HistogramTag, Minimum, Maximum, Count> Dependencies;
6053 static std::string name()
6055 return std::string(
"StandardQuantiles<") + HistogramTag::name() +
" >";
6060 template <
class U,
class BASE>
6062 :
public CachedResultBase<BASE, TinyVector<double, 7>, U>
6064 typedef typename CachedResultBase<BASE, TinyVector<double, 7>, U>::result_type result_type;
6065 typedef typename CachedResultBase<BASE, TinyVector<double, 7>, U>::value_type value_type;
6067 static const unsigned int workInPass = LookupDependency<HistogramTag, BASE>::type::workInPass;
6069 result_type operator()()
const
6073 double desiredQuantiles[] = {0.0, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0 };
6074 getAccumulator<HistogramTag>(*this).computeStandardQuantiles(getDependency<Minimum>(*
this), getDependency<Maximum>(*
this),
6075 getDependency<Count>(*
this), value_type(desiredQuantiles),
6079 return this->value_;
6085 struct feature_RegionContour_can_only_be_computed_for_2D_arrays
6086 : vigra::staticAssert::AssertBool<N==2>
6098 static std::string name()
6100 return std::string(
"RegionContour");
6105 template <
class T,
class BASE>
6109 typedef HandleArgSelector<T, LabelArgTag, BASE> LabelHandle;
6112 typedef value_type
const & result_type;
6115 value_type contour_;
6122 void setCoordinateOffset(point_type
const & offset)
6127 template <
class U,
class NEXT>
6130 VIGRA_STATIC_ASSERT((feature_RegionContour_can_only_be_computed_for_2D_arrays<
6132 if(getDependency<Count>(*
this) == 1)
6135 extractContour(LabelHandle::getHandle(t).arrayView(), t.point(), contour_);
6136 contour_ += offset_;
6140 template <
class U,
class NEXT>
6148 vigra_precondition(
false,
6149 "RegionContour::operator+=(): RegionContour cannot be merged.");
6152 result_type operator()()
const
6171 static std::string name()
6173 return std::string(
"RegionPerimeter");
6178 template <
class T,
class BASE>
6182 typedef double value_type;
6183 typedef value_type result_type;
6185 result_type operator()()
const
6187 return getDependency<RegionContour>(*this).length();
6204 static std::string name()
6206 return std::string(
"RegionCircularity");
6211 template <
class T,
class BASE>
6215 typedef double value_type;
6216 typedef value_type result_type;
6218 result_type operator()()
const
6220 return 2.0*
sqrt(M_PI*getDependency<RegionContour>(*this).area()) / getDependency<RegionContour>(*this).length();
6236 static std::string name()
6238 return std::string(
"RegionEccentricity");
6243 template <
class T,
class BASE>
6247 typedef double value_type;
6248 typedef value_type result_type;
6250 result_type operator()()
const
6252 double M = getDependency<RegionRadii>(*this).front(),
6253 m = getDependency<RegionRadii>(*this).back();
6254 return sqrt(1.0 -
sq(m/M));
6260 struct feature_ConvexHull_can_only_be_computed_for_2D_arrays
6261 : vigra::staticAssert::AssertBool<N==2>
6273 static std::string name()
6275 return std::string(
"ConvexHull");
6280 template <
class T,
class BASE>
6284 static const unsigned int workInPass = 2;
6286 typedef HandleArgSelector<T, LabelArgTag, BASE> LabelHandle;
6289 typedef Impl value_type;
6290 typedef value_type
const & result_type;
6292 polygon_type convex_hull_;
6293 point_type input_center_, convex_hull_center_, defect_center_;
6294 double convexity_, rugosity_, mean_defect_displacement_,
6295 defect_area_mean_, defect_area_variance_, defect_area_skewness_, defect_area_kurtosis_;
6296 int convexity_defect_count_;
6298 bool features_computed_;
6303 , convex_hull_center_()
6307 , mean_defect_displacement_()
6308 , defect_area_mean_()
6309 , defect_area_variance_()
6310 , defect_area_skewness_()
6311 , defect_area_kurtosis_()
6312 , convexity_defect_count_()
6313 , convexity_defect_area_()
6314 , features_computed_(
false)
6317 template <
class U,
class NEXT>
6320 VIGRA_STATIC_ASSERT((feature_ConvexHull_can_only_be_computed_for_2D_arrays<
6322 if(!features_computed_)
6324 using namespace functor;
6325 Shape2 start = getDependency<Coord<Minimum> >(*this),
6326 stop = getDependency<Coord<Maximum> >(*this) + Shape2(1);
6327 point_type offset(start);
6328 input_center_ = getDependency<RegionCenter>(*this);
6331 convex_hull_.clear();
6332 convexHull(getDependency<RegionContour>(*
this), convex_hull_);
6333 convex_hull_center_ = centroid(convex_hull_);
6335 convexity_ = getDependency<RegionContour>(*this).area() / convex_hull_.area();
6336 rugosity_ = getDependency<RegionContour>(*this).length() / convex_hull_.length();
6339 fillPolygon(convex_hull_ - offset, convex_hull_difference, 1);
6341 LabelHandle::getHandle(t).arrayView().subarray(start, stop),
6342 convex_hull_difference,
6343 ifThenElse(Arg2() == Param(label), Param(0), Arg1()));
6346 convexity_defect_count_ =
6349 if (convexity_defect_count_ != 0)
6353 convexity_defects_stats.ignoreLabel(0);
6356 double total_defect_area = 0.0;
6357 mean_defect_displacement_ = 0.0;
6358 defect_center_ = point_type();
6359 for (
int k = 1; k <= convexity_defect_count_; ++k)
6361 double area = get<Count>(convexity_defects_stats, k);
6362 point_type center = get<RegionCenter>(convexity_defects_stats, k) + offset;
6364 convexity_defect_area_.push_back(area);
6365 total_defect_area += area;
6366 defect_center_ += area*center;
6367 mean_defect_displacement_ += area*
norm(input_center_ - center);
6369 sort(convexity_defect_area_.begin(), convexity_defect_area_.end(),
6370 std::greater<MultiArrayIndex>());
6371 mean_defect_displacement_ /= total_defect_area;
6372 defect_center_ /= total_defect_area;
6377 convexity_defect_area_.end(), defect_area_stats);
6379 defect_area_mean_ = convexity_defect_count_ > 0
6380 ? get<Mean>(defect_area_stats)
6382 defect_area_variance_ = convexity_defect_count_ > 1
6383 ? get<UnbiasedVariance>(defect_area_stats)
6385 defect_area_skewness_ = convexity_defect_count_ > 2
6386 ? get<UnbiasedSkewness>(defect_area_stats)
6388 defect_area_kurtosis_ = convexity_defect_count_ > 3
6389 ? get<UnbiasedKurtosis>(defect_area_stats)
6393 features_computed_ =
true;
6397 template <
class U,
class NEXT>
6405 vigra_precondition(
false,
6406 "ConvexHull::operator+=(): ConvexHull features cannot be merged.");
6409 result_type operator()()
const
6417 polygon_type
const & hull()
const
6419 return convex_hull_;
6425 double inputArea()
const
6427 vigra_precondition(features_computed_,
6428 "ConvexHull: features must be calculated first.");
6429 return getDependency<RegionContour>(*this).area();
6435 double hullArea()
const
6437 vigra_precondition(features_computed_,
6438 "ConvexHull: features must be calculated first.");
6439 return convex_hull_.area();
6445 double inputPerimeter()
const
6447 vigra_precondition(features_computed_,
6448 "ConvexHull: features must be calculated first.");
6449 return getDependency<RegionContour>(*this).length();
6455 double hullPerimeter()
const
6457 vigra_precondition(features_computed_,
6458 "ConvexHull: features must be calculated first.");
6459 return convex_hull_.length();
6465 point_type
const & inputCenter()
const
6467 return input_center_;
6473 point_type
const & hullCenter()
const
6475 return convex_hull_center_;
6481 point_type
const & convexityDefectCenter()
const
6483 return defect_center_;
6491 double convexity()
const
6493 vigra_precondition(features_computed_,
6494 "ConvexHull: features must be calculated first.");
6503 double rugosity()
const
6505 vigra_precondition(features_computed_,
6506 "ConvexHull: features must be calculated first.");
6514 int convexityDefectCount()
const
6516 vigra_precondition(features_computed_,
6517 "ConvexHull: features must be calculated first.");
6518 return convexity_defect_count_;
6524 double convexityDefectAreaMean()
const
6526 vigra_precondition(features_computed_,
6527 "ConvexHull: features must be calculated first.");
6528 return defect_area_mean_;
6534 double convexityDefectAreaVariance()
const
6536 vigra_precondition(features_computed_,
6537 "ConvexHull: features must be calculated first.");
6538 return defect_area_variance_;
6544 double convexityDefectAreaSkewness()
const
6546 vigra_precondition(features_computed_,
6547 "ConvexHull: features must be calculated first.");
6548 return defect_area_skewness_;
6554 double convexityDefectAreaKurtosis()
const
6556 vigra_precondition(features_computed_,
6557 "ConvexHull: features must be calculated first.");
6558 return defect_area_kurtosis_;
6565 double meanDefectDisplacement()
const
6567 vigra_precondition(features_computed_,
6568 "ConvexHull: features must be calculated first.");
6569 return mean_defect_displacement_;
6577 vigra_precondition(features_computed_,
6578 "ConvexHull: features must be calculated first.");
6579 return convexity_defect_area_;
6587 #endif // VIGRA_ACCUMULATOR_HXX
CoupledHandleCast< TARGET_INDEX, Handle >::reference get(Handle &handle)
Definition: multi_handle.hxx:927
void operator+=(AccumulatorChainArray const &o)
Definition: accumulator.hxx:2422
Basic statistic. Data value where weight assumes its minimal value.
Definition: accumulator.hxx:5378
Basic statistic. PowerSum<N> = .
Definition: accumulator-grammar.hxx:59
PowerSum< 0 > Count
Alias. Count.
Definition: accumulator-grammar.hxx:154
Basic statistic. First data value seen of the object.
Definition: accumulator.hxx:5279
ArrayVector< std::string > activeNames() const
Definition: accumulator.hxx:2200
Basic statistic. Maximum value.
Definition: accumulator.hxx:5200
Compute the eccentricity of a 2D region in terms of its prinipal radii.
Definition: accumulator.hxx:6231
unsigned int passesRequired() const
Definition: accumulator.hxx:2599
void extractContour(MultiArrayView< 2, T, S > const &label_image, Shape2 const &anchor_point, PointArray &contour_points)
Create a polygon from the interpixel contour of a labeled region.
Definition: polygon.hxx:766
Return both the minimum and maximum in std::pair.
Definition: accumulator.hxx:5347
Basic statistic. Skewness.
Definition: accumulator.hxx:4439
unsigned int passesRequired() const
Definition: accumulator.hxx:2211
void reshape(TinyVector< U, N > const &s)
Definition: accumulator.hxx:2048
Compute the contour of a 2D region.
Definition: accumulator.hxx:6268
Basic statistic. Identity matrix of appropriate size.
Definition: accumulator.hxx:3840
ArrayVector< std::string > activeNames() const
Definition: accumulator.hxx:2589
const_iterator begin() const
Definition: array_vector.hxx:223
void setMaxRegionLabel(unsigned label)
Definition: accumulator.hxx:2401
void setCoordinateOffset(SHAPE const &offset)
MultiArrayIndex ignoredLabel() const
Definition: accumulator.hxx:2394
Basic statistic. Kurtosis.
Definition: accumulator.hxx:4511
Basic statistic. Unbiased Kurtosis.
Definition: accumulator.hxx:4547
Main MultiArray class containing the memory management.
Definition: multi_array.hxx:2420
void activateAll()
Definition: accumulator.hxx:2176
LookupTag< TAG, A >::reference getAccumulator(A &a)
Definition: accumulator.hxx:2904
void merge(AccumulatorChainImpl const &o)
Create an accumulator chain containing the selected statistics and their dependencies.
Definition: accumulator.hxx:2036
Basic statistic. Flattened uppter-triangular part of scatter matrix.
Definition: accumulator.hxx:4643
Modifier. Substract mean before computing statistic.
Definition: accumulator-grammar.hxx:148
Wrapper for MakeTypeList that additionally performs tag standardization.
Definition: accumulator.hxx:392
std::ptrdiff_t MultiArrayIndex
Definition: multi_fwd.hxx:60
bool isActive(A const &a)
Definition: accumulator.hxx:2999
Create an array of dynamic accumulator chains containing the selected per-region and global statistic...
Definition: accumulator.hxx:2544
void setCoordinateOffset(MultiArrayIndex k, SHAPE const &offset)
Definition: accumulator.hxx:2474
void reset(unsigned int reset_to_pass=0)
bool isActive(std::string tag) const
Definition: accumulator.hxx:2572
unsigned int labelImageWithBackground(...)
Find the connected components of a segmented image, excluding the background from labeling...
void activate(std::string tag)
Definition: accumulator.hxx:2160
bool isActive() const
Definition: accumulator.hxx:2583
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude)
Definition: fftw3.hxx:1037
bool isActive() const
Definition: accumulator.hxx:2193
Compute the contour of a 2D region.
Definition: accumulator.hxx:6093
Definition: array_vector.hxx:58
FFTWComplex< R > & operator+=(FFTWComplex< R > &a, const FFTWComplex< R > &b)
add-assignment
Definition: fftw3.hxx:859
NumericTraits< T >::Promote sq(T t)
The square function.
Definition: mathutil.hxx:372
void activate()
Definition: accumulator.hxx:2559
Basic statistic. Unbiased Skewness.
Definition: accumulator.hxx:4475
NumericTraits< V >::Promote prod(TinyVectorBase< V, SIZE, D1, D2 > const &l)
product of the vector's elements
Definition: tinyvector.hxx:2097
void activate()
Definition: accumulator.hxx:2169
bool symmetricEigensystem(MultiArrayView< 2, T, C1 > const &a, MultiArrayView< 2, T, C2 > &ew, MultiArrayView< 2, T, C3 > &ev)
Definition: eigensystem.hxx:1008
void merge(AccumulatorChainArray const &o)
Definition: accumulator.hxx:2438
std::string asString(T t)(...)
void extractFeatures(...)
void activateAll()
Definition: accumulator.hxx:2565
static ArrayVector< std::string > const & tagNames()
Definition: accumulator.hxx:2459
void operator+=(AccumulatorChainImpl const &o)
void updatePassN(T const &t, unsigned int N)
Iterator argMax(Iterator first, Iterator last)
Find the maximum element in a sequence.
Definition: algorithm.hxx:96
Create an accumulator chain that works independently of a MultiArray.
Definition: accumulator.hxx:2312
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
std::string normalizeString(std::string const &s)
Definition: utilities.hxx:109
Create an accumulator chain that works independently of a MultiArray.
Definition: accumulator.hxx:2262
void updatePassN(T const &t, unsigned int N)
unsigned int regionCount() const
Definition: accumulator.hxx:2415
PowerSum< 1 > Sum
Alias. Sum.
Definition: accumulator-grammar.hxx:165
Class for fixed size vectors.This class contains an array of size SIZE of the specified VALUETYPE...
Definition: accessor.hxx:940
Definition: multi_fwd.hxx:115
void ignoreLabel(MultiArrayIndex l)
Definition: accumulator.hxx:2387
unsigned int passesRequired() const
Definition: accumulator.hxx:4813
void setHistogramOptions(HistogramOptions const &options)
Modifier. Project onto PCA eigenvectors.
Definition: accumulator-grammar.hxx:149
void combineTwoMultiArrays(...)
Combine two multi-dimensional arrays into one using a binary function or functor. ...
Basic statistic. Data where weight assumes its maximal value.
Definition: accumulator.hxx:5453
bool isActive(std::string tag) const
Definition: accumulator.hxx:2182
static ArrayVector< std::string > const & tagNames()
Definition: accumulator.hxx:2058
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude)
Definition: fftw3.hxx:1002
Base class for, and view to, vigra::MultiArray.
Definition: multi_array.hxx:650
void merge(unsigned i, unsigned j)
Definition: accumulator.hxx:2429
void activate(std::string tag)
Definition: accumulator.hxx:2551
MultiArrayIndex maxRegionLabel() const
Definition: accumulator.hxx:2408
const_iterator end() const
Definition: array_vector.hxx:237
Compute the perimeter of a 2D region.
Definition: accumulator.hxx:6166
void convexHull(const PointArray1 &points, PointArray2 &convex_hull)
Compute convex hull of a 2D polygon.
Definition: polygon.hxx:838
void merge(AccumulatorChainArray const &o, ArrayLike const &labelMapping)
Definition: accumulator.hxx:2450
Modifier. Divide statistic by Count: DivideByCount<TAG> = TAG / Count .
Definition: accumulator-grammar.hxx:136
void activate(A &a)
Definition: accumulator.hxx:2988
void fillPolygon(Polygon< Point > const &p, MultiArrayView< 2, T, S > &output_image, Value value)
Render closed polygon p into the image output_image.
Definition: polygon.hxx:1005
void setHistogramOptions(HistogramOptions const &options)
int floor(FixedPoint< IntBits, FracBits > v)
rounding down.
Definition: fixedpoint.hxx:667
Basic statistic. Minimum value.
Definition: accumulator.hxx:5122
Create a dynamic accumulator chain containing the selected statistics and their dependencies.
Definition: accumulator.hxx:2151
Compute the circularity of a 2D region.
Definition: accumulator.hxx:6199
Modifier. Compute statistic from pixel coordinates rather than from pixel values. ...
Definition: accumulator-grammar.hxx:142
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616
Create an array of accumulator chains containing the selected per-region and global statistics and th...
Definition: accumulator.hxx:2373
Set histogram options.
Definition: histogram.hxx:49