TePDIRadarGammaFilter.cpp

Go to the documentation of this file.
00001 #include "TePDIRadarGammaFilter.hpp"
00002 
00003 #include "../kernel/TeAgnostic.h"
00004 #include "TePDIUtils.hpp"
00005 
00006 #include "math.h"
00007 
00008 TePDIRadarGammaFilter::TePDIRadarGammaFilter()
00009 {
00010 }
00011 
00012 
00013 TePDIRadarGammaFilter::~TePDIRadarGammaFilter()
00014 {
00015 }
00016 
00017 
00018 void TePDIRadarGammaFilter::ResetState( const TePDIParameters& params )
00019 {
00020   TePDIRadarFilter::ResetState( params );
00021 }
00022 
00023 
00024 bool TePDIRadarGammaFilter::CheckParameters( 
00025   const TePDIParameters& parameters ) const
00026 {
00027   /* Checking for general required parameters */
00028 
00029   TePDITypes::TePDIRasterPtrType inRaster;
00030   if( ! parameters.GetParameter( "input_image", inRaster ) ) {
00031 
00032     TEAGN_LOGERR( "Missing parameter: input_image" );
00033     return false;
00034   }
00035   if( ! inRaster.isActive() ) {
00036 
00037     TEAGN_LOGERR( "Invalid parameter: input_image inactive" );
00038     return false;
00039   }
00040   if( inRaster->params().status_ == TeRasterParams::TeNotReady ) {
00041 
00042     TEAGN_LOGERR( "Invalid parameter: input_image not ready" );
00043     return false;
00044   }
00045 
00046   TePDITypes::TePDIRasterPtrType outRaster;
00047   if( ! parameters.GetParameter( "output_image", outRaster ) ) {
00048 
00049     TEAGN_LOGERR( "Missing parameter: output_image" );
00050     return false;
00051   }
00052   if( ! outRaster.isActive() ) {
00053 
00054     TEAGN_LOGERR( "Invalid parameter: output_image inactive" );
00055     return false;
00056   }
00057   if( inRaster->params().status_ == TeRasterParams::TeReadyToWrite ) {
00058 
00059     TEAGN_LOGERR( "Invalid parameter: output_image not ready" );
00060     return false;
00061   }
00062 
00063   /* Filter type checking */
00064   TePDIGammaFType filter_type;
00065   if( ! parameters.GetParameter( "filter_type", filter_type ) ) {
00066 
00067     TEAGN_LOGERR( "Missing parameter: filter_type" );
00068     return false;
00069   }
00070   if( ( filter_type != TePDIGammaFixedType ) &&
00071       ( filter_type != TePDIGammaAdaptType ) ) {
00072 
00073     TEAGN_LOGERR( "Invalid parameter: filter_type" );
00074     return false;
00075   }
00076 
00077   /* channels parameter checking */
00078 
00079   std::vector< int > channels;
00080   if( ! parameters.GetParameter( "channels", channels ) ) {
00081 
00082     TEAGN_LOGERR( "Missing parameter: channels" );
00083     return false;
00084   }
00085   for( unsigned int index = 0 ; index < channels.size() ; ++index ) {
00086     if( channels[ index ] >= inRaster->nBands() ) {
00087       TEAGN_LOGERR( "Invalid parameter: channels" );
00088       return false;
00089     }
00090   }
00091 
00092   /* Checking for number of iterations */
00093 
00094   int iterations = 0;
00095   if( ! parameters.GetParameter( "iterations", iterations ) ) {
00096 
00097     TEAGN_LOGERR( "Missing parameter: iterations" );
00098     return false;
00099   }
00100   TEAGN_TRUE_OR_RETURN( iterations > 0, "Invalid iterations number" );
00101 
00102   /* Checking for detection type parameter */
00103 
00104   TePDIGammaDetType det_type;
00105   TEAGN_TRUE_OR_RETURN( parameters.GetParameter( "det_type", det_type ),
00106     "Missing parameter: det_type" );
00107   TEAGN_TRUE_OR_RETURN(
00108     ( ( det_type == TePDIGammaDTLinear ) || ( det_type == TePDIGammaDTQuadratic ) ),
00109     "Invalid detection type" );
00110 
00111   /* Checking for image look number */
00112 
00113   double look_number = 0;
00114   TEAGN_TRUE_OR_RETURN( parameters.GetParameter( "look_number", look_number ),
00115     "Missing parameter: look_number" );
00116   TEAGN_TRUE_OR_RETURN( look_number > 0,  "Invalid image look number" );
00117 
00118   /* Checking for detection type parameter */
00119 
00120   int mask_width = 0;
00121   TEAGN_TRUE_OR_RETURN( parameters.GetParameter( "mask_width", mask_width ),
00122     "Missing parameter: mask_width" );
00123   TEAGN_TRUE_OR_RETURN( ( ( mask_width > 2 ) && ( ( mask_width % 2 ) != 0 ) ),
00124     "Invalid mask width" );
00125   if( filter_type != TePDIGammaAdaptType ) {
00126     TEAGN_TRUE_OR_RETURN( ( mask_width <=  (int)max_adapt_mask_width_ ),
00127       "Invalid mask width" );
00128   }
00129 
00130   /* Checking photometric interpretation */
00131   
00132   for( unsigned int channel = 0 ; channel < channels.size() ; ++channel ) {
00133     TEAGN_TRUE_OR_RETURN( ( 
00134       ( inRaster->params().photometric_[ channel ] == 
00135         TeRasterParams::TeRGB ) ||
00136       ( inRaster->params().photometric_[ channel ] == 
00137         TeRasterParams::TeMultiBand ) ),
00138     "Invalid parameter - input_image (invalid photometric interpretation)" );
00139   }      
00140 
00141   return true;
00142 }
00143 
00144 
00145 bool TePDIRadarGammaFilter::RunImplementation()
00146 {
00147   TePDIGammaFType filter_type;
00148   params_.GetParameter( "filter_type", filter_type );
00149 
00150   switch( filter_type ) {
00151     case TePDIGammaFixedType :
00152     {
00153       return RunFixedImplementation();
00154       break;
00155     }
00156     default :
00157     {
00158       TEAGN_LOG_AND_RETURN( "Invalid algorithm type" );
00159     }
00160   }
00161 }
00162 
00163 bool TePDIRadarGammaFilter::RunFixedImplementation()
00164 {
00165   TePDITypes::TePDIRasterPtrType inRaster;
00166   params_.GetParameter( "input_image", inRaster );
00167 
00168   TePDITypes::TePDIRasterPtrType outRaster;
00169   params_.GetParameter( "output_image", outRaster );
00170 
00171   std::vector< int > channels;
00172   params_.GetParameter( "channels", channels );
00173 
00174   int mask_width;
00175   params_.GetParameter( "mask_width", mask_width );
00176 
00177   int iterations = 0;
00178   params_.GetParameter( "iterations", iterations );
00179 
00180   TePDIGammaDetType det_type;
00181   params_.GetParameter( "det_type", det_type );
00182 
00183   double look_number = 0;
00184   params_.GetParameter( "look_number", look_number );
00185 
00186   /* Setting the output raster */
00187 
00188   TeRasterParams outRaster_params = outRaster->params();
00189   
00190   outRaster_params.nBands( channels.size() );
00191   if( inRaster->projection() != 0 ) {
00192     TeSharedPtr< TeProjection > proj( TeProjectionFactory::make( 
00193       inRaster->projection()->params() ) );  
00194     outRaster_params.projection( proj.nakedPointer() );
00195   }
00196   outRaster_params.boxResolution( inRaster->params().box().x1(), 
00197     inRaster->params().box().y1(), inRaster->params().box().x2(), 
00198     inRaster->params().box().y2(), inRaster->params().resx_, 
00199     inRaster->params().resy_ );  
00200     
00201   outRaster_params.setPhotometric( TeRasterParams::TeMultiBand, -1 ); 
00202 
00203   TEAGN_TRUE_OR_RETURN( outRaster->init( outRaster_params ),
00204     "Output raster reset error" );         
00205 
00206   /* Creating the temporary rasters with one band each */
00207 
00208   TePDITypes::TePDIRasterPtrType aux_raster1;
00209   TePDITypes::TePDIRasterPtrType aux_raster2;
00210   
00211   TeRasterParams auxRasterParams = inRaster->params();
00212   auxRasterParams.nBands( 1 );
00213   auxRasterParams.setDataType( TeDOUBLE, -1 );
00214   
00215   if( iterations > 1  )
00216   {
00217     TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( auxRasterParams,
00218       aux_raster1 ), "Unable to create auxiliary raster 1" );
00219   }
00220 
00221   if( iterations > 2 )
00222   {
00223     TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( auxRasterParams,
00224       aux_raster2 ), "Unable to create auxiliary raster 1" );
00225   }
00226 
00227   /* Noise statistics */
00228 
00229   double noise_deviation = 0;
00230 
00231   //if( det_type == TePDIGammaDTLinear ) {
00232   //  noise_deviation = 0.522723008 / sqrt( look_number );
00233   //} else if( det_type == TePDIGammaDTQuadratic ) {
00234     noise_deviation = 1.0 / sqrt( look_number );
00235   //}
00236 
00237   const double noise_variance = noise_deviation * noise_deviation;
00238 
00239   /* Setting the convolution buffer initial state */
00240 
00241   const unsigned int raster_lines = (unsigned int)outRaster->params().nlines_;
00242   const unsigned int raster_columns = (unsigned int)outRaster->params().ncols_;
00243 
00244   reset_conv_buf( mask_width, raster_columns );
00245 
00246   /* Convolution Loop */
00247 
00248   double output_level; /* the value generated by each pixel mask calcule */
00249 
00250   unsigned int mask_middle_off_lines =
00251     (unsigned int) floor( ((double)mask_width) / 2. );
00252   unsigned int mask_middle_off_columns = mask_middle_off_lines;
00253 
00254   unsigned int conv_column_bound = raster_columns - mask_width + 1;
00255   unsigned int conv_line_bound = raster_lines - mask_width + 1;
00256 
00257   unsigned int raster_line; /* mask top-left line */
00258   unsigned int conv_buf_column; /* mask top-left column */
00259 
00260   unsigned int current_pixel_column; /* raster reference for the current pixel being
00261                                         processed */
00262 
00263   double channel_min_level;
00264   double channel_max_level;
00265 
00266   double mean; /* for the current window covolution inside convolution buffer */
00267   double variance; /* for the current window convolution inside convolution buffer */
00268   int sourceChannel = 0;
00269   int targetChannel = 0;  
00270 
00271   TePDITypes::TePDIRasterPtrType source_raster;
00272   TePDITypes::TePDIRasterPtrType target_raster;
00273   
00274   StartProgInt( "Gamma fixed filter", channels.size() * iterations * 
00275     conv_line_bound ); 
00276 
00277   for( unsigned int channels_index = 0 ; channels_index < channels.size() ;
00278        ++channels_index ) 
00279   {
00280     for( int iteration = 0 ; (int)iteration < iterations ; 
00281       ++iteration ) 
00282     {
00283       /* Switching rasters */
00284 
00285       if( iteration == 0 ) 
00286       {
00287         source_raster = inRaster;
00288         sourceChannel = channels[ channels_index ];
00289         
00290         if( iterations > 1 )
00291         {
00292           target_raster = aux_raster1;
00293           targetChannel = 0;
00294         }
00295         else
00296         {
00297           target_raster = outRaster;
00298           targetChannel = channels_index;
00299         }
00300       }
00301       else if( iteration == ( iterations - 1 ) )
00302       {
00303         source_raster = target_raster;
00304         sourceChannel = targetChannel;
00305         
00306         target_raster = outRaster;
00307         targetChannel = channels_index;
00308       }
00309       else 
00310       {
00311         source_raster = target_raster;
00312         sourceChannel = targetChannel;
00313         
00314         if( target_raster == aux_raster1 )
00315         {
00316           target_raster = aux_raster2;
00317         }
00318         else
00319         {
00320           target_raster = aux_raster1;
00321         }
00322         targetChannel = 0;
00323       }
00324       
00325       TEAGN_TRUE_OR_RETURN( TePDIUtils::TeGetRasterMinMaxBounds(
00326         target_raster, targetChannel, channel_min_level,
00327         channel_max_level ), "Unable to get raster channel level bounds" );      
00328 
00329       /* Fills the convolution buffer with the first "mask_lines" from the raster */
00330 
00331       for( int line = 0 ; line < ( mask_width - 1) ; ++line ) {
00332         up_conv_buf( source_raster, line, sourceChannel );
00333       }
00334 
00335       /* window convolution over raster */
00336 
00337       for( raster_line = 0 ; raster_line < conv_line_bound ; ++raster_line ) {
00338         /* Getting one more line from the source raster and adding to buffer */
00339         
00340         TEAGN_FALSE_OR_RETURN( UpdateProgInt( ( channels_index * iterations * 
00341           conv_line_bound ) +
00342           ( iteration * conv_line_bound ) + raster_line ),
00343           "Canceled by the user" );
00344 
00345         up_conv_buf( source_raster, raster_line + mask_width - 1,
00346           sourceChannel );
00347 
00348         for( conv_buf_column = 0 ; conv_buf_column < conv_column_bound ;
00349              ++conv_buf_column ) 
00350         {
00351           current_pixel_column = conv_buf_column +  mask_middle_off_columns;
00352 
00353           conv_buf_estatistics( 0, conv_buf_column, mask_width, mask_width, mean,
00354             variance );
00355 
00356                   double zval = conv_buf_[ mask_middle_off_lines ][ current_pixel_column ];
00357 
00358                   double c = sqrt(2.0) * noise_deviation;
00359                   double ci = sqrt(variance) / mean;
00360 
00361                   if( ci <= noise_deviation ) {
00362             output_level = mean;
00363                   //} else if( ( noise_deviation < ci ) && ( ci < c ) ) {
00364                   } else if( ( noise_deviation < ci ) && ( noise_deviation < c ) ) {
00365                         double alpha = ( 1 + noise_variance ) / ( ( ci * ci ) - noise_variance );
00366                         double b = alpha - look_number - 1;
00367                         double d = ( ( mean * mean ) * ( b * b ) ) + ( 4 * alpha * look_number * mean *
00368                           zval );
00369                         
00370                         output_level = ( ( b * mean ) + sqrt( d ) ) / ( 2 * alpha );
00371 
00372                   } else {
00373                         output_level = zval;
00374                   }
00375 
00376           /* Level range filtering */
00377 
00378           if( output_level < channel_min_level ) {
00379             output_level = channel_min_level;
00380           } else if( output_level > channel_max_level ) {
00381             output_level = channel_max_level;
00382           }
00383 
00384           TEAGN_TRUE_OR_RETURN( target_raster->setElement(
00385             current_pixel_column,
00386             raster_line +  mask_middle_off_lines, output_level, targetChannel ),
00387             "Pixel mapping error" );
00388         }
00389       }
00390     }
00391   }
00392 
00393   return true;
00394 }

Generated on Sun Jul 29 04:01:25 2012 for TerraLib - Development Source by  doxygen 1.5.3