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)
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)
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
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)
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
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);
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);
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;
586 #if 0 // turned the "internal error" in a postcondition message
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);
790 typedef typename VectorElementAccessor<SrcAccessor>::value_type SrcType;
791 typedef typename VectorElementAccessor<DestAccessor>::value_type DestType;
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);
827 typedef typename VectorElementAccessor<SrcAccessor>::value_type SrcType;
828 typedef typename VectorElementAccessor<DestAccessor>::value_type DestType;
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);
898 typedef typename VectorElementAccessor<SrcAccessor>::value_type SrcType;
899 typedef typename VectorElementAccessor<DestAccessor>::value_type DestType;
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,
1065 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
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,
1188 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
1190 ArrayVector<TinyVector<double, 2> > variance;
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,
1313 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
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,
1473 NoiseNormalizationOptions
const & options)
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,
1676 NoiseNormalizationOptions
const & options = NoiseNormalizationOptions())
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.");
1752 #endif // VIGRA_NOISE_NORMALIZATION_HXX
NoiseNormalizationOptions & noiseEstimationQuantile(double quantile)
Definition: noise_normalization.hxx:161
detail::SelectIntegerType< 8, detail::UnsignedIntTypes >::type UInt8
8-bit unsigned int
Definition: sized_int.hxx:179
linalg::TemporaryMatrix< T > exp(MultiArrayView< 2, T, C > const &v)
void localMinima(...)
Find local minima in an image or multi-dimensional array.
bool nonparametricNoiseNormalization(...)
Noise normalization by means of an estimated non-parametric noise model.
linalg::TemporaryMatrix< T > asin(MultiArrayView< 2, T, C > const &v)
NoiseNormalizationOptions & noiseVarianceInitialGuess(double guess)
Definition: noise_normalization.hxx:174
detail::SelectIntegerType< 16, detail::UnsignedIntTypes >::type UInt16
16-bit unsigned int
Definition: sized_int.hxx:181
bool linearNoiseNormalization(...)
Noise normalization by means of an estimated or given linear noise model.
void separableConvolveX(...)
Performs a 1 dimensional convolution in x direction.
NoiseNormalizationOptions()
Definition: noise_normalization.hxx:95
void discErosion(...)
Apply erosion (minimum) filter with disc of given radius to image.
BasicImage< UInt8 > BImage
Definition: stdimage.hxx:62
NoiseNormalizationOptions & averagingQuantile(double quantile)
Definition: noise_normalization.hxx:147
NumericTraits< T >::Promote sq(T t)
The square function.
Definition: mathutil.hxx:382
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition: tinyvector.hxx:2073
NoiseNormalizationOptions & clusterCount(unsigned int c)
Definition: noise_normalization.hxx:132
std::string asString(T t)(...)
void combineTwoImages(...)
Combine two source images into destination image.
NoiseNormalizationOptions & useGradient(bool r)
Definition: noise_normalization.hxx:109
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void outer(const MultiArrayView< 2, T, C1 > &x, const MultiArrayView< 2, T, C2 > &y, MultiArrayView< 2, T, C3 > &r)
Definition: matrix.hxx:1459
Pass options to one of the noise normalization functions.
Definition: noise_normalization.hxx:89
bool closeAtTolerance(T1 l, T2 r, typename PromoteTraits< T1, T2 >::Promote epsilon)
Tolerance based floating-point equality.
Definition: mathutil.hxx:1638
linalg::TemporaryMatrix< T > log(MultiArrayView< 2, T, C > const &v)
NoiseNormalizationOptions & windowRadius(unsigned int r)
Definition: noise_normalization.hxx:119
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up.
Definition: fixedpoint.hxx:675
bool quadraticNoiseNormalization(...)
Noise normalization by means of an estimated or given quadratic noise model.
void noiseVarianceEstimation(...)
Determine the noise variance as a function of the image intensity.
void noiseVarianceClustering(...)
Determine the noise variance as a function of the image intensity and cluster the results...
void separableConvolveY(...)
Performs a 1 dimensional convolution in y direction.
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root.
Definition: fixedpoint.hxx:616