Hi Zbynek,
The best way is by using the MRS noise estimation algorithm. See pcl/ATrousWaveletTransform.h for references and documentation on these routines; in particular, look for the NoiseKSigma() and NoiseMRS() member functions.
The following snippet is an adaptation of actual code from the ImageIntegration tool:
/*
* 5x5 B3-spline wavelet scaling function. Used by the noise estimation
* routines.
*
* Kernel filter coefficients:
*
* 1.0/256, 1.0/64, 3.0/128, 1.0/64, 1.0/256,
* 1.0/64, 1.0/16, 3.0/32, 1.0/16, 1.0/64,
* 3.0/128, 3.0/32, 9.0/64, 3.0/32, 3.0/128,
* 1.0/64, 1.0/16, 3.0/32, 1.0/16, 1.0/64,
* 1.0/256, 1.0/64, 3.0/128, 1.0/64, 1.0/256
*
* Note that we use this scaling function as a separable filter (row and column
* vectors) for performance reasons.
*/
// Separable filter coefficients.
const float __5x5B3Spline_hv[] = { 0.0625F, 0.25F, 0.375F, 0.25F, 0.0625F };
// Gaussian noise scaling factors
const float __5x5B3Spline_kj[] =
{ 0.8907F, 0.2007F, 0.0856F, 0.0413F, 0.0205F, 0.0103F, 0.0052F, 0.0026F, 0.0013F, 0.0007F };
static const int __mrsNoiseEvaluationLayers = 3;
static const float __mrsMinDataFraction = 0.02;
// ...
template <class P>
static FVector NoiseSigma( const Generic2DImage<P>& img )
{
FVector noise( img.NumberOfNominalChannels() );
SeparableFilter H( __5x5B3Spline_hv, __5x5B3Spline_hv, 5 );
ATrousWaveletTransform W( H, __mrsNoiseEvaluationLayers );
SpinStatus spin;
img.SetStatusCallback( &spin );
img.Status().Initialize( "MRS noise evaluation" );
img.Status().DisableInitialization();
for ( int c = 0; c < img.NumberOfNominalChannels(); ++c )
{
img.SelectChannel( c );
W << img;
double s0 = W.NoiseKSigma( 0 )/__5x5B3Spline_kj[0];
size_type N;
noise[c] = W.NoiseMRS( ImageVariant( &img ), __5x5B3Spline_kj, s0, 3, &N );
if ( noise[c] == 0 )
{
console.WriteLn( "<end><cbr>** Warning: No convergence in MRS noise estimation routine"
" - using k-sigma noise estimate." );
noise[c] = s0;
}
else if ( N < __mrsMinDataFraction*img.NumberOfPixels() )
{
console.WriteLn( "<end><cbr>** Warning: No significant data in MRS noise estimation routine"
" - using k-sigma noise estimate." );
noise[c] = s0;
}
}
img.Status().Complete();
img.Status().EnableInitialization();
img.SetStatusCallback( 0 );
return noise;
}
The code above is perfectible (it is a sum of fragment out of their actual context). In particular, the above routine doesn't need to be a template (you can work with ImageVariant). I hope you get the idea, though. Let me know if you need more information.