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"
57 #include "polytope.hxx"
59 #include "functorexpression.hxx"
60 #include "labelimage.hxx"
61 #include "multi_labeling.hxx"
394 template <
class T01=void,
class T02=void,
class T03=void,
class T04=void,
class T05=void,
395 class T06=void,
class T07=void,
class T08=void,
class T09=void,
class T10=void,
396 class T11=void,
class T12=void,
class T13=void,
class T14=void,
class T15=void,
397 class T16=void,
class T17=void,
class T18=void,
class T19=void,
class T20=
void>
399 :
public MakeTypeList<
400 typename StandardizeTag<T01>::type, typename StandardizeTag<T02>::type, typename StandardizeTag<T03>::type,
401 typename StandardizeTag<T04>::type, typename StandardizeTag<T05>::type, typename StandardizeTag<T06>::type,
402 typename StandardizeTag<T07>::type, typename StandardizeTag<T08>::type, typename StandardizeTag<T09>::type,
403 typename StandardizeTag<T10>::type, typename StandardizeTag<T11>::type, typename StandardizeTag<T12>::type,
404 typename StandardizeTag<T13>::type, typename StandardizeTag<T14>::type, typename StandardizeTag<T15>::type,
405 typename StandardizeTag<T16>::type, typename StandardizeTag<T17>::type, typename StandardizeTag<T18>::type,
406 typename StandardizeTag<T19>::type, typename StandardizeTag<T20>::type
411 template <
class T01,
class T02,
class T03,
class T04,
class T05,
412 class T06,
class T07,
class T08,
class T09,
class T10,
413 class T11,
class T12,
class T13,
class T14,
class T15,
414 class T16,
class T17,
class T18,
class T19,
class T20>
415 struct StandardizeTag<
Select<T01, T02, T03, T04, T05,
416 T06, T07, T08, T09, T10,
417 T11, T12, T13, T14, T15,
418 T16, T17, T18, T19, T20>,
419 Select<T01, T02, T03, T04, T05,
420 T06, T07, T08, T09, T10,
421 T11, T12, T13, T14, T15,
422 T16, T17, T18, T19, T20> >
424 typedef typename Select<T01, T02, T03, T04, T05,
425 T06, T07, T08, T09, T10,
426 T11, T12, T13, T14, T15,
427 T16, T17, T18, T19, T20>::type type;
430 struct AccumulatorBegin
432 typedef Select<> Dependencies;
434 static std::string name()
436 return "AccumulatorBegin (internal)";
441 template <
class T,
class BASE>
448 struct AccumulatorEnd;
453 struct LabelDispatchTag;
455 template <
class T,
class TAG,
class CHAIN>
456 struct HandleArgSelector;
458 struct Error__Global_statistics_are_only_defined_for_AccumulatorChainArray;
470 static std::string name()
472 return std::string(
"LabelArg<") +
asString(INDEX) +
"> (internal)";
477 template <
class T,
class BASE>
481 typedef LabelArgTag Tag;
482 typedef void value_type;
483 typedef void result_type;
485 static const int value = INDEX;
486 static const unsigned int workInPass = 0;
496 static std::string name()
498 return std::string(
"CoordArg<") +
asString(INDEX) +
"> (internal)";
503 template <
class T,
class BASE>
507 typedef CoordArgTag Tag;
508 typedef void value_type;
509 typedef void result_type;
511 static const int value = INDEX;
512 static const unsigned int workInPass = 0;
516 template <
class T,
class TAG,
class NEXT=AccumulatorEnd>
517 struct AccumulatorBase;
519 template <
class Tag,
class A>
522 template <
class Tag,
class A,
class TargetTag=
typename A::Tag>
523 struct LookupDependency;
527 template <
class TAG,
class A>
528 typename LookupTag<TAG, A>::reference
531 template <
class TAG,
class A>
532 typename LookupDependency<TAG, A>::result_type
533 getDependency(A
const & a);
537 namespace acc_detail {
548 struct PushArgTagToTail
553 #define VIGRA_PUSHARGTAG(TAG) \
554 template <int INDEX, class TAIL> \
555 struct PushArgTagToTail<TypeList<TAG<INDEX>, TAIL> > \
557 typedef typename Push<TAIL, TypeList<TAG<INDEX> > >::type type; \
560 VIGRA_PUSHARGTAG(DataArg)
561 VIGRA_PUSHARGTAG(WeightArg)
562 VIGRA_PUSHARGTAG(CoordArg)
563 VIGRA_PUSHARGTAG(LabelArg)
565 #undef VIGRA_PUSHARGTAG
571 struct AddDependencies;
573 template <
class HEAD,
class TAIL>
574 struct AddDependencies<TypeList<HEAD, TAIL> >
576 typedef typename AddDependencies<TAIL>::type TailWithDependencies;
577 typedef typename StandardizeDependencies<HEAD>::type HeadDependencies;
578 typedef typename AddDependencies<HeadDependencies>::type TransitiveHeadDependencies;
579 typedef TypeList<HEAD, TransitiveHeadDependencies> HeadWithDependencies;
580 typedef typename PushUnique<HeadWithDependencies, TailWithDependencies>::type UnsortedDependencies;
581 typedef typename PushArgTagToTail<UnsortedDependencies>::type type;
585 struct AddDependencies<void>
592 template <
class Dependencies>
593 struct ActivateDependencies;
595 template <
class HEAD,
class TAIL>
596 struct ActivateDependencies<TypeList<HEAD, TAIL> >
598 template <
class Chain,
class ActiveFlags>
599 static void exec(ActiveFlags & flags)
601 LookupTag<HEAD, Chain>::type::activateImpl(flags);
602 ActivateDependencies<TAIL>::template exec<Chain>(flags);
605 template <
class Chain,
class ActiveFlags,
class GlobalFlags>
606 static void exec(ActiveFlags & flags, GlobalFlags & gflags)
608 LookupTag<HEAD, Chain>::type::template activateImpl<Chain>(flags, gflags);
609 ActivateDependencies<TAIL>::template exec<Chain>(flags, gflags);
613 template <
class HEAD,
class TAIL>
614 struct ActivateDependencies<TypeList<Global<HEAD>, TAIL> >
616 template <
class Chain,
class ActiveFlags,
class GlobalFlags>
617 static void exec(ActiveFlags & flags, GlobalFlags & gflags)
619 LookupTag<Global<HEAD>, Chain>::type::activateImpl(gflags);
620 ActivateDependencies<TAIL>::template exec<Chain>(flags, gflags);
625 struct ActivateDependencies<void>
627 template <
class Chain,
class ActiveFlags>
628 static void exec(ActiveFlags &)
631 template <
class Chain,
class ActiveFlags,
class GlobalFlags>
632 static void exec(ActiveFlags &, GlobalFlags &)
636 template <
class List>
637 struct SeparateGlobalAndRegionTags;
639 template <
class HEAD,
class TAIL>
640 struct SeparateGlobalAndRegionTags<TypeList<HEAD, TAIL> >
642 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
643 typedef TypeList<HEAD, typename Inner::RegionTags> RegionTags;
644 typedef typename Inner::GlobalTags GlobalTags;
647 template <
class HEAD,
class TAIL>
648 struct SeparateGlobalAndRegionTags<TypeList<Global<HEAD>, TAIL> >
650 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
651 typedef typename Inner::RegionTags RegionTags;
652 typedef TypeList<HEAD, typename Inner::GlobalTags> GlobalTags;
655 template <
int INDEX,
class TAIL>
656 struct SeparateGlobalAndRegionTags<TypeList<DataArg<INDEX>, TAIL> >
658 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
659 typedef TypeList<DataArg<INDEX>,
typename Inner::RegionTags> RegionTags;
660 typedef TypeList<DataArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
663 template <
int INDEX,
class TAIL>
664 struct SeparateGlobalAndRegionTags<TypeList<LabelArg<INDEX>, TAIL> >
666 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
667 typedef TypeList<LabelArg<INDEX>,
typename Inner::RegionTags> RegionTags;
668 typedef TypeList<LabelArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
671 template <
int INDEX,
class TAIL>
672 struct SeparateGlobalAndRegionTags<TypeList<WeightArg<INDEX>, TAIL> >
674 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
675 typedef TypeList<WeightArg<INDEX>,
typename Inner::RegionTags> RegionTags;
676 typedef TypeList<WeightArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
679 template <
int INDEX,
class TAIL>
680 struct SeparateGlobalAndRegionTags<TypeList<CoordArg<INDEX>, TAIL> >
682 typedef SeparateGlobalAndRegionTags<TAIL> Inner;
683 typedef TypeList<CoordArg<INDEX>,
typename Inner::RegionTags> RegionTags;
684 typedef TypeList<CoordArg<INDEX>,
typename Inner::GlobalTags> GlobalTags;
688 struct SeparateGlobalAndRegionTags<void>
690 typedef void RegionTags;
691 typedef void GlobalTags;
700 template <
class Accumulators>
701 struct CollectAccumulatorNames;
703 template <
class HEAD,
class TAIL>
704 struct CollectAccumulatorNames<TypeList<HEAD, TAIL> >
706 template <
class BackInsertable>
707 static void exec(BackInsertable & a,
bool skipInternals=
true)
709 if(!skipInternals || HEAD::name().find(
"internal") == std::string::npos)
710 a.push_back(HEAD::name());
711 CollectAccumulatorNames<TAIL>::exec(a, skipInternals);
716 struct CollectAccumulatorNames<void>
718 template <
class BackInsertable>
719 static void exec(BackInsertable &,
bool =
true)
724 struct ApplyVisitorToTag;
726 template <
class HEAD,
class TAIL>
727 struct ApplyVisitorToTag<TypeList<HEAD, TAIL> >
729 template <
class Accu,
class Visitor>
730 static bool exec(Accu & a, std::string
const & tag, Visitor
const & v)
732 static std::string * name = VIGRA_SAFE_STATIC(name,
new std::string(
normalizeString(HEAD::name())));
735 v.template exec<HEAD>(a);
740 return ApplyVisitorToTag<TAIL>::exec(a, tag, v);
746 struct ApplyVisitorToTag<void>
748 template <
class Accu,
class Visitor>
749 static bool exec(Accu &, std::string
const &, Visitor
const &)
755 struct ActivateTag_Visitor
757 template <
class TAG,
class Accu>
758 void exec(Accu & a)
const
760 a.template activate<TAG>();
764 struct TagIsActive_Visitor
768 template <
class TAG,
class Accu>
769 void exec(Accu & a)
const
771 result = a.template isActive<TAG>();
782 struct SetHistogramBincount
784 template <
class Accu>
785 static void exec(Accu &, HistogramOptions
const &)
789 template <
template <
int>
class Histogram>
790 struct SetHistogramBincount<Histogram<0> >
792 template <
class Accu>
793 static void exec(Accu & a, HistogramOptions
const & options)
795 a.setBinCount(options.binCount);
800 struct ApplyHistogramOptions
802 template <
class Accu>
803 static void exec(Accu &, HistogramOptions
const &)
808 struct ApplyHistogramOptions<StandardQuantiles<TAG> >
810 template <
class Accu>
811 static void exec(Accu &, HistogramOptions
const &)
815 template <
class TAG,
template <
class>
class MODIFIER>
816 struct ApplyHistogramOptions<MODIFIER<TAG> >
817 :
public ApplyHistogramOptions<TAG>
821 struct ApplyHistogramOptions<IntegerHistogram<0> >
823 template <
class Accu>
824 static void exec(Accu & a, HistogramOptions
const & options)
826 SetHistogramBincount<IntegerHistogram<0> >::exec(a, options);
830 template <
int BinCount>
831 struct ApplyHistogramOptions<UserRangeHistogram<BinCount> >
833 template <
class Accu>
834 static void exec(Accu & a, HistogramOptions
const & options)
836 SetHistogramBincount<UserRangeHistogram<BinCount> >::exec(a, options);
837 if(a.scale_ == 0.0 && options.validMinMax())
838 a.setMinMax(options.minimum, options.maximum);
842 template <
int BinCount>
843 struct ApplyHistogramOptions<AutoRangeHistogram<BinCount> >
845 template <
class Accu>
846 static void exec(Accu & a, HistogramOptions
const & options)
848 SetHistogramBincount<AutoRangeHistogram<BinCount> >::exec(a, options);
849 if(a.scale_ == 0.0 && options.validMinMax())
850 a.setMinMax(options.minimum, options.maximum);
854 template <
int BinCount>
855 struct ApplyHistogramOptions<GlobalRangeHistogram<BinCount> >
857 template <
class Accu>
858 static void exec(Accu & a, HistogramOptions
const & options)
860 SetHistogramBincount<GlobalRangeHistogram<BinCount> >::exec(a, options);
863 if(options.validMinMax())
864 a.setMinMax(options.minimum, options.maximum);
866 a.setRegionAutoInit(options.local_auto_init);
883 template <
unsigned LEVEL,
class GlobalAccumulatorHandle>
884 struct AccumulatorEndImpl
886 typedef typename GlobalAccumulatorHandle::type GlobalAccumulatorType;
888 typedef AccumulatorEnd Tag;
889 typedef void value_type;
890 typedef bool result_type;
891 typedef BitArray<LEVEL> AccumulatorFlags;
893 static const unsigned int workInPass = 0;
894 static const int index = -1;
895 static const unsigned level = LEVEL;
897 AccumulatorFlags active_accumulators_;
898 mutable AccumulatorFlags is_dirty_;
899 GlobalAccumulatorHandle globalAccumulator_;
901 template <
class GlobalAccumulator>
902 void setGlobalAccumulator(GlobalAccumulator
const * a)
904 globalAccumulator_.pointer_ = a;
907 static std::string name()
909 return "AccumulatorEnd (internal)";
912 bool operator()()
const {
return false; }
913 bool get()
const {
return false; }
915 template <
unsigned,
class U>
919 template <
unsigned,
class U>
920 void pass(U
const &,
double)
924 void mergeImpl(U
const &)
928 void resize(U
const &)
932 void setCoordinateOffsetImpl(U
const &)
943 template <
class Flags>
944 static void activateImpl(Flags &)
947 template <
class Accu,
class Flags1,
class Flags2>
948 static void activateImpl(Flags1 &, Flags2 &)
951 template <
class Flags>
952 static bool isActiveImpl(Flags
const &)
957 void applyHistogramOptions(HistogramOptions
const &)
960 static unsigned int passesRequired()
965 static unsigned int passesRequired(AccumulatorFlags
const &)
972 active_accumulators_.clear();
977 void setDirtyImpl()
const
979 is_dirty_.template set<which>();
983 void setCleanImpl()
const
985 is_dirty_.template reset<which>();
989 bool isDirtyImpl()
const
991 return is_dirty_.template test<which>();
996 template <
class A,
unsigned CurrentPass,
bool allowRuntimeActivation,
unsigned WorkPass=A::workInPass>
1000 static void exec(A &, T
const &)
1004 static void exec(A &, T
const &,
double)
1008 template <
class A,
unsigned CurrentPass>
1009 struct DecoratorImpl<A, CurrentPass, false, CurrentPass>
1012 static void exec(A & a, T
const & t)
1018 static void exec(A & a, T
const & t,
double weight)
1020 a.update(t, weight);
1023 static typename A::result_type
get(A
const & a)
1028 static void mergeImpl(A & a, A
const & o)
1034 static void resize(A & a, T
const & t)
1039 static void applyHistogramOptions(A & a, HistogramOptions
const & options)
1041 ApplyHistogramOptions<typename A::Tag>::exec(a, options);
1044 static unsigned int passesRequired()
1046 static const unsigned int A_workInPass = A::workInPass;
1047 return std::max(A_workInPass, A::InternalBaseType::passesRequired());
1051 template <
class A,
unsigned CurrentPass>
1052 struct DecoratorImpl<A, CurrentPass, true, CurrentPass>
1056 return A::isActiveImpl(getAccumulator<AccumulatorEnd>(a).active_accumulators_);
1060 static void exec(A & a, T
const & t)
1067 static void exec(A & a, T
const & t,
double weight)
1070 a.update(t, weight);
1073 static typename A::result_type
get(A
const & a)
1077 std::string message = std::string(
"get(accumulator): attempt to access inactive statistic '") +
1078 A::Tag::name() +
"'.";
1079 vigra_precondition(
false, message);
1084 static void mergeImpl(A & a, A
const & o)
1091 static void resize(A & a, T
const & t)
1097 static void applyHistogramOptions(A & a, HistogramOptions
const & options)
1100 ApplyHistogramOptions<typename A::Tag>::exec(a, options);
1103 template <
class ActiveFlags>
1104 static unsigned int passesRequired(ActiveFlags
const & flags)
1106 static const unsigned int A_workInPass = A::workInPass;
1107 return A::isActiveImpl(flags)
1108 ? std::max(A_workInPass, A::InternalBaseType::passesRequired(flags))
1109 : A::InternalBaseType::passesRequired(flags);
1115 template <
class T,
class Shape>
1116 void reshapeImpl(T &, Shape
const &)
1119 template <
class T,
class Shape,
class Initial>
1120 void reshapeImpl(T &, Shape
const &, Initial
const & = T())
1123 template <
unsigned int N,
class T,
class Alloc,
class Shape>
1124 void reshapeImpl(MultiArray<N, T, Alloc> & a, Shape
const & s, T
const & initial = T())
1126 MultiArray<N, T, Alloc>(s, initial).swap(a);
1129 template <
class T,
class Alloc,
class Shape>
1130 void reshapeImpl(Matrix<T, Alloc> & a, Shape
const & s, T
const & initial = T())
1132 Matrix<T, Alloc>(s, initial).swap(a);
1135 template <
class T,
class U>
1136 void copyShapeImpl(T
const &, U
const &)
1139 template <
unsigned int N,
class T,
class Alloc,
class U>
1140 void copyShapeImpl(MultiArray<N, T, Alloc>
const & from, U & to)
1142 to.reshape(from.shape());
1145 template <
class T,
class Alloc,
class U>
1146 void copyShapeImpl(Matrix<T, Alloc>
const & from, U & to)
1148 to.reshape(from.shape());
1151 template <
class T,
class U>
1152 bool hasDataImpl(T
const &)
1157 template <
unsigned int N,
class T,
class Str
ide>
1158 bool hasDataImpl(MultiArrayView<N, T, Stride>
const & a)
1164 template <
unsigned int N,
class T,
class Str
ide>
1166 shapeOf(MultiArrayView<N, T, Stride>
const & a)
1171 template <
class T,
int N>
1173 shapeOf(TinyVector<T, N>
const &)
1178 template <
class T,
class NEXT>
1179 inline CoupledHandle<T, NEXT>
const &
1180 shapeOf(CoupledHandle<T, NEXT>
const & t)
1185 #define VIGRA_SHAPE_OF(type) \
1192 VIGRA_SHAPE_OF(
unsigned char)
1193 VIGRA_SHAPE_OF(
signed char)
1194 VIGRA_SHAPE_OF(
unsigned short)
1195 VIGRA_SHAPE_OF(
short)
1196 VIGRA_SHAPE_OF(
unsigned int)
1198 VIGRA_SHAPE_OF(
unsigned long)
1199 VIGRA_SHAPE_OF(
long)
1200 VIGRA_SHAPE_OF(
unsigned long long)
1201 VIGRA_SHAPE_OF(
long long)
1202 VIGRA_SHAPE_OF(
float)
1203 VIGRA_SHAPE_OF(
double)
1204 VIGRA_SHAPE_OF(
long double)
1206 #undef VIGRA_SHAPE_OF
1215 template <
class T,
class GlobalAccumulators,
class RegionAccumulators>
1216 struct LabelDispatch
1218 typedef LabelDispatchTag Tag;
1219 typedef GlobalAccumulators GlobalAccumulatorChain;
1220 typedef RegionAccumulators RegionAccumulatorChain;
1221 typedef typename LookupTag<AccumulatorEnd, RegionAccumulatorChain>::type::AccumulatorFlags ActiveFlagsType;
1222 typedef ArrayVector<RegionAccumulatorChain> RegionAccumulatorArray;
1224 typedef LabelDispatch type;
1225 typedef LabelDispatch & reference;
1226 typedef LabelDispatch
const & const_reference;
1227 typedef GlobalAccumulatorChain InternalBaseType;
1229 typedef T
const & argument_type;
1230 typedef argument_type first_argument_type;
1231 typedef double second_argument_type;
1232 typedef RegionAccumulatorChain & result_type;
1234 static const int index = GlobalAccumulatorChain::index + 1;
1236 template <
class IndexDefinition,
class TagFound=
typename IndexDefinition::Tag>
1237 struct CoordIndexSelector
1239 static const int value = 0;
1242 template <
class IndexDefinition>
1243 struct CoordIndexSelector<IndexDefinition, CoordArgTag>
1245 static const int value = IndexDefinition::value;
1248 static const int coordIndex = CoordIndexSelector<typename LookupTag<CoordArgTag, GlobalAccumulatorChain>::type>::value;
1249 static const int coordSize = CoupledHandleCast<coordIndex, T>::type::value_type::static_size;
1250 typedef TinyVector<double, coordSize> CoordinateType;
1252 GlobalAccumulatorChain next_;
1253 RegionAccumulatorArray regions_;
1254 HistogramOptions region_histogram_options_;
1256 ActiveFlagsType active_region_accumulators_;
1257 CoordinateType coordinateOffset_;
1259 template <
class TAG>
1262 typedef typename LookupTag<TAG, type>::type TargetAccumulator;
1264 static void activate(GlobalAccumulatorChain & globals, RegionAccumulatorArray & regions,
1265 ActiveFlagsType & flags)
1267 TargetAccumulator::template activateImpl<LabelDispatch>(
1268 flags, getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
1269 for(
unsigned int k=0; k<regions.size(); ++k)
1270 getAccumulator<AccumulatorEnd>(regions[k]).active_accumulators_ = flags;
1273 static bool isActive(GlobalAccumulatorChain
const &, ActiveFlagsType
const & flags)
1275 return TargetAccumulator::isActiveImpl(flags);
1279 template <
class TAG>
1280 struct ActivateImpl<Global<TAG> >
1282 static void activate(GlobalAccumulatorChain & globals, RegionAccumulatorArray &, ActiveFlagsType &)
1284 LookupTag<TAG, GlobalAccumulatorChain>::type::activateImpl(getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
1287 static bool isActive(GlobalAccumulatorChain
const & globals, ActiveFlagsType
const &)
1289 return LookupTag<TAG, GlobalAccumulatorChain>::type::isActiveImpl(getAccumulator<AccumulatorEnd>(globals).active_accumulators_);
1293 template <
int INDEX>
1294 struct ActivateImpl<LabelArg<INDEX> >
1296 static void activate(GlobalAccumulatorChain &, RegionAccumulatorArray &, ActiveFlagsType &)
1299 static bool isActive(GlobalAccumulatorChain
const & globals, ActiveFlagsType
const &)
1301 return getAccumulator<LabelArg<INDEX> >(globals).
isActive();
1308 region_histogram_options_(),
1310 active_region_accumulators_()
1313 LabelDispatch(LabelDispatch
const & o)
1315 regions_(o.regions_),
1316 region_histogram_options_(o.region_histogram_options_),
1317 ignore_label_(o.ignore_label_),
1318 active_region_accumulators_(o.active_region_accumulators_)
1320 for(
unsigned int k=0; k<regions_.size(); ++k)
1322 getAccumulator<AccumulatorEnd>(regions_[k]).setGlobalAccumulator(&next_);
1331 void setMaxRegionLabel(
unsigned maxlabel)
1335 unsigned int oldSize = regions_.size();
1336 regions_.resize(maxlabel + 1);
1337 for(
unsigned int k=oldSize; k<regions_.size(); ++k)
1339 getAccumulator<AccumulatorEnd>(regions_[k]).setGlobalAccumulator(&next_);
1340 getAccumulator<AccumulatorEnd>(regions_[k]).active_accumulators_ = active_region_accumulators_;
1341 regions_[k].applyHistogramOptions(region_histogram_options_);
1342 regions_[k].setCoordinateOffsetImpl(coordinateOffset_);
1353 return ignore_label_;
1356 void applyHistogramOptions(HistogramOptions
const & options)
1358 applyHistogramOptions(options, options);
1361 void applyHistogramOptions(HistogramOptions
const & regionoptions,
1362 HistogramOptions
const & globaloptions)
1364 region_histogram_options_ = regionoptions;
1365 for(
unsigned int k=0; k<regions_.size(); ++k)
1367 regions_[k].applyHistogramOptions(region_histogram_options_);
1369 next_.applyHistogramOptions(globaloptions);
1372 void setCoordinateOffsetImpl(CoordinateType
const & offset)
1374 coordinateOffset_ = offset;
1375 for(
unsigned int k=0; k<regions_.size(); ++k)
1377 regions_[k].setCoordinateOffsetImpl(coordinateOffset_);
1379 next_.setCoordinateOffsetImpl(coordinateOffset_);
1382 void setCoordinateOffsetImpl(
MultiArrayIndex k, CoordinateType
const & offset)
1385 "Accumulator::setCoordinateOffset(k, offset): region k does not exist.");
1386 regions_[k].setCoordinateOffsetImpl(offset);
1390 void resize(U
const & t)
1392 if(regions_.size() == 0)
1394 typedef HandleArgSelector<U, LabelArgTag, GlobalAccumulatorChain> LabelHandle;
1395 typedef typename LabelHandle::value_type LabelType;
1396 typedef MultiArrayView<LabelHandle::size, LabelType, StridedArrayTag> LabelArray;
1397 LabelArray labelArray(t.shape(), LabelHandle::getHandle(t).strides(),
1398 const_cast<LabelType *
>(LabelHandle::getHandle(t).ptr()));
1400 LabelType minimum, maximum;
1401 labelArray.minmax(&minimum, &maximum);
1402 setMaxRegionLabel(maximum);
1406 for(
unsigned int k=0; k<regions_.size(); ++k)
1407 regions_[k].resize(t);
1410 template <
unsigned N>
1411 void pass(T
const & t)
1413 typedef HandleArgSelector<T, LabelArgTag, GlobalAccumulatorChain> LabelHandle;
1414 if(LabelHandle::getValue(t) != ignore_label_)
1416 next_.template pass<N>(t);
1417 regions_[LabelHandle::getValue(t)].template pass<N>(t);
1421 template <
unsigned N>
1422 void pass(T
const & t,
double weight)
1424 typedef HandleArgSelector<T, LabelArgTag, GlobalAccumulatorChain> LabelHandle;
1425 if(LabelHandle::getValue(t) != ignore_label_)
1427 next_.template pass<N>(t, weight);
1428 regions_[LabelHandle::getValue(t)].template pass<N>(t, weight);
1432 static unsigned int passesRequired()
1434 return std::max(GlobalAccumulatorChain::passesRequired(), RegionAccumulatorChain::passesRequired());
1437 unsigned int passesRequiredDynamic()
const
1439 return std::max(GlobalAccumulatorChain::passesRequired(getAccumulator<AccumulatorEnd>(next_).active_accumulators_),
1440 RegionAccumulatorChain::passesRequired(active_region_accumulators_));
1447 active_region_accumulators_.clear();
1448 RegionAccumulatorArray().swap(regions_);
1454 template <
class TAG>
1457 ActivateImpl<TAG>::activate(next_, regions_, active_region_accumulators_);
1462 getAccumulator<AccumulatorEnd>(next_).active_accumulators_.set();
1463 active_region_accumulators_.set();
1464 for(
unsigned int k=0; k<regions_.size(); ++k)
1465 getAccumulator<AccumulatorEnd>(regions_[k]).active_accumulators_.set();
1468 template <
class TAG>
1471 return ActivateImpl<TAG>::isActive(next_, active_region_accumulators_);
1474 void mergeImpl(LabelDispatch
const & o)
1476 for(
unsigned int k=0; k<regions_.size(); ++k)
1477 regions_[k].mergeImpl(o.regions_[k]);
1478 next_.mergeImpl(o.next_);
1481 void mergeImpl(
unsigned i,
unsigned j)
1483 regions_[i].mergeImpl(regions_[j]);
1484 regions_[j].reset();
1485 getAccumulator<AccumulatorEnd>(regions_[j]).active_accumulators_ = active_region_accumulators_;
1488 template <
class ArrayLike>
1489 void mergeImpl(LabelDispatch
const & o, ArrayLike
const & labelMapping)
1491 MultiArrayIndex newMaxLabel = std::max<MultiArrayIndex>(maxRegionLabel(), *
argMax(labelMapping.begin(), labelMapping.end()));
1492 setMaxRegionLabel(newMaxLabel);
1493 for(
unsigned int k=0; k<labelMapping.size(); ++k)
1494 regions_[labelMapping[k]].mergeImpl(o.regions_[k]);
1495 next_.mergeImpl(o.next_);
1499 template <
class TargetTag,
class TagList>
1502 template <
class TargetTag,
class HEAD,
class TAIL>
1503 struct FindNextTag<TargetTag, TypeList<HEAD, TAIL> >
1505 typedef typename FindNextTag<TargetTag, TAIL>::type type;
1508 template <
class TargetTag,
class TAIL>
1509 struct FindNextTag<TargetTag, TypeList<TargetTag, TAIL> >
1511 typedef typename TAIL::Head type;
1514 template <
class TargetTag>
1515 struct FindNextTag<TargetTag, TypeList<TargetTag, void> >
1520 template <
class TargetTag>
1521 struct FindNextTag<TargetTag, void>
1527 template <
class TAG,
class CONFIG,
unsigned LEVEL=0>
1528 struct AccumulatorFactory
1530 typedef typename FindNextTag<TAG, typename CONFIG::TagList>::type NextTag;
1531 typedef typename AccumulatorFactory<NextTag, CONFIG, LEVEL+1>::type NextType;
1532 typedef typename CONFIG::InputType InputType;
1543 template <
class T,
class NEXT>
1544 struct ConfigureTag<CoupledHandle<T, NEXT> >
1546 typedef typename StandardizeTag<DataFromHandle<TAG> >::type WrappedTag;
1547 typedef typename IfBool<(!HasModifierPriority<WrappedTag, WeightingPriority>::value && ShouldBeWeighted<WrappedTag>::value),
1548 Weighted<WrappedTag>, WrappedTag>::type type;
1551 typedef typename ConfigureTag<InputType>::type UseTag;
1555 struct AccumulatorBase
1557 typedef AccumulatorBase ThisType;
1559 typedef NextType InternalBaseType;
1560 typedef InputType input_type;
1561 typedef input_type
const & argument_type;
1562 typedef argument_type first_argument_type;
1563 typedef double second_argument_type;
1564 typedef void result_type;
1566 static const unsigned int workInPass = 1;
1567 static const int index = InternalBaseType::index + 1;
1569 InternalBaseType next_;
1571 static std::string name()
1576 template <
class ActiveFlags>
1577 static void activateImpl(ActiveFlags & flags)
1579 flags.template set<index>();
1580 typedef typename StandardizeDependencies<Tag>::type StdDeps;
1581 acc_detail::ActivateDependencies<StdDeps>::template exec<ThisType>(flags);
1584 template <
class Accu,
class ActiveFlags,
class GlobalFlags>
1585 static void activateImpl(ActiveFlags & flags, GlobalFlags & gflags)
1587 flags.template set<index>();
1588 typedef typename StandardizeDependencies<Tag>::type StdDeps;
1589 acc_detail::ActivateDependencies<StdDeps>::template exec<Accu>(flags, gflags);
1592 template <
class ActiveFlags>
1593 static bool isActiveImpl(ActiveFlags & flags)
1595 return flags.template test<index>();
1598 void setDirty()
const
1600 next_.template setDirtyImpl<index>();
1603 template <
int INDEX>
1604 void setDirtyImpl()
const
1606 next_.template setDirtyImpl<INDEX>();
1609 void setClean()
const
1611 next_.template setCleanImpl<index>();
1614 template <
int INDEX>
1615 void setCleanImpl()
const
1617 next_.template setCleanImpl<INDEX>();
1620 bool isDirty()
const
1622 return next_.template isDirtyImpl<index>();
1625 template <
int INDEX>
1626 bool isDirtyImpl()
const
1628 return next_.template isDirtyImpl<INDEX>();
1634 template <
class Shape>
1635 void setCoordinateOffset(Shape
const &)
1638 template <
class Shape>
1639 void reshape(Shape
const &)
1646 void update(U
const &)
1650 void update(U
const &,
double)
1653 template <
class TargetTag>
1654 typename LookupDependency<TargetTag, ThisType>::result_type
1655 call_getDependency()
const
1657 return getDependency<TargetTag>(*
this);
1662 typedef typename UseTag::template Impl<InputType, AccumulatorBase> AccumulatorImpl;
1669 :
public AccumulatorImpl
1671 typedef Accumulator type;
1672 typedef Accumulator & reference;
1673 typedef Accumulator
const & const_reference;
1674 typedef AccumulatorImpl A;
1676 static const unsigned int workInPass = A::workInPass;
1677 static const bool allowRuntimeActivation = CONFIG::allowRuntimeActivation;
1680 void resize(T
const & t)
1682 this->next_.resize(t);
1683 DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::resize(*
this, t);
1688 this->next_.reset();
1692 typename A::result_type
get()
const
1694 return DecoratorImpl<A, workInPass, allowRuntimeActivation>::get(*
this);
1697 template <
unsigned N,
class T>
1698 void pass(T
const & t)
1700 this->next_.template pass<N>(t);
1701 DecoratorImpl<Accumulator, N, allowRuntimeActivation>::exec(*
this, t);
1704 template <
unsigned N,
class T>
1705 void pass(T
const & t,
double weight)
1707 this->next_.template pass<N>(t, weight);
1708 DecoratorImpl<Accumulator, N, allowRuntimeActivation>::exec(*
this, t, weight);
1711 void mergeImpl(Accumulator
const & o)
1713 DecoratorImpl<Accumulator, Accumulator::workInPass, allowRuntimeActivation>::mergeImpl(*
this, o);
1714 this->next_.mergeImpl(o.next_);
1717 void applyHistogramOptions(HistogramOptions
const & options)
1719 DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::applyHistogramOptions(*
this, options);
1720 this->next_.applyHistogramOptions(options);
1723 template <
class SHAPE>
1724 void setCoordinateOffsetImpl(SHAPE
const & offset)
1726 this->setCoordinateOffset(offset);
1727 this->next_.setCoordinateOffsetImpl(offset);
1730 static unsigned int passesRequired()
1732 return DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::passesRequired();
1735 template <
class ActiveFlags>
1736 static unsigned int passesRequired(ActiveFlags
const & flags)
1738 return DecoratorImpl<Accumulator, workInPass, allowRuntimeActivation>::passesRequired(flags);
1742 typedef Accumulator type;
1745 template <
class CONFIG,
unsigned LEVEL>
1746 struct AccumulatorFactory<void, CONFIG, LEVEL>
1748 typedef AccumulatorEndImpl<LEVEL, typename CONFIG::GlobalAccumulatorHandle> type;
1751 struct InvalidGlobalAccumulatorHandle
1753 typedef Error__Global_statistics_are_only_defined_for_AccumulatorChainArray type;
1755 InvalidGlobalAccumulatorHandle()
1759 type
const * pointer_;
1765 template <
class T,
class Selected,
bool dynamic=false,
class GlobalHandle=Inval
idGlobalAccumulatorHandle>
1766 struct ConfigureAccumulatorChain
1768 :
public ConfigureAccumulatorChain<T, typename AddDependencies<typename Selected::type>::type, dynamic>
1772 template <
class T,
class HEAD,
class TAIL,
bool dynamic,
class GlobalHandle>
1773 struct ConfigureAccumulatorChain<T, TypeList<HEAD, TAIL>, dynamic, GlobalHandle>
1775 typedef TypeList<HEAD, TAIL> TagList;
1776 typedef T InputType;
1777 static const bool allowRuntimeActivation = dynamic;
1778 typedef GlobalHandle GlobalAccumulatorHandle;
1780 typedef typename AccumulatorFactory<HEAD, ConfigureAccumulatorChain>::type type;
1783 template <
class T,
class Selected,
bool dynamic=false>
1784 struct ConfigureAccumulatorChainArray
1786 :
public ConfigureAccumulatorChainArray<T, typename AddDependencies<typename Selected::type>::type, dynamic>
1790 template <
class T,
class HEAD,
class TAIL,
bool dynamic>
1791 struct ConfigureAccumulatorChainArray<T, TypeList<HEAD, TAIL>, dynamic>
1793 typedef TypeList<HEAD, TAIL> TagList;
1794 typedef SeparateGlobalAndRegionTags<TagList> TagSeparator;
1795 typedef typename TagSeparator::GlobalTags GlobalTags;
1796 typedef typename TagSeparator::RegionTags RegionTags;
1797 typedef typename ConfigureAccumulatorChain<T, GlobalTags, dynamic>::type GlobalAccumulatorChain;
1799 struct GlobalAccumulatorHandle
1801 typedef GlobalAccumulatorChain type;
1803 GlobalAccumulatorHandle()
1807 type
const * pointer_;
1810 typedef typename ConfigureAccumulatorChain<T, RegionTags, dynamic, GlobalAccumulatorHandle>::type RegionAccumulatorChain;
1812 typedef LabelDispatch<T, GlobalAccumulatorChain, RegionAccumulatorChain> type;
1824 template <
class T,
class NEXT>
1825 class AccumulatorChainImpl
1828 typedef NEXT InternalBaseType;
1829 typedef AccumulatorBegin Tag;
1830 typedef typename InternalBaseType::argument_type argument_type;
1831 typedef typename InternalBaseType::first_argument_type first_argument_type;
1832 typedef typename InternalBaseType::second_argument_type second_argument_type;
1833 typedef void value_type;
1834 typedef typename InternalBaseType::result_type result_type;
1836 static const int staticSize = InternalBaseType::index;
1838 InternalBaseType next_;
1842 unsigned int current_pass_;
1844 AccumulatorChainImpl()
1850 void setHistogramOptions(HistogramOptions
const & options)
1852 next_.applyHistogramOptions(options);
1858 void setHistogramOptions(HistogramOptions
const & regionoptions, HistogramOptions
const & globaloptions)
1860 next_.applyHistogramOptions(regionoptions, globaloptions);
1869 template <
class SHAPE>
1870 void setCoordinateOffset(SHAPE
const & offset)
1872 next_.setCoordinateOffsetImpl(offset);
1877 void reset(
unsigned int reset_to_pass = 0)
1879 current_pass_ = reset_to_pass;
1880 if(reset_to_pass == 0)
1884 template <
unsigned N>
1885 void update(T
const & t)
1887 if(current_pass_ == N)
1889 next_.template pass<N>(t);
1891 else if(current_pass_ < N)
1895 next_.resize(acc_detail::shapeOf(t));
1896 next_.template pass<N>(t);
1900 std::string message(
"AccumulatorChain::update(): cannot return to pass ");
1901 message << N <<
" after working on pass " << current_pass_ <<
".";
1902 vigra_precondition(
false, message);
1906 template <
unsigned N>
1907 void update(T
const & t,
double weight)
1909 if(current_pass_ == N)
1911 next_.template pass<N>(t, weight);
1913 else if(current_pass_ < N)
1917 next_.resize(acc_detail::shapeOf(t));
1918 next_.template pass<N>(t, weight);
1922 std::string message(
"AccumulatorChain::update(): cannot return to pass ");
1923 message << N <<
" after working on pass " << current_pass_ <<
".";
1924 vigra_precondition(
false, message);
1930 void operator+=(AccumulatorChainImpl
const & o)
1937 void merge(AccumulatorChainImpl
const & o)
1939 next_.mergeImpl(o.next_);
1942 result_type operator()()
const
1947 void operator()(T
const & t)
1952 void operator()(T
const & t,
double weight)
1954 update<1>(t, weight);
1957 void updatePass2(T
const & t)
1962 void updatePass2(T
const & t,
double weight)
1964 update<2>(t, weight);
1969 void updatePassN(T
const & t,
unsigned int N)
1973 case 1: update<1>(t);
break;
1974 case 2: update<2>(t);
break;
1975 case 3: update<3>(t);
break;
1976 case 4: update<4>(t);
break;
1977 case 5: update<5>(t);
break;
1979 vigra_precondition(
false,
1980 "AccumulatorChain::updatePassN(): 0 < N < 6 required.");
1986 void updatePassN(T
const & t,
double weight,
unsigned int N)
1990 case 1: update<1>(t, weight);
break;
1991 case 2: update<2>(t, weight);
break;
1992 case 3: update<3>(t, weight);
break;
1993 case 4: update<4>(t, weight);
break;
1994 case 5: update<5>(t, weight);
break;
1996 vigra_precondition(
false,
1997 "AccumulatorChain::updatePassN(): 0 < N < 6 required.");
2003 unsigned int passesRequired()
const
2005 return InternalBaseType::passesRequired();
2041 template <
class T,
class Selected,
bool dynamic=false>
2044 :
public AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChain<T, Selected, dynamic>::type>
2049 typedef typename acc_detail::ConfigureAccumulatorChain<T, Selected, dynamic>::TagList AccumulatorTags;
2053 template <
class U,
int N>
2056 vigra_precondition(this->current_pass_ == 0,
2057 "AccumulatorChain::reshape(): cannot reshape after seeing data. Call AccumulatorChain::reset() first.");
2058 this->next_.resize(s);
2059 this->current_pass_ = 1;
2083 template <
class SHAPE>
2087 void reset(
unsigned int reset_to_pass = 0);
2094 void merge(AccumulatorChainImpl
const & o);
2114 acc_detail::CollectAccumulatorNames<AccumulatorTags>::exec(n);
2120 template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected,
bool dynamic>
2121 class AccumulatorChain<
CoupledArrays<N, T1, T2, T3, T4, T5>, Selected, dynamic>
2122 :
public AccumulatorChain<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected, dynamic>
2156 template <
class T,
class Selected>
2162 typedef typename DynamicAccumulatorChain::AccumulatorTags AccumulatorTags;
2168 vigra_precondition(activateImpl(tag),
2169 std::string(
"DynamicAccumulatorChain::activate(): Tag '") + tag +
"' not found.");
2174 template <
class TAG>
2177 LookupTag<TAG, DynamicAccumulatorChain>::type::activateImpl(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
2184 getAccumulator<AccumulatorEnd>(*this).active_accumulators_.set();
2190 acc_detail::TagIsActive_Visitor v;
2191 vigra_precondition(isActiveImpl(tag, v),
2192 std::string(
"DynamicAccumulatorChain::isActive(): Tag '") + tag +
"' not found.");
2198 template <
class TAG>
2201 return LookupTag<TAG, DynamicAccumulatorChain>::type::isActiveImpl(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
2219 return InternalBaseType::passesRequired(getAccumulator<AccumulatorEnd>(*this).active_accumulators_);
2224 bool activateImpl(std::string tag)
2226 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(*
this,
2230 bool isActiveImpl(std::string tag, acc_detail::TagIsActive_Visitor & v)
const
2232 return acc_detail::ApplyVisitorToTag<AccumulatorTags>::exec(*
this,
normalizeString(tag), v);
2236 template <
unsigned int N,
class T1,
class T2,
class T3,
class T4,
class T5,
class Selected>
2237 class DynamicAccumulatorChain<CoupledArrays<N, T1, T2, T3, T4, T5>, Selected>
2238 :
public DynamicAccumulatorChain<typename CoupledArrays<N, T1, T2, T3, T4, T5>::HandleType, Selected>
2267 template<
unsigned int N,
class T,
class SELECT>
2273 typedef typename CoupledHandleType<N, T>::type HandleType;
2274 typedef typename HandleType::base_type CoordHandle;
2275 typedef typename CoordHandle::value_type CoordType;
2276 typedef SELECT SelectType;
2281 handle_((T
const *)0, CoordType(), CoordHandle(CoordType()))
2284 void updatePassN(
const T & val,
const CoordType & coord,
unsigned int p)
2286 cast<0>(handle_).internal_reset(coord);
2287 cast<1>(handle_).internal_reset(&val);
2317 template<
unsigned int N,
class SELECT>
2323 typedef typename CoupledHandleType<N>::type HandleType;
2324 typedef typename HandleType::value_type CoordType;
2326 typedef SELECT SelectType;
2331 handle_(CoordType())
2334 template<
class IGNORED_DATA>
2336 updatePassN(
const IGNORED_DATA &,
2337 const CoordType & coord,
2340 this->updatePassN(coord, p);
2344 void updatePassN(
const CoordType & coord,
unsigned int p)
2346 handle_.internal_reset(coord);
2378 template <
class T,
class Selected,
bool dynamic=false>
2381 :
public AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic>::type>
2385 typedef AccumulatorChainImpl<T, typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic>::type> base_type;
2386 typedef typename acc_detail::ConfigureAccumulatorChainArray<T, Selected, dynamic> Creator;
2387 typedef typename Creator::TagList AccumulatorTags;
2388 typedef typename Creator::GlobalTags GlobalTags;
2389 typedef typename Creator::RegionTags RegionTags;
2395 this->next_.ignoreLabel(l);
2402 return this->next_.ignoredLabel();
2409 this->next_.setMaxRegionLabel(label);
2416 return this->next_.maxRegionLabel();
2423 return this->next_.regions_.size();
2438 "AccumulatorChainArray::merge(): region labels out of range.");
2439 this->next_.mergeImpl(i, j);
2449 "AccumulatorChainArray::merge(): maxRegionLabel must be equal.");
2450 this->next_.mergeImpl(o.next_);
2455 template <
class ArrayLike>
2458 vigra_precondition(labelMapping.size() == o.
regionCount(),
2459 "AccumulatorChainArray::merge(): labelMapping.size() must match regionCount() of RHS.");
2460 this->next_.mergeImpl(o.next_, labelMapping);
2471 using base_type::setCoordinateOffset;