TuttleOFX
1
|
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