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;
189template <
class ArgumentType,
class ResultType>
190class 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);
253template <
class ArgumentType,
class ResultType>
254class 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);
311template <
class ArgumentType,
class ResultType>
312class 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) \
365template <class ResultType> \
366class 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 \
391VIGRA_NoiseNormalizationFunctor(NonparametricNoiseNormalizationFunctor,
UInt8, 256)
392VIGRA_NoiseNormalizationFunctor(NonparametricNoiseNormalizationFunctor,
UInt16, 65536)
393VIGRA_NoiseNormalizationFunctor(QuadraticNoiseNormalizationFunctor,
UInt8, 256)
394VIGRA_NoiseNormalizationFunctor(QuadraticNoiseNormalizationFunctor,
UInt16, 65536)
395VIGRA_NoiseNormalizationFunctor(LinearNoiseNormalizationFunctor,
UInt8, 256)
396VIGRA_NoiseNormalizationFunctor(LinearNoiseNormalizationFunctor,
UInt16, 65536)
398#undef VIGRA_NoiseNormalizationFunctor
402template <
class SrcIterator,
class SrcAcessor,
405iterativeNoiseEstimationChi2(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);
457template <
class SrcIterator,
class SrcAcessor,
460iterativeNoiseEstimationGauss(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);
515template <
class SrcIterator,
class SrcAccessor,
516 class DestIterator,
class DestAccessor>
518symmetricDifferenceSquaredMagnitude(
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());
539template <
class SrcIterator,
class SrcAccessor,
540 class DestIterator,
class DestAccessor>
542findHomogeneousRegionsFoerstner(
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);
559template <
class SrcIterator,
class SrcAccessor,
560 class DestIterator,
class DestAccessor>
562findHomogeneousRegions(
563 SrcIterator sul, SrcIterator slr, SrcAccessor src,
564 DestIterator dul, DestAccessor dest)
569template <
class Vector1,
class Vector2>
570void 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));
620struct SortNoiseByMean
623 bool operator()(T
const & l, T
const & r)
const
629struct SortNoiseByVariance
632 bool operator()(T
const & l, T
const & r)
const
638template <
class Vector1,
class Vector2,
class Vector3>
639void 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));
671template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
672void noiseVarianceEstimationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
673 BackInsertable & result,
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;
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));
725template <
class Vector,
class BackInsertable>
726void noiseVarianceClusteringImpl(Vector & noise, BackInsertable & result,
727 unsigned int clusterCount,
double quantile)
729 std::sort(noise.begin(), noise.end(), detail::SortNoiseByMean());
732 detail::noiseVarianceListMedianCut(noise, clusters, clusterCount);
734 std::sort(clusters.
begin(), clusters.
end(), detail::SortNoiseByMean());
736 detail::noiseVarianceClusterAveraging(noise, clusters, result, quantile);
739template <
class Functor,
740 class SrcIterator,
class SrcAccessor,
741 class DestIterator,
class DestAccessor>
743noiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
744 DestIterator dul, DestAccessor dest,
748 noiseVarianceEstimationImpl(sul, slr, src, noiseData, options);
750 if(noiseData.
size() < 10)
755 noiseVarianceClusteringImpl(noiseData, noiseClusters,
756 options.cluster_count, options.averaging_quantile);
763template <
class SrcIterator,
class SrcAccessor,
764 class DestIterator,
class DestAccessor>
766nonparametricNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
767 DestIterator dul, DestAccessor dest,
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);
777template <
class SrcIterator,
class SrcAccessor,
778 class DestIterator,
class DestAccessor>
780nonparametricNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
781 DestIterator dul, DestAccessor dest,
785 int bands = src.size(sul);
786 for(
int b=0; b<bands; ++b)
793 if(!noiseNormalizationImpl<NonparametricNoiseNormalizationFunctor<SrcType, DestType> >
794 (sul, slr, sband, dul, dband, options))
800template <
class SrcIterator,
class SrcAccessor,
801 class DestIterator,
class DestAccessor>
803quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
804 DestIterator dul, DestAccessor dest,
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);
814template <
class SrcIterator,
class SrcAccessor,
815 class DestIterator,
class DestAccessor>
817quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
818 DestIterator dul, DestAccessor dest,
822 int bands = src.size(sul);
823 for(
int b=0; b<bands; ++b)
830 if(!noiseNormalizationImpl<QuadraticNoiseNormalizationFunctor<SrcType, DestType> >
831 (sul, slr, sband, dul, dband, options))
837template <
class SrcIterator,
class SrcAccessor,
838 class DestIterator,
class DestAccessor>
840quadraticNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
841 DestIterator dul, DestAccessor dest,
842 double a0,
double a1,
double a2,
850 QuadraticNoiseNormalizationFunctor<
typename SrcAccessor::value_type,
851 typename DestAccessor::value_type>(noiseClusters));
854template <
class SrcIterator,
class SrcAccessor,
855 class DestIterator,
class DestAccessor>
857quadraticNoiseNormalizationImpl(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)
867 quadraticNoiseNormalizationImpl(sul, slr, sband, dul, dband, a0, a1, a2, VigraTrueType());
871template <
class SrcIterator,
class SrcAccessor,
872 class DestIterator,
class DestAccessor>
874linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
875 DestIterator dul, DestAccessor dest,
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);
885template <
class SrcIterator,
class SrcAccessor,
886 class DestIterator,
class DestAccessor>
888linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
889 DestIterator dul, DestAccessor dest,
893 int bands = src.size(sul);
894 for(
int b=0; b<bands; ++b)
901 if(!noiseNormalizationImpl<LinearNoiseNormalizationFunctor<SrcType, DestType> >
902 (sul, slr, sband, dul, dband, options))
908template <
class SrcIterator,
class SrcAccessor,
909 class DestIterator,
class DestAccessor>
911linearNoiseNormalizationImpl(SrcIterator sul, SrcIterator slr, SrcAccessor src,
912 DestIterator dul, DestAccessor dest,
913 double a0,
double a1,
920 LinearNoiseNormalizationFunctor<
typename SrcAccessor::value_type,
921 typename DestAccessor::value_type>(noiseClusters));
924template <
class SrcIterator,
class SrcAccessor,
925 class DestIterator,
class DestAccessor>
927linearNoiseNormalizationImpl(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)
937 linearNoiseNormalizationImpl(sul, slr, sband, dul, dband, a0, a1, VigraTrueType());
944struct noiseVarianceEstimation_can_only_work_on_scalar_images
945: vigra::staticAssert::AssertBool<P>
1061template <
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);
1076template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1079 BackInsertable & result,
1085template <
class T1,
class S1,
class BackInsertable>
1088 BackInsertable & result,
1184template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1187 BackInsertable & result,
1192 detail::noiseVarianceClusteringImpl(variance, result, options.cluster_count, options.averaging_quantile);
1195template <
class SrcIterator,
class SrcAccessor,
class BackInsertable>
1198 BackInsertable & result,
1204template <
class T1,
class S1,
class BackInsertable>
1207 BackInsertable & result,
1308template <
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());
1321template <
class SrcIterator,
class SrcAccessor,
1322 class DestIterator,
class DestAccessor>
1325 pair<DestIterator, DestAccessor> dest,
1331template <
class T1,
class S1,
1338 vigra_precondition(src.
shape() == dest.
shape(),
1339 "nonparametricNoiseNormalization(): shape mismatch between input and output.");
1468template <
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());
1481template <
class SrcIterator,
class SrcAccessor,
1482 class DestIterator,
class DestAccessor>
1485 pair<DestIterator, DestAccessor> dest,
1491template <
class T1,
class S1,
1498 vigra_precondition(src.
shape() == dest.
shape(),
1499 "quadraticNoiseNormalization(): shape mismatch between input and output.");
1510template <
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());
1523template <
class SrcIterator,
class SrcAccessor,
1524 class DestIterator,
class DestAccessor>
1527 pair<DestIterator, DestAccessor> dest,
1528 double a0,
double a1,
double a2)
1533template <
class T1,
class S1,
1538 double a0,
double a1,
double a2)
1540 vigra_precondition(src.
shape() == dest.
shape(),
1541 "quadraticNoiseNormalization(): shape mismatch between input and output.");
1671template <
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());
1684template <
class SrcIterator,
class SrcAccessor,
1685 class DestIterator,
class DestAccessor>
1688 pair<DestIterator, DestAccessor> dest,
1694template <
class T1,
class S1,
1701 vigra_precondition(src.
shape() == dest.
shape(),
1702 "linearNoiseNormalization(): shape mismatch between input and output.");
1713template <
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());
1726template <
class SrcIterator,
class SrcAccessor,
1727 class DestIterator,
class DestAccessor>
1730 pair<DestIterator, DestAccessor> dest,
1731 double a0,
double a1)
1736template <
class T1,
class S1,
1741 double a0,
double a1)
1743 vigra_precondition(src.
shape() == dest.
shape(),
1744 "linearNoiseNormalization(): shape mismatch between input and output.");
const_iterator begin() const
Definition: array_vector.hxx:223
size_type size() const
Definition: array_vector.hxx:358
const_iterator end() const
Definition: array_vector.hxx:237
Definition: array_vector.hxx:514
Fundamental class template for images.
Definition: basicimage.hxx:476
Two dimensional difference vector.
Definition: diff2d.hxx:186
Base class for, and view to, vigra::MultiArray.
Definition: multi_array.hxx:705
const difference_type & shape() const
Definition: multi_array.hxx:1648
Pass options to one of the noise normalization functions.
Definition: noise_normalization.hxx:90
NoiseNormalizationOptions & noiseEstimationQuantile(double quantile)
Definition: noise_normalization.hxx:161
NoiseNormalizationOptions()
Definition: noise_normalization.hxx:95
NoiseNormalizationOptions & windowRadius(unsigned int r)
Definition: noise_normalization.hxx:119
NoiseNormalizationOptions & averagingQuantile(double quantile)
Definition: noise_normalization.hxx:147
NoiseNormalizationOptions & useGradient(bool r)
Definition: noise_normalization.hxx:109
NoiseNormalizationOptions & clusterCount(unsigned int c)
Definition: noise_normalization.hxx:132
NoiseNormalizationOptions & noiseVarianceInitialGuess(double guess)
Definition: noise_normalization.hxx:174
Accessor for one component of a vector.
Definition: accessor.hxx:540
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
detail::SelectIntegerType< 8, detail::UnsignedIntTypes >::type UInt8
8-bit unsigned int
Definition: sized_int.hxx:179
void separableConvolveX(...)
Performs a 1 dimensional convolution in x direction.
bool linearNoiseNormalization(...)
Noise normalization by means of an estimated or given linear noise model.
bool nonparametricNoiseNormalization(...)
Noise normalization by means of an estimated non-parametric noise model.
void noiseVarianceEstimation(...)
Determine the noise variance as a function of the image intensity.
NumericTraits< T >::Promote sq(T t)
The square function.
Definition: mathutil.hxx:382
detail::SelectIntegerType< 16, detail::UnsignedIntTypes >::type UInt16
16-bit unsigned int
Definition: sized_int.hxx:181
void separableConvolveY(...)
Performs a 1 dimensional convolution in y direction.
bool quadraticNoiseNormalization(...)
Noise normalization by means of an estimated or given quadratic noise model.
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements
Definition: tinyvector.hxx:2073
void combineTwoImages(...)
Combine two source images into destination image.
doxygen_overloaded_function(template<... > void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
void localMinima(...)
Find local minima in an image or multi-dimensional array.
bool closeAtTolerance(T1 l, T2 r, typename PromoteTraits< T1, T2 >::Promote epsilon)
Tolerance based floating-point equality.
Definition: mathutil.hxx:1638
void discErosion(...)
Apply erosion (minimum) filter with disc of given radius to image.
std::string asString(T t)(...)
void noiseVarianceClustering(...)
Determine the noise variance as a function of the image intensity and cluster the results.