37 #ifndef VIGRA_NOISE_NORMALIZATION_HXX
38 #define VIGRA_NOISE_NORMALIZATION_HXX
40 #include "utilities.hxx"
41 #include "tinyvector.hxx"
42 #include "stdimage.hxx"
43 #include "transformimage.hxx"
44 #include "combineimages.hxx"
45 #include "localminmax.hxx"
46 #include "functorexpression.hxx"
47 #include "numerictraits.hxx"
48 #include "separableconvolution.hxx"
49 #include "linear_solve.hxx"
50 #include "array_vector.hxx"
51 #include "static_assert.hxx"
96 noise_estimation_quantile(1.5),
97 averaging_quantile(0.8),
98 noise_variance_initial_guess(10.0),
119 vigra_precondition(r > 0,
120 "NoiseNormalizationOptions: window radius must be > 0.");
132 vigra_precondition(c > 0,
133 "NoiseNormalizationOptions: cluster count must be > 0.");
147 vigra_precondition(quantile > 0.0 && quantile <= 1.0,
148 "NoiseNormalizationOptions: averaging quantile must be between 0 and 1.");
149 averaging_quantile = quantile;
161 vigra_precondition(quantile > 0.0,
162 "NoiseNormalizationOptions: noise estimation quantile must be > 0.");
163 noise_estimation_quantile = quantile;
174 vigra_precondition(guess > 0.0,
175 "NoiseNormalizationOptions: noise variance initial guess must be > 0.");
176 noise_variance_initial_guess = guess;
180 unsigned int window_radius, cluster_count;
181 double noise_estimation_quantile, averaging_quantile, noise_variance_initial_guess;
187 template <
class ArgumentType,
class ResultType>
188 class NonparametricNoiseNormalizationFunctor
192 double lower, a, b, shift;
195 ArrayVector<Segment> segments_;
198 double exec(
unsigned int k, T t)
const
200 if(segments_[k].a == 0.0)
206 return 2.0 / segments_[k].a *
VIGRA_CSTD::sqrt(std::max(0.0, segments_[k].a * t + segments_[k].b));
211 typedef ArgumentType argument_type;
212 typedef ResultType result_type;
214 template <
class Vector>
215 NonparametricNoiseNormalizationFunctor(Vector
const & clusters)
216 : segments_(clusters.size()-1)
218 for(
unsigned int k = 0; k<segments_.size(); ++k)
220 segments_[k].lower = clusters[k][0];
221 segments_[k].a = (clusters[k+1][1] - clusters[k][1]) / (clusters[k+1][0] - clusters[k][0]);
222 segments_[k].b = clusters[k][1] - segments_[k].a * clusters[k][0];
229 segments_[k].shift = segments_[k].lower - exec(k, segments_[k].lower);
233 segments_[k].shift = exec(k-1, segments_[k].lower) - exec(k, segments_[k].lower) + segments_[k-1].shift;
238 result_type operator()(argument_type t)
const
242 for(; k < segments_.size(); ++k)
243 if(t < segments_[k].lower)
247 return detail::RequiresExplicitCast<ResultType>::cast(exec(k, t) + segments_[k].shift);
251 template <
class ArgumentType,
class ResultType>
252 class QuadraticNoiseNormalizationFunctor
254 double a, b, c, d, f, o;
256 void init(
double ia,
double ib,
double ic,
double xmin)
275 typedef ArgumentType argument_type;
276 typedef ResultType result_type;
278 template <
class Vector>
279 QuadraticNoiseNormalizationFunctor(Vector
const & clusters)
281 double xmin = NumericTraits<double>::max();
282 Matrix<double> m(3,3), r(3, 1), l(3, 1);
283 for(
unsigned int k = 0; k<clusters.size(); ++k)
286 l(1,0) = clusters[k][0];
287 l(2,0) =
sq(clusters[k][0]);
289 r += clusters[k][1]*l;
290 if(clusters[k][0] < xmin)
291 xmin = clusters[k][0];
295 init(l(0,0), l(1,0), l(2,0), xmin);
298 result_type operator()(argument_type t)
const
305 return detail::RequiresExplicitCast<ResultType>::cast(r);
309 template <
class ArgumentType,
class ResultType>
310 class LinearNoiseNormalizationFunctor
314 void init(
double ia,
double ib,
double xmin)
329 typedef ArgumentType argument_type;
330 typedef ResultType result_type;
332 template <
class Vector>
333 LinearNoiseNormalizationFunctor(Vector
const & clusters)
335 double xmin = NumericTraits<double>::max();
336 Matrix<double> m(2,2), r(2, 1), l(2, 1);
337 for(
unsigned int k = 0; k<clusters.size(); ++k)
340 l(1,0) = clusters[k][0];
342 r += clusters[k][1]*l;
343 if(clusters[k][0] < xmin)
344 xmin = clusters[k][0];
348 init(l(0,0), l(1,0), xmin);
351 result_type operator()(argument_type t)
const
358 return detail::RequiresExplicitCast<ResultType>::cast(r);
362 #define VIGRA_NoiseNormalizationFunctor(name, type, size) \
363 template <class ResultType> \
364 class name<type, ResultType> \
366 ResultType lut_[size]; \
369 typedef type argument_type; \
370 typedef ResultType result_type; \
372 template <class Vector> \
373 name(Vector const & clusters) \
375 name<double, ResultType> f(clusters); \
377 for(unsigned int k = 0; k < size; ++k) \
383 result_type operator()(argument_type t) const \
389 VIGRA_NoiseNormalizationFunctor(NonparametricNoiseNormalizationFunctor,
UInt8, 256)
390 VIGRA_NoiseNormalizationFunctor(NonparametricNoiseNormalizationFunctor,
UInt16, 65536)
391 VIGRA_NoiseNormalizationFunctor(QuadraticNoiseNormalizationFunctor,
UInt8, 256)
392 VIGRA_NoiseNormalizationFunctor(QuadraticNoiseNormalizationFunctor, UInt16, 65536)
393 VIGRA_NoiseNormalizationFunctor(LinearNoiseNormalizationFunctor, UInt8, 256)
394 VIGRA_NoiseNormalizationFunctor(LinearNoiseNormalizationFunctor, UInt16, 65536)
396 #undef VIGRA_NoiseNormalizationFunctor
400 template <
class SrcIterator,
class SrcAcessor,
403 iterativeNoiseEstimationChi2(SrcIterator s, SrcAcessor src, GradIterator g,
404 double & mean,
double & variance,
405 double robustnessThreshold,
int windowRadius)
407 double l2 =
sq(robustnessThreshold);
411 Diff2D ul(-windowRadius, -windowRadius);
412 int r2 =
sq(windowRadius);
414 for(
int iter=0; iter<100 ; ++iter)
419 unsigned int count = 0;
420 unsigned int tcount = 0;
422 SrcIterator siy = s + ul;
423 GradIterator giy = g + ul;
424 for(
int y=-windowRadius; y <= windowRadius; y++, ++siy.y, ++giy.y)
426 typename SrcIterator::row_iterator six = siy.rowIterator();
427 typename GradIterator::row_iterator gix = giy.rowIterator();
428 for(
int x=-windowRadius; x <= windowRadius; x++, ++six, ++gix)
430 if (
sq(x) +
sq(y) > r2)
434 if (*gix < l2*variance)
445 double oldvariance = variance;
446 variance= f * gsum / count;
450 return (count >= tcount * countThreshold / 2.0);
455 template <
class SrcIterator,
class SrcAcessor,
458 iterativeNoiseEstimationGauss(SrcIterator s, SrcAcessor src, GradIterator,
459 double & mean,
double & variance,
460 double robustnessThreshold,
int windowRadius)
462 double l2 =
sq(robustnessThreshold);
468 Diff2D ul(-windowRadius, -windowRadius);
469 int r2 =
sq(windowRadius);
471 for(
int iter=0; iter<100 ; ++iter)
476 unsigned int count = 0;
477 unsigned int tcount = 0;
479 SrcIterator siy = s + ul;
480 for(
int y=-windowRadius; y <= windowRadius; y++, ++siy.y)
482 typename SrcIterator::row_iterator six = siy.rowIterator();
483 for(
int x=-windowRadius; x <= windowRadius; x++, ++six)
485 if (
sq(x) +
sq(y) > r2)
489 if (
sq(src(six) - mean) < l2*variance)
492 sum2 +=
sq(src(six));
500 double oldmean = mean;
501 double oldvariance = variance;
503 variance= f * (sum2 / count -
sq(mean));
507 return (count >= tcount * countThreshold / 2.0);
513 template <
class SrcIterator,
class SrcAccessor,
514 class DestIterator,
class DestAccessor>
516 symmetricDifferenceSquaredMagnitude(
517 SrcIterator sul, SrcIterator slr, SrcAccessor src,
518 DestIterator dul, DestAccessor dest)
520 using namespace functor;
521 int w = slr.x - sul.x;
522 int h = slr.y - sul.y;
524 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
525 typedef BasicImage<TmpType> TmpImage;
527 Kernel1D<double> mask;
528 mask.initSymmetricGradient();
529 mask.setBorderTreatment(BORDER_TREATMENT_REFLECT);
531 TmpImage dx(w, h), dy(w, h);
534 combineTwoImages(srcImageRange(dx), srcImage(dy), destIter(dul, dest), Arg1()*Arg1() + Arg2()*Arg2());
537 template <
class SrcIterator,
class SrcAccessor,
538 class DestIterator,
class DestAccessor>
540 findHomogeneousRegionsFoerstner(
541 SrcIterator sul, SrcIterator slr, SrcAccessor src,
542 DestIterator dul, DestAccessor dest,
543 unsigned int windowRadius = 6,
double homogeneityThreshold = 40.0)
545 using namespace vigra::functor;
546 int w = slr.x - sul.x;
547 int h = slr.y - sul.y;
549 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
550 typedef BasicImage<TmpType> TmpImage;
554 ifThenElse(Arg1() <= Param(homogeneityThreshold), Param(1), Param(0)));
557 discErosion(srcImageRange(btmp), destIter(dul, dest), windowRadius);
560 template <
class SrcIterator,
class SrcAccessor,
561 class DestIterator,
class DestAccessor>
563 findHomogeneousRegions(
564 SrcIterator sul, SrcIterator slr, SrcAccessor src,
565 DestIterator dul, DestAccessor dest)
570 template <
class Vector1,
class Vector2>
571 void noiseVarianceListMedianCut(Vector1
const & noise, Vector2 & clusters,
572 unsigned int maxClusterCount)
574 typedef typename Vector2::value_type Result;
576 clusters.push_back(Result(0, noise.size()));
578 while(clusters.size() <= maxClusterCount)
581 unsigned int kMax = 0;
582 double diffMax = 0.0;
583 for(
unsigned int k=0; k < clusters.size(); ++k)
585 int k1 = clusters[k][0], k2 = clusters[k][1]-1;
586 std::string message(
"noiseVarianceListMedianCut(): internal error (");
587 message += std::string(
"k: ") +
asString(k) +
", ";
588 message += std::string(
"k1: ") +
asString(k1) +
", ";
589 message += std::string(
"k2: ") +
asString(k2) +
", ";
590 message += std::string(
"noise.size(): ") +
asString(noise.size()) +
", ";
591 message += std::string(
"clusters.size(): ") +
asString(clusters.size()) +
").";
592 vigra_invariant(k1 >= 0 && k1 < (
int)noise.size() && k2 >= 0 && k2 < (int)noise.size(), message.c_str());
594 double diff = noise[k2][0] - noise[k1][0];
605 unsigned int k1 = clusters[kMax][0],
606 k2 = clusters[kMax][1];
607 unsigned int kSplit = k1 + (k2 - k1) / 2;
608 clusters[kMax][1] = kSplit;
609 clusters.push_back(Result(kSplit, k2));
613 struct SortNoiseByMean
616 bool operator()(T
const & l, T
const & r)
const
622 struct SortNoiseByVariance
625 bool operator()(T
const & l, T
const & r)
const
631 template <
class Vector1,
class Vector2,
class Vector3>
632 void noiseVarianceClusterAveraging(Vector1 & noise, Vector2 & clusters,
633 Vector3 & result,
double quantile)
635 typedef typename Vector1::iterator Iter;
636 typedef typename Vector3::value_type Result;
638 for(
unsigned int k=0; k<clusters.size(); ++k)
640 Iter i1 = noise.begin() + clusters[k][0];
641 Iter i2 = noise.begin() + clusters[k][1];
643 std::sort(i1, i2, SortNoiseByVariance());
645 std::size_t size =
static_cast<std::size_t
>(
VIGRA_CSTD::ceil(quantile*(i2 - i1)));
646 if(static_cast<std::size_t>(i2 - i1) < size)
657 variance += (*i1)[1];
660 result.push_back(Result(mean / size, variance / size));
664 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
665 void noiseVarianceEstimationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
666 BackInsertable & result,
667 NoiseNormalizationOptions
const & options)
669 typedef typename BackInsertable::value_type ResultType;
671 unsigned int w = slr.x - sul.x;
672 unsigned int h = slr.y - sul.y;
674 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
675 typedef BasicImage<TmpType> TmpImage;
677 TmpImage gradient(w, h);
678 symmetricDifferenceSquaredMagnitude(sul, slr, src, gradient.upperLeft(), gradient.accessor());
681 findHomogeneousRegions(gradient.upperLeft(), gradient.lowerRight(), gradient.accessor(),
682 homogeneous.upperLeft(), homogeneous.accessor());
685 unsigned int windowRadius = options.window_radius;
686 for(
unsigned int y=windowRadius; y<h-windowRadius; ++y)
688 for(
unsigned int x=windowRadius; x<w-windowRadius; ++x)
690 if (! homogeneous(x, y))
694 double mean = 0.0, variance = options.noise_variance_initial_guess;
698 if(options.use_gradient)
700 success = iterativeNoiseEstimationChi2(sul + center, src,
701 gradient.upperLeft() + center, mean, variance,
702 options.noise_estimation_quantile, windowRadius);
706 success = iterativeNoiseEstimationGauss(sul + center, src,
707 gradient.upperLeft() + center, mean, variance,
708 options.noise_estimation_quantile, windowRadius);
712 result.push_back(ResultType(mean, variance));
718 template <
class Vector,
class BackInsertable>
719 void noiseVarianceClusteringImpl(Vector & noise, BackInsertable & result,
720 unsigned int clusterCount,
double quantile)
722 std::sort(noise.begin(), noise.end(), detail::SortNoiseByMean());
724 ArrayVector<TinyVector<unsigned int, 2> > clusters;
725 detail::noiseVarianceListMedianCut(noise, clusters, clusterCount);
727 std::sort(clusters.begin(), clusters.end(), detail::SortNoiseByMean());
729 detail::noiseVarianceClusterAveraging(noise, clusters, result, quantile);
732 template <
class Functor,
733 class SrcIterator,
class SrcAccessor,
734 class DestIterator,
class DestAccessor>
736 noiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
737 DestIterator dul, DestAccessor dest,
738 NoiseNormalizationOptions
const & options)
740 ArrayVector<TinyVector<double, 2> > noiseData;
741 noiseVarianceEstimationImpl(sul, slr, src, noiseData, options);
743 if(noiseData.size() < 10)
746 ArrayVector<TinyVector<double, 2> > noiseClusters;
748 noiseVarianceClusteringImpl(noiseData, noiseClusters,
749 options.cluster_count, options.averaging_quantile);
756 template <
class SrcIterator,
class SrcAccessor,
757 class DestIterator,
class DestAccessor>
759 nonparametricNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
760 DestIterator dul, DestAccessor dest,
761 NoiseNormalizationOptions
const & options,
764 typedef typename SrcAccessor::value_type SrcType;
765 typedef typename DestAccessor::value_type DestType;
766 return noiseNormalizationImpl<NonparametricNoiseNormalizationFunctor<SrcType, DestType> >
767 (sul, slr, src, dul, dest, options);
770 template <
class SrcIterator,
class SrcAccessor,
771 class DestIterator,
class DestAccessor>
773 nonparametricNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
774 DestIterator dul, DestAccessor dest,
775 NoiseNormalizationOptions
const & options,
778 int bands = src.size(sul);
779 for(
int b=0; b<bands; ++b)
781 VectorElementAccessor<SrcAccessor> sband(b, src);
782 VectorElementAccessor<DestAccessor> dband(b, dest);
783 typedef typename VectorElementAccessor<SrcAccessor>::value_type SrcType;
784 typedef typename VectorElementAccessor<DestAccessor>::value_type DestType;
786 if(!noiseNormalizationImpl<NonparametricNoiseNormalizationFunctor<SrcType, DestType> >
787 (sul, slr, sband, dul, dband, options))
793 template <
class SrcIterator,
class SrcAccessor,
794 class DestIterator,
class DestAccessor>
796 quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
797 DestIterator dul, DestAccessor dest,
798 NoiseNormalizationOptions
const & options,
801 typedef typename SrcAccessor::value_type SrcType;
802 typedef typename DestAccessor::value_type DestType;
803 return noiseNormalizationImpl<QuadraticNoiseNormalizationFunctor<SrcType, DestType> >
804 (sul, slr, src, dul, dest, options);
807 template <
class SrcIterator,
class SrcAccessor,
808 class DestIterator,
class DestAccessor>
810 quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
811 DestIterator dul, DestAccessor dest,
812 NoiseNormalizationOptions
const & options,
815 int bands = src.size(sul);
816 for(
int b=0; b<bands; ++b)
818 VectorElementAccessor<SrcAccessor> sband(b, src);
819 VectorElementAccessor<DestAccessor> dband(b, dest);
820 typedef typename VectorElementAccessor<SrcAccessor>::value_type SrcType;
821 typedef typename VectorElementAccessor<DestAccessor>::value_type DestType;
823 if(!noiseNormalizationImpl<QuadraticNoiseNormalizationFunctor<SrcType, DestType> >
824 (sul, slr, sband, dul, dband, options))
830 template <
class SrcIterator,
class SrcAccessor,
831 class DestIterator,
class DestAccessor>
833 quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
834 DestIterator dul, DestAccessor dest,
835 double a0,
double a1,
double a2,
838 ArrayVector<TinyVector<double, 2> > noiseClusters;
839 noiseClusters.push_back(TinyVector<double, 2>(0.0, a0));
840 noiseClusters.push_back(TinyVector<double, 2>(1.0, a0 + a1 + a2));
841 noiseClusters.push_back(TinyVector<double, 2>(2.0, a0 + 2.0*a1 + 4.0*a2));
843 QuadraticNoiseNormalizationFunctor<
typename SrcAccessor::value_type,
844 typename DestAccessor::value_type>(noiseClusters));
847 template <
class SrcIterator,
class SrcAccessor,
848 class DestIterator,
class DestAccessor>
850 quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
851 DestIterator dul, DestAccessor dest,
852 double a0,
double a1,
double a2,
855 int bands = src.size(sul);
856 for(
int b=0; b<bands; ++b)
858 VectorElementAccessor<SrcAccessor> sband(b, src);
859 VectorElementAccessor<DestAccessor> dband(b, dest);
860 quadraticNoiseNormalizationImpl(sul, slr, sband, dul, dband, a0, a1, a2, VigraTrueType());
864 template <
class SrcIterator,
class SrcAccessor,
865 class DestIterator,
class DestAccessor>
867 linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
868 DestIterator dul, DestAccessor dest,
869 NoiseNormalizationOptions
const & options,
872 typedef typename SrcAccessor::value_type SrcType;
873 typedef typename DestAccessor::value_type DestType;
874 return noiseNormalizationImpl<LinearNoiseNormalizationFunctor<SrcType, DestType> >
875 (sul, slr, src, dul, dest, options);
878 template <
class SrcIterator,
class SrcAccessor,
879 class DestIterator,
class DestAccessor>
881 linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
882 DestIterator dul, DestAccessor dest,
883 NoiseNormalizationOptions
const & options,
886 int bands = src.size(sul);
887 for(
int b=0; b<bands; ++b)
889 VectorElementAccessor<SrcAccessor> sband(b, src);
890 VectorElementAccessor<DestAccessor> dband(b, dest);
891 typedef typename VectorElementAccessor<SrcAccessor>::value_type SrcType;
892 typedef typename VectorElementAccessor<DestAccessor>::value_type DestType;
894 if(!noiseNormalizationImpl<LinearNoiseNormalizationFunctor<SrcType, DestType> >
895 (sul, slr, sband, dul, dband, options))
901 template <
class SrcIterator,
class SrcAccessor,
902 class DestIterator,
class DestAccessor>
904 linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
905 DestIterator dul, DestAccessor dest,
906 double a0,
double a1,
909 ArrayVector<TinyVector<double, 2> > noiseClusters;
910 noiseClusters.push_back(TinyVector<double, 2>(0.0, a0));
911 noiseClusters.push_back(TinyVector<double, 2>(1.0, a0 + a1));
913 LinearNoiseNormalizationFunctor<
typename SrcAccessor::value_type,
914 typename DestAccessor::value_type>(noiseClusters));
917 template <
class SrcIterator,
class SrcAccessor,
918 class DestIterator,
class DestAccessor>
920 linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
921 DestIterator dul, DestAccessor dest,
922 double a0,
double a1,
925 int bands = src.size(sul);
926 for(
int b=0; b<bands; ++b)
928 VectorElementAccessor<SrcAccessor> sband(b, src);
929 VectorElementAccessor<DestAccessor> dband(b, dest);
930 linearNoiseNormalizationImpl(sul, slr, sband, dul, dband, a0, a1, VigraTrueType());
937 struct noiseVarianceEstimation_can_only_work_on_scalar_images
938 : vigra::staticAssert::AssertBool<P>
1029 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1032 BackInsertable & result,
1033 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1035 typedef typename BackInsertable::value_type ResultType;
1036 typedef typename SrcAccessor::value_type SrcType;
1037 typedef typename NumericTraits<SrcType>::isScalar isScalar;
1039 VIGRA_STATIC_ASSERT((
1040 noiseVarianceEstimation_can_only_work_on_scalar_images<(isScalar::asBool)>));
1042 detail::noiseVarianceEstimationImpl(sul, slr, src, result, options);
1045 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1048 BackInsertable & result,
1049 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1118 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1121 BackInsertable & result,
1122 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1124 ArrayVector<TinyVector<double, 2> > variance;
1126 detail::noiseVarianceClusteringImpl(variance, result, options.cluster_count, options.averaging_quantile);
1129 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1132 BackInsertable & result,
1133 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1209 template <
class SrcIterator,
class SrcAccessor,
1210 class DestIterator,
class DestAccessor>
1213 DestIterator dul, DestAccessor dest,
1214 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1216 typedef typename SrcAccessor::value_type SrcType;
1218 return detail::nonparametricNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
1219 typename NumericTraits<SrcType>::isScalar());
1222 template <
class SrcIterator,
class SrcAccessor,
1223 class DestIterator,
class DestAccessor>
1226 pair<DestIterator, DestAccessor> dest,
1227 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1289 template <
class SrcIterator,
class SrcAccessor,
1290 class DestIterator,
class DestAccessor>
1293 DestIterator dul, DestAccessor dest,
1294 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1296 typedef typename SrcAccessor::value_type SrcType;
1298 return detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
1299 typename NumericTraits<SrcType>::isScalar());
1302 template <
class SrcIterator,
class SrcAccessor,
1303 class DestIterator,
class DestAccessor>
1306 pair<DestIterator, DestAccessor> dest,
1307 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1373 template <
class SrcIterator,
class SrcAccessor,
1374 class DestIterator,
class DestAccessor>
1377 DestIterator dul, DestAccessor dest,
1378 double a0,
double a1,
double a2)
1380 typedef typename SrcAccessor::value_type SrcType;
1382 detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a1, a2,
1383 typename NumericTraits<SrcType>::isScalar());
1386 template <
class SrcIterator,
class SrcAccessor,
1387 class DestIterator,
class DestAccessor>
1390 pair<DestIterator, DestAccessor> dest,
1391 double a0,
double a1,
double a2)
1453 template <
class SrcIterator,
class SrcAccessor,
1454 class DestIterator,
class DestAccessor>
1457 DestIterator dul, DestAccessor dest,
1458 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1460 typedef typename SrcAccessor::value_type SrcType;
1462 return detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
1463 typename NumericTraits<SrcType>::isScalar());
1466 template <
class SrcIterator,
class SrcAccessor,
1467 class DestIterator,
class DestAccessor>
1470 pair<DestIterator, DestAccessor> dest,
1471 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1537 template <
class SrcIterator,
class SrcAccessor,
1538 class DestIterator,
class DestAccessor>
1541 DestIterator dul, DestAccessor dest,
1542 double a0,
double a1)
1544 typedef typename SrcAccessor::value_type SrcType;
1546 detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a1,
1547 typename NumericTraits<SrcType>::isScalar());
1550 template <
class SrcIterator,
class SrcAccessor,
1551 class DestIterator,
class DestAccessor>
1554 pair<DestIterator, DestAccessor> dest,
1555 double a0,
double a1)
1564 #endif // VIGRA_NOISE_NORMALIZATION_HXX