37 #ifndef VIGRA_NOISE_NORMALIZATION_HXX
38 #define VIGRA_NOISE_NORMALIZATION_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"
52 #include "multi_shape.hxx"
98 noise_estimation_quantile(1.5),
99 averaging_quantile(0.8),
100 noise_variance_initial_guess(10.0),
121 vigra_precondition(r > 0,
122 "NoiseNormalizationOptions: window radius must be > 0.");
134 vigra_precondition(c > 0,
135 "NoiseNormalizationOptions: cluster count must be > 0.");
149 vigra_precondition(quantile > 0.0 && quantile <= 1.0,
150 "NoiseNormalizationOptions: averaging quantile must be between 0 and 1.");
151 averaging_quantile = quantile;
163 vigra_precondition(quantile > 0.0,
164 "NoiseNormalizationOptions: noise estimation quantile must be > 0.");
165 noise_estimation_quantile = quantile;
176 vigra_precondition(guess > 0.0,
177 "NoiseNormalizationOptions: noise variance initial guess must be > 0.");
178 noise_variance_initial_guess = guess;
182 unsigned int window_radius, cluster_count;
183 double noise_estimation_quantile, averaging_quantile, noise_variance_initial_guess;
189 template <
class ArgumentType,
class ResultType>
190 class NonparametricNoiseNormalizationFunctor
194 double lower, a, b, shift;
197 ArrayVector<Segment> segments_;
200 double exec(
unsigned int k, T t)
const
202 if(segments_[k].a == 0.0)
204 return t / VIGRA_CSTD::sqrt(segments_[k].b);
208 return 2.0 / segments_[k].a * VIGRA_CSTD::sqrt(std::max(0.0, segments_[k].a * t + segments_[k].b));
213 typedef ArgumentType argument_type;
214 typedef ResultType result_type;
216 template <
class Vector>
217 NonparametricNoiseNormalizationFunctor(Vector
const & clusters)
218 : segments_(clusters.size()-1)
220 for(
unsigned int k = 0; k<segments_.size(); ++k)
222 segments_[k].lower = clusters[k][0];
223 segments_[k].a = (clusters[k+1][1] - clusters[k][1]) / (clusters[k+1][0] - clusters[k][0]);
224 segments_[k].b = clusters[k][1] - segments_[k].a * clusters[k][0];
231 segments_[k].shift = segments_[k].lower - exec(k, segments_[k].lower);
235 segments_[k].shift = exec(k-1, segments_[k].lower) - exec(k, segments_[k].lower) + segments_[k-1].shift;
240 result_type operator()(argument_type t)
const
244 for(; k < segments_.size(); ++k)
245 if(t < segments_[k].lower)
249 return detail::RequiresExplicitCast<ResultType>::cast(exec(k, t) + segments_[k].shift);
253 template <
class ArgumentType,
class ResultType>
254 class QuadraticNoiseNormalizationFunctor
256 double a, b, c, d, f, o;
258 void init(
double ia,
double ib,
double ic,
double xmin)
263 d = VIGRA_CSTD::sqrt(VIGRA_CSTD::fabs(c));
266 o = VIGRA_CSTD::log(VIGRA_CSTD::fabs((2.0*c*xmin + b)/d + 2*VIGRA_CSTD::sqrt(c*
sq(xmin) +b*xmin + a)))/d;
271 f = VIGRA_CSTD::sqrt(b*b - 4.0*a*c);
272 o = -VIGRA_CSTD::asin((2.0*c*xmin+b)/f)/d;
277 typedef ArgumentType argument_type;
278 typedef ResultType result_type;
280 template <
class Vector>
281 QuadraticNoiseNormalizationFunctor(Vector
const & clusters)
283 double xmin = NumericTraits<double>::max();
284 Matrix<double> m(3,3), r(3, 1), l(3, 1);
285 for(
unsigned int k = 0; k<clusters.size(); ++k)
288 l(1,0) = clusters[k][0];
289 l(2,0) =
sq(clusters[k][0]);
291 r += clusters[k][1]*l;
292 if(clusters[k][0] < xmin)
293 xmin = clusters[k][0];
297 init(l(0,0), l(1,0), l(2,0), xmin);
300 result_type operator()(argument_type t)
const
304 r = VIGRA_CSTD::log(VIGRA_CSTD::fabs((2.0*c*t + b)/d + 2.0*VIGRA_CSTD::sqrt(c*t*t +b*t + a)))/d-o;
306 r = -VIGRA_CSTD::asin((2.0*c*t+b)/f)/d-o;
307 return detail::RequiresExplicitCast<ResultType>::cast(r);
311 template <
class ArgumentType,
class ResultType>
312 class LinearNoiseNormalizationFunctor
316 void init(
double ia,
double ib,
double xmin)
322 o = xmin - 2.0 / b * VIGRA_CSTD::sqrt(a + b * xmin);
326 o = xmin - xmin / VIGRA_CSTD::sqrt(a);
331 typedef ArgumentType argument_type;
332 typedef ResultType result_type;
334 template <
class Vector>
335 LinearNoiseNormalizationFunctor(Vector
const & clusters)
337 double xmin = NumericTraits<double>::max();
338 Matrix<double> m(2,2), r(2, 1), l(2, 1);
339 for(
unsigned int k = 0; k<clusters.size(); ++k)
342 l(1,0) = clusters[k][0];
344 r += clusters[k][1]*l;
345 if(clusters[k][0] < xmin)
346 xmin = clusters[k][0];
350 init(l(0,0), l(1,0), xmin);
353 result_type operator()(argument_type t)
const
357 r = 2.0 / b * VIGRA_CSTD::sqrt(a + b*t) + o;
359 r = t / VIGRA_CSTD::sqrt(a) + o;
360 return detail::RequiresExplicitCast<ResultType>::cast(r);
364 #define VIGRA_NoiseNormalizationFunctor(name, type, size) \
365 template <class ResultType> \
366 class name<type, ResultType> \
368 ResultType lut_[size]; \
371 typedef type argument_type; \
372 typedef ResultType result_type; \
374 template <class Vector> \
375 name(Vector const & clusters) \
377 name<double, ResultType> f(clusters); \
379 for(unsigned int k = 0; k < size; ++k) \
385 result_type operator()(argument_type t) const \
391 VIGRA_NoiseNormalizationFunctor(NonparametricNoiseNormalizationFunctor,
UInt8, 256)
392 VIGRA_NoiseNormalizationFunctor(NonparametricNoiseNormalizationFunctor,
UInt16, 65536)
393 VIGRA_NoiseNormalizationFunctor(QuadraticNoiseNormalizationFunctor,
UInt8, 256)
394 VIGRA_NoiseNormalizationFunctor(QuadraticNoiseNormalizationFunctor,
UInt16, 65536)
395 VIGRA_NoiseNormalizationFunctor(LinearNoiseNormalizationFunctor,
UInt8, 256)
396 VIGRA_NoiseNormalizationFunctor(LinearNoiseNormalizationFunctor,
UInt16, 65536)
398 #undef VIGRA_NoiseNormalizationFunctor
402 template <
class SrcIterator,
class SrcAcessor,
405 iterativeNoiseEstimationChi2(SrcIterator s, SrcAcessor src, GradIterator g,
406 double & mean,
double & variance,
407 double robustnessThreshold,
int windowRadius)
409 double l2 =
sq(robustnessThreshold);
410 double countThreshold = 1.0 - VIGRA_CSTD::exp(-l2);
411 double f = (1.0 - VIGRA_CSTD::exp(-l2)) / (1.0 - (1.0 + l2)*VIGRA_CSTD::exp(-l2));
413 Diff2D ul(-windowRadius, -windowRadius);
414 int r2 =
sq(windowRadius);
416 for(
int iter=0; iter<100 ; ++iter)
421 unsigned int count = 0;
422 unsigned int tcount = 0;
424 SrcIterator siy = s + ul;
425 GradIterator giy = g + ul;
426 for(
int y=-windowRadius; y <= windowRadius; y++, ++siy.y, ++giy.y)
428 typename SrcIterator::row_iterator six = siy.rowIterator();
429 typename GradIterator::row_iterator gix = giy.rowIterator();
430 for(
int x=-windowRadius; x <= windowRadius; x++, ++six, ++gix)
432 if (
sq(x) +
sq(y) > r2)
436 if (*gix < l2*variance)
447 double oldvariance = variance;
448 variance= f * gsum / count;
452 return (count >= tcount * countThreshold / 2.0);
457 template <
class SrcIterator,
class SrcAcessor,
460 iterativeNoiseEstimationGauss(SrcIterator s, SrcAcessor src, GradIterator,
461 double & mean,
double & variance,
462 double robustnessThreshold,
int windowRadius)
464 double l2 =
sq(robustnessThreshold);
465 double countThreshold = erf(VIGRA_CSTD::sqrt(0.5 * l2));
466 double f = countThreshold / (countThreshold - VIGRA_CSTD::sqrt(2.0/M_PI*l2)*VIGRA_CSTD::exp(-l2/2.0));
470 Diff2D ul(-windowRadius, -windowRadius);
471 int r2 =
sq(windowRadius);
473 for(
int iter=0; iter<100 ; ++iter)
478 unsigned int count = 0;
479 unsigned int tcount = 0;
481 SrcIterator siy = s + ul;
482 for(
int y=-windowRadius; y <= windowRadius; y++, ++siy.y)
484 typename SrcIterator::row_iterator six = siy.rowIterator();
485 for(
int x=-windowRadius; x <= windowRadius; x++, ++six)
487 if (
sq(x) +
sq(y) > r2)
491 if (
sq(src(six) - mean) < l2*variance)
494 sum2 +=
sq(src(six));
502 double oldmean = mean;
503 double oldvariance = variance;
505 variance= f * (sum2 / count -
sq(mean));
509 return (count >= tcount * countThreshold / 2.0);
515 template <
class SrcIterator,
class SrcAccessor,
516 class DestIterator,
class DestAccessor>
518 symmetricDifferenceSquaredMagnitude(
519 SrcIterator sul, SrcIterator slr, SrcAccessor src,
520 DestIterator dul, DestAccessor dest)
522 using namespace functor;
523 int w = slr.x - sul.x;
524 int h = slr.y - sul.y;
526 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
527 typedef BasicImage<TmpType> TmpImage;
529 Kernel1D<double> mask;
530 mask.initSymmetricGradient();
531 mask.setBorderTreatment(BORDER_TREATMENT_REFLECT);
533 TmpImage dx(w, h), dy(w, h);
536 combineTwoImages(srcImageRange(dx), srcImage(dy), destIter(dul, dest), Arg1()*Arg1() + Arg2()*Arg2());
539 template <
class SrcIterator,
class SrcAccessor,
540 class DestIterator,
class DestAccessor>
542 findHomogeneousRegionsFoerstner(
543 SrcIterator sul, SrcIterator slr, SrcAccessor src,
544 DestIterator dul, DestAccessor dest,
545 unsigned int windowRadius = 6,
double homogeneityThreshold = 40.0)
547 using namespace vigra::functor;
548 int w = slr.x - sul.x;
549 int h = slr.y - sul.y;
553 ifThenElse(Arg1() <= Param(homogeneityThreshold), Param(1), Param(0)));
556 discErosion(srcImageRange(btmp), destIter(dul, dest), windowRadius);
559 template <
class SrcIterator,
class SrcAccessor,
560 class DestIterator,
class DestAccessor>
562 findHomogeneousRegions(
563 SrcIterator sul, SrcIterator slr, SrcAccessor src,
564 DestIterator dul, DestAccessor dest)
569 template <
class Vector1,
class Vector2>
570 void noiseVarianceListMedianCut(Vector1
const & noise, Vector2 & clusters,
571 unsigned int maxClusterCount)
573 typedef typename Vector2::value_type Result;
575 clusters.push_back(Result(0, noise.size()));
577 while(clusters.size() <= maxClusterCount)
580 unsigned int kMax = 0;
581 double diffMax = 0.0;
582 for(
unsigned int k=0; k < clusters.size(); ++k)
584 int k1 = clusters[k][0], k2 = clusters[k][1]-1;
588 std::string message(
"noiseVarianceListMedianCut(): internal error (");
589 message += std::string(
"k: ") +
asString(k) +
", ";
590 message += std::string(
"k1: ") +
asString(k1) +
", ";
591 message += std::string(
"k2: ") +
asString(k2) +
", ";
592 message += std::string(
"noise.size(): ") +
asString(noise.size()) +
", ";
593 message += std::string(
"clusters.size(): ") +
asString(clusters.size()) +
").";
594 vigra_invariant(k1 >= 0 && k1 < (
int)noise.size() && k2 >= 0 && k2 < (
int)noise.size(), message.c_str());
597 vigra_postcondition(k1 >= 0 && k1 < (
int)noise.size() &&
598 k2 >= 0 && k2 < (
int)noise.size(),
599 "noiseVarianceClustering(): Unable to find homogeneous regions.");
601 double diff = noise[k2][0] - noise[k1][0];
612 unsigned int k1 = clusters[kMax][0],
613 k2 = clusters[kMax][1];
614 unsigned int kSplit = k1 + (k2 - k1) / 2;
615 clusters[kMax][1] = kSplit;
616 clusters.push_back(Result(kSplit, k2));
620 struct SortNoiseByMean
623 bool operator()(T
const & l, T
const & r)
const
629 struct SortNoiseByVariance
632 bool operator()(T
const & l, T
const & r)
const
638 template <
class Vector1,
class Vector2,
class Vector3>
639 void noiseVarianceClusterAveraging(Vector1 & noise, Vector2 & clusters,
640 Vector3 & result,
double quantile)
642 typedef typename Vector1::iterator Iter;
643 typedef typename Vector3::value_type Result;
645 for(
unsigned int k=0; k<clusters.size(); ++k)
647 Iter i1 = noise.begin() + clusters[k][0];
648 Iter i2 = noise.begin() + clusters[k][1];
650 std::sort(i1, i2, SortNoiseByVariance());
652 std::size_t size =
static_cast<std::size_t
>(VIGRA_CSTD::ceil(quantile*(i2 - i1)));
653 if(
static_cast<std::size_t
>(i2 - i1) < size)
664 variance += (*i1)[1];
667 result.push_back(Result(mean / size, variance / size));
671 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
672 void noiseVarianceEstimationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
673 BackInsertable & result,
674 NoiseNormalizationOptions
const & options)
676 typedef typename BackInsertable::value_type ResultType;
678 unsigned int w = slr.x - sul.x;
679 unsigned int h = slr.y - sul.y;
681 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
682 typedef BasicImage<TmpType> TmpImage;
684 TmpImage gradient(w, h);
685 symmetricDifferenceSquaredMagnitude(sul, slr, src, gradient.upperLeft(), gradient.accessor());
688 findHomogeneousRegions(gradient.upperLeft(), gradient.lowerRight(), gradient.accessor(),
689 homogeneous.upperLeft(), homogeneous.accessor());
692 unsigned int windowRadius = options.window_radius;
693 for(
unsigned int y=windowRadius; y<h-windowRadius; ++y)
695 for(
unsigned int x=windowRadius; x<w-windowRadius; ++x)
697 if (! homogeneous(x, y))
701 double mean = 0.0, variance = options.noise_variance_initial_guess;
705 if(options.use_gradient)
707 success = iterativeNoiseEstimationChi2(sul + center, src,
708 gradient.upperLeft() + center, mean, variance,
709 options.noise_estimation_quantile, windowRadius);
713 success = iterativeNoiseEstimationGauss(sul + center, src,
714 gradient.upperLeft() + center, mean, variance,
715 options.noise_estimation_quantile, windowRadius);
719 result.push_back(ResultType(mean, variance));
725 template <
class Vector,
class BackInsertable>
726 void noiseVarianceClusteringImpl(Vector & noise, BackInsertable & result,
727 unsigned int clusterCount,
double quantile)
729 std::sort(noise.begin(), noise.end(), detail::SortNoiseByMean());
731 ArrayVector<TinyVector<unsigned int, 2> > clusters;
732 detail::noiseVarianceListMedianCut(noise, clusters, clusterCount);
734 std::sort(clusters.begin(), clusters.end(), detail::SortNoiseByMean());
736 detail::noiseVarianceClusterAveraging(noise, clusters, result, quantile);
739 template <
class Functor,
740 class SrcIterator,
class SrcAccessor,
741 class DestIterator,
class DestAccessor>
743 noiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
744 DestIterator dul, DestAccessor dest,
745 NoiseNormalizationOptions
const & options)
747 ArrayVector<TinyVector<double, 2> > noiseData;
748 noiseVarianceEstimationImpl(sul, slr, src, noiseData, options);
750 if(noiseData.size() < 10)
753 ArrayVector<TinyVector<double, 2> > noiseClusters;
755 noiseVarianceClusteringImpl(noiseData, noiseClusters,
756 options.cluster_count, options.averaging_quantile);
763 template <
class SrcIterator,
class SrcAccessor,
764 class DestIterator,
class DestAccessor>
766 nonparametricNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
767 DestIterator dul, DestAccessor dest,
768 NoiseNormalizationOptions
const & options,
771 typedef typename SrcAccessor::value_type SrcType;
772 typedef typename DestAccessor::value_type DestType;
773 return noiseNormalizationImpl<NonparametricNoiseNormalizationFunctor<SrcType, DestType> >
774 (sul, slr, src, dul, dest, options);
777 template <
class SrcIterator,
class SrcAccessor,
778 class DestIterator,
class DestAccessor>
780 nonparametricNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
781 DestIterator dul, DestAccessor dest,
782 NoiseNormalizationOptions
const & options,
785 int bands = src.size(sul);
786 for(
int b=0; b<bands; ++b)
788 VectorElementAccessor<SrcAccessor> sband(b, src);
789 VectorElementAccessor<DestAccessor> dband(b, dest);
793 if(!noiseNormalizationImpl<NonparametricNoiseNormalizationFunctor<SrcType, DestType> >
794 (sul, slr, sband, dul, dband, options))
800 template <
class SrcIterator,
class SrcAccessor,
801 class DestIterator,
class DestAccessor>
803 quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
804 DestIterator dul, DestAccessor dest,
805 NoiseNormalizationOptions
const & options,
808 typedef typename SrcAccessor::value_type SrcType;
809 typedef typename DestAccessor::value_type DestType;
810 return noiseNormalizationImpl<QuadraticNoiseNormalizationFunctor<SrcType, DestType> >
811 (sul, slr, src, dul, dest, options);
814 template <
class SrcIterator,
class SrcAccessor,
815 class DestIterator,
class DestAccessor>
817 quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
818 DestIterator dul, DestAccessor dest,
819 NoiseNormalizationOptions
const & options,
822 int bands = src.size(sul);
823 for(
int b=0; b<bands; ++b)
825 VectorElementAccessor<SrcAccessor> sband(b, src);
826 VectorElementAccessor<DestAccessor> dband(b, dest);
830 if(!noiseNormalizationImpl<QuadraticNoiseNormalizationFunctor<SrcType, DestType> >
831 (sul, slr, sband, dul, dband, options))
837 template <
class SrcIterator,
class SrcAccessor,
838 class DestIterator,
class DestAccessor>
840 quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
841 DestIterator dul, DestAccessor dest,
842 double a0,
double a1,
double a2,
845 ArrayVector<TinyVector<double, 2> > noiseClusters;
846 noiseClusters.push_back(TinyVector<double, 2>(0.0, a0));
847 noiseClusters.push_back(TinyVector<double, 2>(1.0, a0 + a1 + a2));
848 noiseClusters.push_back(TinyVector<double, 2>(2.0, a0 + 2.0*a1 + 4.0*a2));
850 QuadraticNoiseNormalizationFunctor<
typename SrcAccessor::value_type,
851 typename DestAccessor::value_type>(noiseClusters));
854 template <
class SrcIterator,
class SrcAccessor,
855 class DestIterator,
class DestAccessor>
857 quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
858 DestIterator dul, DestAccessor dest,
859 double a0,
double a1,
double a2,
862 int bands = src.size(sul);
863 for(
int b=0; b<bands; ++b)
865 VectorElementAccessor<SrcAccessor> sband(b, src);
866 VectorElementAccessor<DestAccessor> dband(b, dest);
867 quadraticNoiseNormalizationImpl(sul, slr, sband, dul, dband, a0, a1, a2, VigraTrueType());
871 template <
class SrcIterator,
class SrcAccessor,
872 class DestIterator,
class DestAccessor>
874 linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
875 DestIterator dul, DestAccessor dest,
876 NoiseNormalizationOptions
const & options,
879 typedef typename SrcAccessor::value_type SrcType;
880 typedef typename DestAccessor::value_type DestType;
881 return noiseNormalizationImpl<LinearNoiseNormalizationFunctor<SrcType, DestType> >
882 (sul, slr, src, dul, dest, options);
885 template <
class SrcIterator,
class SrcAccessor,
886 class DestIterator,
class DestAccessor>
888 linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
889 DestIterator dul, DestAccessor dest,
890 NoiseNormalizationOptions
const & options,
893 int bands = src.size(sul);
894 for(
int b=0; b<bands; ++b)
896 VectorElementAccessor<SrcAccessor> sband(b, src);
897 VectorElementAccessor<DestAccessor> dband(b, dest);
901 if(!noiseNormalizationImpl<LinearNoiseNormalizationFunctor<SrcType, DestType> >
902 (sul, slr, sband, dul, dband, options))
908 template <
class SrcIterator,
class SrcAccessor,
909 class DestIterator,
class DestAccessor>
911 linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
912 DestIterator dul, DestAccessor dest,
913 double a0,
double a1,
916 ArrayVector<TinyVector<double, 2> > noiseClusters;
917 noiseClusters.push_back(TinyVector<double, 2>(0.0, a0));
918 noiseClusters.push_back(TinyVector<double, 2>(1.0, a0 + a1));
920 LinearNoiseNormalizationFunctor<
typename SrcAccessor::value_type,
921 typename DestAccessor::value_type>(noiseClusters));
924 template <
class SrcIterator,
class SrcAccessor,
925 class DestIterator,
class DestAccessor>
927 linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
928 DestIterator dul, DestAccessor dest,
929 double a0,
double a1,
932 int bands = src.size(sul);
933 for(
int b=0; b<bands; ++b)
935 VectorElementAccessor<SrcAccessor> sband(b, src);
936 VectorElementAccessor<DestAccessor> dband(b, dest);
937 linearNoiseNormalizationImpl(sul, slr, sband, dul, dband, a0, a1, VigraTrueType());
944 struct noiseVarianceEstimation_can_only_work_on_scalar_images
945 : vigra::staticAssert::AssertBool<P>
1061 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1064 BackInsertable & result,
1067 typedef typename SrcAccessor::value_type SrcType;
1068 typedef typename NumericTraits<SrcType>::isScalar isScalar;
1070 VIGRA_STATIC_ASSERT((
1071 noiseVarianceEstimation_can_only_work_on_scalar_images<(isScalar::asBool)>));
1073 detail::noiseVarianceEstimationImpl(sul, slr, src, result, options);
1076 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1079 BackInsertable & result,
1080 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1085 template <
class T1,
class S1,
class BackInsertable>
1088 BackInsertable & result,
1089 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1184 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1187 BackInsertable & result,
1192 detail::noiseVarianceClusteringImpl(variance, result, options.cluster_count, options.averaging_quantile);
1195 template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1198 BackInsertable & result,
1199 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1204 template <
class T1,
class S1,
class BackInsertable>
1207 BackInsertable & result,
1208 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1308 template <
class SrcIterator,
class SrcAccessor,
1309 class DestIterator,
class DestAccessor>
1312 DestIterator dul, DestAccessor dest,
1315 typedef typename SrcAccessor::value_type SrcType;
1317 return detail::nonparametricNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
1318 typename NumericTraits<SrcType>::isScalar());
1321 template <
class SrcIterator,
class SrcAccessor,
1322 class DestIterator,
class DestAccessor>
1325 pair<DestIterator, DestAccessor> dest,
1326 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1331 template <
class T1,
class S1,
1335 MultiArrayView<2, T2, S2> dest,
1336 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1338 vigra_precondition(src.shape() == dest.shape(),
1339 "nonparametricNoiseNormalization(): shape mismatch between input and output.");
1468 template <
class SrcIterator,
class SrcAccessor,
1469 class DestIterator,
class DestAccessor>
1472 DestIterator dul, DestAccessor dest,
1475 typedef typename SrcAccessor::value_type SrcType;
1477 return detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
1478 typename NumericTraits<SrcType>::isScalar());
1481 template <
class SrcIterator,
class SrcAccessor,
1482 class DestIterator,
class DestAccessor>
1485 pair<DestIterator, DestAccessor> dest,
1486 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1491 template <
class T1,
class S1,
1495 MultiArrayView<2, T2, S2> dest,
1496 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1498 vigra_precondition(src.shape() == dest.shape(),
1499 "quadraticNoiseNormalization(): shape mismatch between input and output.");
1510 template <
class SrcIterator,
class SrcAccessor,
1511 class DestIterator,
class DestAccessor>
1514 DestIterator dul, DestAccessor dest,
1515 double a0,
double a1,
double a2)
1517 typedef typename SrcAccessor::value_type SrcType;
1519 detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a1, a2,
1520 typename NumericTraits<SrcType>::isScalar());
1523 template <
class SrcIterator,
class SrcAccessor,
1524 class DestIterator,
class DestAccessor>
1527 pair<DestIterator, DestAccessor> dest,
1528 double a0,
double a1,
double a2)
1533 template <
class T1,
class S1,
1537 MultiArrayView<2, T2, S2> dest,
1538 double a0,
double a1,
double a2)
1540 vigra_precondition(src.shape() == dest.shape(),
1541 "quadraticNoiseNormalization(): shape mismatch between input and output.");
1671 template <
class SrcIterator,
class SrcAccessor,
1672 class DestIterator,
class DestAccessor>
1675 DestIterator dul, DestAccessor dest,
1678 typedef typename SrcAccessor::value_type SrcType;
1680 return detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
1681 typename NumericTraits<SrcType>::isScalar());
1684 template <
class SrcIterator,
class SrcAccessor,
1685 class DestIterator,
class DestAccessor>
1688 pair<DestIterator, DestAccessor> dest,
1689 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1694 template <
class T1,
class S1,
1698 MultiArrayView<2, T2, S2> dest,
1699 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1701 vigra_precondition(src.shape() == dest.shape(),
1702 "linearNoiseNormalization(): shape mismatch between input and output.");
1713 template <
class SrcIterator,
class SrcAccessor,
1714 class DestIterator,
class DestAccessor>
1717 DestIterator dul, DestAccessor dest,
1718 double a0,
double a1)
1720 typedef typename SrcAccessor::value_type SrcType;
1722 detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a1,
1723 typename NumericTraits<SrcType>::isScalar());
1726 template <
class SrcIterator,
class SrcAccessor,
1727 class DestIterator,
class DestAccessor>
1730 pair<DestIterator, DestAccessor> dest,
1731 double a0,
double a1)
1736 template <
class T1,
class S1,
1740 MultiArrayView<2, T2, S2> dest,
1741 double a0,
double a1)
1743 vigra_precondition(src.shape() == dest.shape(),
1744 "linearNoiseNormalization(): shape mismatch between input and output.");
Definition: array_vector.hxx:514
Pass options to one of the noise normalization functions.
Definition: noise_normalization.hxx:90
NoiseNormalizationOptions()
Definition: noise_normalization.hxx:95
NoiseNormalizationOptions & useGradient(bool r)
Definition: noise_normalization.hxx:109
NoiseNormalizationOptions & clusterCount(unsigned int c)
Definition: noise_normalization.hxx:132
NoiseNormalizationOptions & windowRadius(unsigned int r)
Definition: noise_normalization.hxx:119
NoiseNormalizationOptions & noiseEstimationQuantile(double quantile)
Definition: noise_normalization.hxx:161
NoiseNormalizationOptions & noiseVarianceInitialGuess(double guess)
Definition: noise_normalization.hxx:174
NoiseNormalizationOptions & averagingQuantile(double quantile)
Definition: noise_normalization.hxx:147
ACCESSOR::component_type value_type
Definition: accessor.hxx:546
void outer(const MultiArrayView< 2, T, C1 > &x, const MultiArrayView< 2, T, C2 > &y, MultiArrayView< 2, T, C3 > &r)
Definition: matrix.hxx:1459
bool closeAtTolerance(T1 l, T2 r, typename PromoteTraits< T1, T2 >::Promote epsilon)
Tolerance based floating-point equality.
Definition: mathutil.hxx:1638
bool nonparametricNoiseNormalization(...)
Noise normalization by means of an estimated non-parametric noise model.
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition: tinyvector.hxx:2073
void separableConvolveX(...)
Performs a 1 dimensional convolution in x direction.
void localMinima(...)
Find local minima in an image or multi-dimensional array.
NumericTraits< T >::Promote sq(T t)
The square function.
Definition: mathutil.hxx:382
detail::SelectIntegerType< 8, detail::UnsignedIntTypes >::type UInt8
8-bit unsigned int
Definition: sized_int.hxx:179
detail::SelectIntegerType< 16, detail::UnsignedIntTypes >::type UInt16
16-bit unsigned int
Definition: sized_int.hxx:181
void noiseVarianceClustering(...)
Determine the noise variance as a function of the image intensity and cluster the results.
doxygen_overloaded_function(template<... > void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
bool linearNoiseNormalization(...)
Noise normalization by means of an estimated or given linear noise model.
std::string asString(T t)(...)
void noiseVarianceEstimation(...)
Determine the noise variance as a function of the image intensity.
void combineTwoImages(...)
Combine two source images into destination image.
void discErosion(...)
Apply erosion (minimum) filter with disc of given radius to image.
bool quadraticNoiseNormalization(...)
Noise normalization by means of an estimated or given quadratic noise model.
void separableConvolveY(...)
Performs a 1 dimensional convolution in y direction.
BasicImage< UInt8 > BImage
Definition: stdimage.hxx:62