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
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
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
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
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
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
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
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
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
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
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
00228
00229 double noise_deviation = 0;
00230
00231
00232
00233
00234 noise_deviation = 1.0 / sqrt( look_number );
00235
00236
00237 const double noise_variance = noise_deviation * noise_deviation;
00238
00239
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
00247
00248 double output_level;
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;
00258 unsigned int conv_buf_column;
00259
00260 unsigned int current_pixel_column;
00261
00262
00263 double channel_min_level;
00264 double channel_max_level;
00265
00266 double mean;
00267 double variance;
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
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
00330
00331 for( int line = 0 ; line < ( mask_width - 1) ; ++line ) {
00332 up_conv_buf( source_raster, line, sourceChannel );
00333 }
00334
00335
00336
00337 for( raster_line = 0 ; raster_line < conv_line_bound ; ++raster_line ) {
00338
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
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
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 }