TuttleOFX  1
noiseAnalysis.hpp
Go to the documentation of this file.
00001 /**
00002  * @brief This file provides a set of reimplementations of CImg functions by means of the generic image library (gil).
00003  *        Functions for noise analysis
00004  */
00005 #ifndef _NOISE_ANALYSIS_HPP_
00006 #define _NOISE_ANALYSIS_HPP_
00007 
00008 #include <cmath>
00009 #include "boost/gil/gil_all.hpp"
00010 
00011 namespace tuttle {
00012 namespace imageUtils {
00013 
00014 namespace bgil = boost::gil;
00015 
00016 /**
00017  * @brief Compute somme pseudo-residuals
00018  * The pseudo residual r_i of the image Y_i are so thar E[r_i^2] = E[Y_i^2].
00019  * This is the 2D pseudo-implementation.
00020  */
00021 template <class S_VIEW, class D_VIEW>
00022 D_VIEW & pseudo_residual( S_VIEW & src, D_VIEW & dst )
00023 {
00024     using namespace boost::gil;
00025     typedef typename S_VIEW::locator Loc;
00026     typedef typename D_VIEW::x_iterator dxIterator;
00027     typedef typename channel_type<D_VIEW>::type pix_t;
00028 
00029     int w = src.width( );
00030     int h = src.height( );
00031     int nc = src.num_channels( );
00032     int x, y, c;
00033     double t2;
00034 
00035     gil_function_requires< ColorSpacesCompatibleConcept<
00036                            typename color_space_type<S_VIEW>::type,
00037                            typename color_space_type<D_VIEW>::type > > ( );
00038 
00039     for( y = 0; y < h; ++y )
00040     {
00041         dxIterator dst_it = dst.row_begin( y );
00042 
00043         for( x = 0; x < w; ++x )
00044         {
00045             Loc loc = src.xy_at( x, y );
00046             for( c = 0; c < nc; ++c )
00047             {
00048                 t2 = 0;
00049                 if( x == 0 )
00050                     t2 += loc( 1, 0 )[c];
00051                 else
00052                     t2 += loc( -1, 0 )[c];
00053                 if( x == w - 1 )
00054                     t2 += loc( -1, 0 )[c];
00055                 else
00056                     t2 += loc( 1, 0 )[c];
00057                 if( y == 0 )
00058                     t2 += loc( 0, 1 )[c];
00059                 else
00060                     t2 += loc( 0, -1 )[c];
00061                 if( y == h - 1 )
00062                     t2 += loc( 0, -1 )[c];
00063                 else
00064                     t2 += loc( 0, 1 )[c];
00065                 ( *dst_it )[c] = ( pix_t ) ( 0.223606798 * ( 4.0 * ( double ) loc( 0, 0 )[c] - t2 ) );
00066             }
00067             dst_it++;
00068         }
00069     }
00070     return dst;
00071 }
00072 
00073 /**
00074  * @brief Return the variance and the mean of the image
00075  * Least Mean of Square
00076  */
00077 template<class S_VIEW, typename t>
00078 double variance_mean( S_VIEW & src, t& mean )
00079 {
00080     typedef typename S_VIEW::x_iterator sxIterator;
00081     int w = src.width( );
00082     int h = src.height( );
00083     int nc = src.num_channels( );
00084     int x, y, c;
00085     double variance = 0, average = 0;
00086     const unsigned int siz = w * h * nc;
00087     double S = 0, S2 = 0;
00088 
00089     for( y = 0; y < h; ++y )
00090     {
00091         sxIterator src_it = src.row_begin( y );
00092         for( x = 0; x < w; ++x )
00093         {
00094             for( c = 0; c < nc; c++ )
00095             {
00096                 const double val = ( *src_it )[c];
00097                 S += val;
00098                 S2 += val * val;
00099             }
00100             ++src_it;
00101         }
00102     }
00103     variance = ( S2 - S * S / siz ) / siz;
00104     average = S;
00105     mean = ( t ) ( average / siz );
00106     return variance;
00107 }
00108 
00109 
00110 
00111 /**
00112  * @brief Robustly estimatate the variance of a the noise using the pseudo-residuals.
00113  * @see variance_estimation()
00114  */
00115 template <class S_VIEW>
00116 double noise_variance( S_VIEW & src )
00117 {
00118     double mean;
00119     typename image_from_view<S_VIEW>::type tmp( src.dimensions() );
00120     S_VIEW v_tmp( view( tmp ) );
00121     return variance_mean( pseudo_residual( src, v_tmp ), mean );
00122 }
00123 
00124 }
00125 }
00126 
00127 #endif
00128