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