00001 #include "TePDIMorfFilter.hpp"
00002
00003 #include "../kernel/TeAgnostic.h"
00004 #include "TePDIFilterMask.hpp"
00005 #include "TePDIUtils.hpp"
00006
00007 #include "math.h"
00008
00009
00010 TePDIMorfFilter::TePDIMorfFilter()
00011 {
00012 double_buffer_ = 0;
00013 }
00014
00015
00016 TePDIMorfFilter::~TePDIMorfFilter()
00017 {
00018 if( double_buffer_ ) {
00019 delete[] double_buffer_;
00020 }
00021 }
00022
00023
00024 bool TePDIMorfFilter::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::TeNotReady ) {
00058
00059 TEAGN_LOGERR( "Invalid parameter: output_image not ready" );
00060 return false;
00061 }
00062
00063
00064 TePDIMorfType 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 != TePDIMDilationType ) &&
00071 ( filter_type != TePDIMErosionType ) &&
00072 ( filter_type != TePDIMMedianType ) &&
00073 ( filter_type != TePDIMModeType ) ) {
00074
00075 TEAGN_LOGERR( "Invalid parameter: filter_type" );
00076 return false;
00077 }
00078
00079
00080
00081 std::vector< int > channels;
00082 if( ! parameters.GetParameter( "channels", channels ) ) {
00083
00084 TEAGN_LOGERR( "Missing parameter: channels" );
00085 return false;
00086 }
00087 for( unsigned int index = 0 ; index < channels.size() ; ++index ) {
00088 if( channels[ index ] >= inRaster->nBands() ) {
00089 TEAGN_LOGERR( "Invalid parameter: channels" );
00090 return false;
00091 }
00092 }
00093
00094
00095
00096 TePDIFilterMask::pointer mask;
00097
00098 if( ! parameters.GetParameter( "filter_mask", mask ) ) {
00099
00100 TEAGN_LOGERR( "Missing parameter: filter_mask" );
00101 return false;
00102 }
00103 if( ! mask.isActive() ) {
00104
00105 TEAGN_LOGERR( "Invalid parameter: filter_mask inactive" );
00106 return false;
00107 }
00108 if( mask->columns() < 3 ) {
00109 TEAGN_WATCH( mask->columns() );
00110 TEAGN_LOGERR( "Invalid parameter: filter_mask with invalid colunms number" );
00111 return false;
00112 }
00113 if( mask->lines() < 3 ) {
00114 TEAGN_WATCH( mask->lines() );
00115 TEAGN_LOGERR( "Invalid parameter: filter_mask with invalid lines number" );
00116 return false;
00117 }
00118 if( ( (int)mask->lines() > inRaster->params().nlines_ ) ||
00119 ( (int)mask->columns() > inRaster->params().ncols_ ) ){
00120 TEAGN_LOGERR( "Invalid parameter: filter_mask do not fit inside input image" );
00121 return false;
00122 }
00123 TEAGN_TRUE_OR_RETURN(
00124 mask->isMorfMask(), "Invalid mask: Not a morfological mask" );
00125
00126
00127
00128 int iterations = 0;
00129 if( ! parameters.GetParameter( "iterations", iterations ) ) {
00130
00131 TEAGN_LOGERR( "Missing parameter: iterations" );
00132 return false;
00133 }
00134 TEAGN_TRUE_OR_RETURN( iterations > 0, "Invalid iterations number" );
00135
00136 return true;
00137 }
00138
00139
00140 bool TePDIMorfFilter::RunImplementation()
00141 {
00142 TePDIMorfType filter_type;
00143 params_.GetParameter( "filter_type", filter_type );
00144
00145 switch( filter_type ) {
00146 case TePDIMDilationType :
00147 {
00148 return RunDilation();
00149 break;
00150 }
00151 case TePDIMErosionType :
00152 {
00153 return RunErosion();
00154 break;
00155 }
00156 case TePDIMMedianType :
00157 {
00158 return RunMedian();
00159 break;
00160 }
00161 case TePDIMModeType :
00162 {
00163 return RunMode();
00164 break;
00165 }
00166 default :
00167 {
00168 TEAGN_LOG_AND_RETURN( "Invalid algorithm type" );
00169 }
00170 }
00171 }
00172
00173
00174 bool TePDIMorfFilter::RunDilation()
00175 {
00176 TePDITypes::TePDIRasterPtrType inRaster;
00177 params_.GetParameter( "input_image", inRaster );
00178
00179 TePDITypes::TePDIRasterPtrType outRaster;
00180 params_.GetParameter( "output_image", outRaster );
00181
00182 std::vector< int > channels;
00183 params_.GetParameter( "channels", channels );
00184
00185 TePDIFilterMask::pointer mask;
00186 params_.GetParameter( "filter_mask", mask );
00187
00188 int iterations = 0;
00189 params_.GetParameter( "iterations", iterations );
00190
00191 bool inRaster_uses_dummy = inRaster->params().useDummy_;
00192
00193
00194
00195 TeRasterParams outRaster_params = outRaster->params();
00196
00197 outRaster_params.nBands( channels.size() );
00198 if( inRaster->projection() != 0 ) {
00199 TeSharedPtr< TeProjection > proj( TeProjectionFactory::make(
00200 inRaster->projection()->params() ) );
00201 outRaster_params.projection( proj.nakedPointer() );
00202 }
00203 outRaster_params.boxResolution( inRaster->params().box().x1(),
00204 inRaster->params().box().y1(), inRaster->params().box().x2(),
00205 inRaster->params().box().y2(), inRaster->params().resx_,
00206 inRaster->params().resy_ );
00207
00208 outRaster_params.setPhotometric( TeRasterParams::TeMultiBand, -1 );
00209
00210 if( inRaster->params().useDummy_ ) {
00211 outRaster_params.setDummy( inRaster->params().dummy_[ 0 ], -1 );
00212 } else {
00213 outRaster_params.setDummy( 0, -1 );
00214 }
00215
00216 TEAGN_TRUE_OR_RETURN( outRaster->init( outRaster_params ),
00217 "Output raster reset error" );
00218
00219
00220
00221 TePDITypes::TePDIRasterPtrType aux_raster1;
00222 if( iterations > 1 ) {
00223 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( outRaster,
00224 aux_raster1, 1, true, false, TeDOUBLE ),
00225 "Unable to create auxiliary raster 1" );
00226 }
00227
00228 TePDITypes::TePDIRasterPtrType aux_raster2;
00229 if( iterations > 2 ) {
00230 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( outRaster,
00231 aux_raster2, 1, true, false, TeDOUBLE ),
00232 "Unable to create auxiliary raster 2" );
00233 }
00234
00235
00236
00237 reset_maskmatrix( mask );
00238
00239
00240
00241 unsigned int raster_lines = (unsigned int)outRaster->params().nlines_;
00242 unsigned int raster_columns = (unsigned int)outRaster->params().ncols_;
00243
00244 reset_conv_buf( temp_maskmatrix_lines_, raster_columns );
00245
00246
00247
00248 double output_level = 0;
00249
00250 double max_gen_level = 0;
00251
00252 unsigned int mask_middle_off_lines =
00253 (unsigned int) floor( ((double)temp_maskmatrix_lines_) / 2. );
00254 unsigned int mask_middle_off_columns =
00255 (unsigned int) floor( ((double)temp_maskmatrix_columns_) / 2. );
00256
00257 unsigned int conv_column_bound = raster_columns - temp_maskmatrix_columns_ + 1;
00258 unsigned int conv_line_bound = raster_lines - temp_maskmatrix_lines_ + 1;
00259
00260 unsigned int mask_line = 0;
00261 unsigned int mask_column = 0;
00262 unsigned int raster_line = 0;
00263 unsigned int conv_buf_column = 0;
00264
00265 double out_channel_min_level = 0;
00266 double out_channel_max_level = 0;
00267
00268 double dummy_value = 0;
00269 double curr_buf_value = 0;
00270
00271 TePDITypes::TePDIRasterPtrType source_raster;
00272 TePDITypes::TePDIRasterPtrType target_raster;
00273
00274 StartProgInt( "Dilation", channels.size() * iterations *
00275 conv_line_bound );
00276
00277 for( unsigned int channels_index = 0 ;
00278 channels_index < channels.size() ;
00279 ++channels_index ) {
00280
00281 unsigned int current_input_channel =0;
00282 unsigned int curr_out_channel = 0;
00283
00284 if( inRaster_uses_dummy ) {
00285 dummy_value = inRaster->params().dummy_[ current_input_channel ];
00286 }
00287
00288 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeGetRasterMinMaxBounds(
00289 outRaster, channels_index, out_channel_min_level,
00290 out_channel_max_level ), "Unable to get raster channel level bounds" );
00291
00292 for( int iteration = 0 ; (int)iteration < iterations ; ++iteration ) {
00293 if( iteration == 0 ) {
00294
00295
00296 source_raster = inRaster;
00297 current_input_channel = channels[ channels_index ];
00298
00299 if( iterations > 1 ) {
00300 target_raster = aux_raster1;
00301 curr_out_channel = 0;
00302 } else {
00303 target_raster = outRaster;
00304 curr_out_channel = channels[ channels_index ];
00305 }
00306 } else if ( iteration == ( iterations - 1 ) ) {
00307
00308
00309 current_input_channel = 0;
00310 source_raster = target_raster;
00311
00312 target_raster = outRaster;
00313 curr_out_channel = channels[ channels_index ];
00314 } else {
00315
00316
00317 if( iteration == 1 ) {
00318 source_raster = target_raster;
00319 current_input_channel = 0;
00320
00321 target_raster = aux_raster1;
00322 curr_out_channel = 0;
00323 } else {
00324 TePDITypes::TePDIRasterPtrType swap_ptr = source_raster;
00325 source_raster = target_raster;
00326 current_input_channel = 0;
00327
00328 target_raster = swap_ptr;
00329 curr_out_channel = 0;
00330 }
00331 }
00332
00333
00334
00335 for( unsigned int line = 0 ; line < ( temp_maskmatrix_lines_ - 1 );
00336 ++line ) {
00337
00338 up_conv_buf( source_raster, line, current_input_channel );
00339 }
00340
00341
00342
00343 for( raster_line = 0 ; raster_line < conv_line_bound ; ++raster_line ) {
00344
00345
00346 TEAGN_FALSE_OR_RETURN( UpdateProgInt( ( channels_index * iterations *
00347 conv_line_bound ) +
00348 ( iteration * conv_line_bound ) + raster_line ),
00349 "Canceled by the user" );
00350
00351 up_conv_buf( source_raster, raster_line + temp_maskmatrix_lines_ - 1,
00352 current_input_channel );
00353
00354 for( conv_buf_column = 0 ; conv_buf_column < conv_column_bound ;
00355 ++conv_buf_column ) {
00356
00357 output_level = 0;
00358
00359 if( inRaster_uses_dummy ) {
00360 max_gen_level = dummy_value;
00361
00362 for( mask_line = 0; mask_line < temp_maskmatrix_lines_ ;
00363 ++mask_line ) {
00364 for( mask_column = 0; mask_column < temp_maskmatrix_columns_ ;
00365 ++mask_column ) {
00366
00367 curr_buf_value = conv_buf_[ mask_line ][ conv_buf_column +
00368 mask_column ];
00369
00370 if( curr_buf_value != dummy_value ) {
00371 output_level = temp_maskmatrix_[ mask_line ][ mask_column ] *
00372 curr_buf_value;
00373
00374 if( max_gen_level == dummy_value ) {
00375 max_gen_level = output_level;
00376 } else {
00377 if( output_level > max_gen_level ) {
00378 max_gen_level = output_level;
00379 }
00380 }
00381 }
00382 }
00383 }
00384 } else {
00385 max_gen_level = out_channel_min_level;
00386
00387 for( mask_line = 0; mask_line < temp_maskmatrix_lines_ ;
00388 ++mask_line ) {
00389
00390 for( mask_column = 0; mask_column < temp_maskmatrix_columns_ ;
00391 ++mask_column ) {
00392 output_level = temp_maskmatrix_[ mask_line ][ mask_column ] *
00393 conv_buf_[ mask_line ][ conv_buf_column + mask_column ];
00394
00395 if( output_level > max_gen_level ) {
00396 max_gen_level = output_level;
00397 }
00398 }
00399 }
00400 }
00401
00402
00403
00404 if( max_gen_level < out_channel_min_level ) {
00405 max_gen_level = out_channel_min_level;
00406 } else if( max_gen_level > out_channel_max_level ) {
00407 max_gen_level = out_channel_max_level;
00408 }
00409
00410 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
00411 conv_buf_column + mask_middle_off_columns,
00412 raster_line + mask_middle_off_lines, max_gen_level,
00413 curr_out_channel ), "Pixel mapping error" );
00414 }
00415 }
00416 }
00417 }
00418
00419 return true;
00420
00421 }
00422
00423 bool TePDIMorfFilter::RunErosion()
00424 {
00425 TePDITypes::TePDIRasterPtrType inRaster;
00426 params_.GetParameter( "input_image", inRaster );
00427
00428 TePDITypes::TePDIRasterPtrType outRaster;
00429 params_.GetParameter( "output_image", outRaster );
00430
00431 std::vector< int > channels;
00432 params_.GetParameter( "channels", channels );
00433
00434 TePDIFilterMask::pointer mask;
00435 params_.GetParameter( "filter_mask", mask );
00436
00437 int iterations = 0;
00438 params_.GetParameter( "iterations", iterations );
00439
00440 bool inRaster_uses_dummy = inRaster->params().useDummy_;
00441
00442
00443
00444 TeRasterParams outRaster_params = outRaster->params();
00445
00446 outRaster_params.nBands( channels.size() );
00447 if( inRaster->projection() != 0 ) {
00448 TeSharedPtr< TeProjection > proj( TeProjectionFactory::make(
00449 inRaster->projection()->params() ) );
00450 outRaster_params.projection( proj.nakedPointer() );
00451 }
00452 outRaster_params.boxResolution( inRaster->params().box().x1(),
00453 inRaster->params().box().y1(), inRaster->params().box().x2(),
00454 inRaster->params().box().y2(), inRaster->params().resx_,
00455 inRaster->params().resy_ );
00456
00457 outRaster_params.setPhotometric( TeRasterParams::TeMultiBand, -1 );
00458
00459 if( inRaster->params().useDummy_ ) {
00460 outRaster_params.setDummy( inRaster->params().dummy_[ 0 ], -1 );
00461 } else {
00462 outRaster_params.setDummy( 0, -1 );
00463 }
00464
00465 TEAGN_TRUE_OR_RETURN( outRaster->init( outRaster_params ),
00466 "Output raster reset error" );
00467
00468
00469
00470 TePDITypes::TePDIRasterPtrType aux_raster1;
00471 if( iterations > 1 ) {
00472 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( outRaster,
00473 aux_raster1, 1, true, false, TeDOUBLE ),
00474 "Unable to create auxiliary raster 1" );
00475 }
00476
00477 TePDITypes::TePDIRasterPtrType aux_raster2;
00478 if( iterations > 2 ) {
00479 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( outRaster,
00480 aux_raster2, 1, true, false, TeDOUBLE ),
00481 "Unable to create auxiliary raster 2" );
00482 }
00483
00484
00485
00486 reset_maskmatrix( mask );
00487
00488
00489
00490 unsigned int raster_lines = (unsigned int)outRaster->params().nlines_;
00491 unsigned int raster_columns = (unsigned int)outRaster->params().ncols_;
00492
00493 reset_conv_buf( temp_maskmatrix_lines_, raster_columns );
00494
00495
00496
00497 double output_level;
00498
00499 double min_gen_level;
00500
00501 unsigned int mask_middle_off_lines =
00502 (unsigned int) floor( ((double)temp_maskmatrix_lines_) / 2. );
00503 unsigned int mask_middle_off_columns =
00504 (unsigned int) floor( ((double)temp_maskmatrix_columns_) / 2. );
00505
00506 unsigned int conv_column_bound = raster_columns - temp_maskmatrix_columns_ + 1;
00507 unsigned int conv_line_bound = raster_lines - temp_maskmatrix_lines_ + 1;
00508
00509 unsigned int mask_line;
00510 unsigned int mask_column;
00511 unsigned int raster_line;
00512 unsigned int conv_buf_column;
00513
00514 double out_channel_min_level;
00515 double out_channel_max_level;
00516
00517 double dummy_value = 0;
00518 double curr_buf_value = 0;
00519 double curr_mask_value = 0;
00520
00521 TePDITypes::TePDIRasterPtrType source_raster;
00522 TePDITypes::TePDIRasterPtrType target_raster;
00523
00524 StartProgInt( "Erosion", channels.size() * iterations *
00525 conv_line_bound );
00526
00527 for( unsigned int channels_index = 0 ;
00528 channels_index < channels.size() ;
00529 ++channels_index ) {
00530
00531 unsigned int current_input_channel = channels[ channels_index ];
00532 unsigned int curr_out_channel = 0;
00533
00534 if( inRaster_uses_dummy ) {
00535 dummy_value = inRaster->params().dummy_[ current_input_channel ];
00536 }
00537
00538 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeGetRasterMinMaxBounds(
00539 outRaster, channels_index, out_channel_min_level,
00540 out_channel_max_level ), "Unable to get raster channel level bounds" );
00541
00542 for( int iteration = 0 ; (int)iteration < iterations ; ++iteration ) {
00543 if( iteration == 0 ) {
00544
00545
00546 source_raster = inRaster;
00547 current_input_channel = channels[ channels_index ];
00548
00549 if( iterations > 1 ) {
00550 target_raster = aux_raster1;
00551 curr_out_channel = 0;
00552 } else {
00553 target_raster = outRaster;
00554 curr_out_channel = channels[ channels_index ];
00555 }
00556 } else if ( iteration == ( iterations - 1 ) ) {
00557
00558
00559 current_input_channel = 0;
00560 source_raster = target_raster;
00561
00562 target_raster = outRaster;
00563 curr_out_channel = channels[ channels_index ];
00564 } else {
00565
00566
00567 if( iteration == 1 ) {
00568 source_raster = target_raster;
00569 current_input_channel = 0;
00570
00571 target_raster = aux_raster1;
00572 curr_out_channel = 0;
00573 } else {
00574 TePDITypes::TePDIRasterPtrType swap_ptr = source_raster;
00575 source_raster = target_raster;
00576 current_input_channel = 0;
00577
00578 target_raster = swap_ptr;
00579 curr_out_channel = 0;
00580 }
00581 }
00582
00583
00584
00585 for( unsigned int line = 0 ; line < ( temp_maskmatrix_lines_ - 1 ); ++line ) {
00586 up_conv_buf( source_raster, line, current_input_channel );
00587 }
00588
00589
00590
00591 for( raster_line = 0 ; raster_line < conv_line_bound ; ++raster_line ) {
00592
00593
00594 TEAGN_FALSE_OR_RETURN( UpdateProgInt( ( channels_index * iterations *
00595 conv_line_bound ) +
00596 ( iteration * conv_line_bound ) + raster_line ),
00597 "Canceled by the user" );
00598
00599 up_conv_buf( source_raster, raster_line + temp_maskmatrix_lines_ - 1,
00600 current_input_channel );
00601
00602 for( conv_buf_column = 0 ; conv_buf_column < conv_column_bound ;
00603 ++conv_buf_column ) {
00604
00605 output_level = 0;
00606
00607 if( inRaster_uses_dummy ) {
00608 min_gen_level = dummy_value;
00609
00610 for( mask_line = 0; mask_line < temp_maskmatrix_lines_ ;
00611 ++mask_line ) {
00612 for( mask_column = 0; mask_column < temp_maskmatrix_columns_ ;
00613 ++mask_column ) {
00614
00615 curr_buf_value = conv_buf_[ mask_line ][ conv_buf_column +
00616 mask_column ];
00617 curr_mask_value = temp_maskmatrix_[ mask_line ][ mask_column ];
00618
00619 if( ( curr_buf_value != dummy_value ) &&
00620 ( curr_mask_value != 0 ) ) {
00621
00622 output_level = curr_buf_value * curr_mask_value;;
00623
00624 if( min_gen_level == dummy_value ) {
00625 min_gen_level = output_level;
00626 } else {
00627 if( output_level < min_gen_level ) {
00628 min_gen_level = output_level;
00629 }
00630 }
00631 }
00632 }
00633 }
00634 } else {
00635 min_gen_level = out_channel_max_level;
00636
00637 for( mask_line = 0; mask_line < temp_maskmatrix_lines_ ;
00638 ++mask_line ) {
00639 for( mask_column = 0; mask_column < temp_maskmatrix_columns_ ;
00640 ++mask_column ) {
00641
00642 output_level = temp_maskmatrix_[ mask_line ][ mask_column ] *
00643 conv_buf_[ mask_line ][ conv_buf_column + mask_column ];
00644
00645 if( ( output_level < min_gen_level ) &&
00646 ( temp_maskmatrix_[ mask_line ][ mask_column ] != 0 ) ) {
00647
00648 min_gen_level = output_level;
00649 }
00650 }
00651 }
00652 }
00653
00654
00655
00656 if( min_gen_level < out_channel_min_level ) {
00657 min_gen_level = out_channel_min_level;
00658 } else if( min_gen_level > out_channel_max_level ) {
00659 min_gen_level = out_channel_max_level;
00660 }
00661
00662 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
00663 conv_buf_column + mask_middle_off_columns,
00664 raster_line + mask_middle_off_lines, min_gen_level,
00665 curr_out_channel ), "Pixel mapping error" );
00666 }
00667 }
00668 }
00669 }
00670
00671 return true;
00672 }
00673
00674 bool TePDIMorfFilter::RunMedian()
00675 {
00676 TePDITypes::TePDIRasterPtrType inRaster;
00677 params_.GetParameter( "input_image", inRaster );
00678
00679 TePDITypes::TePDIRasterPtrType outRaster;
00680 params_.GetParameter( "output_image", outRaster );
00681
00682 std::vector< int > channels;
00683 params_.GetParameter( "channels", channels );
00684
00685 TePDIFilterMask::pointer mask;
00686 params_.GetParameter( "filter_mask", mask );
00687
00688 int iterations = 0;
00689 params_.GetParameter( "iterations", iterations );
00690
00691 bool inRaster_uses_dummy = inRaster->params().useDummy_;
00692
00693
00694
00695 TeRasterParams outRaster_params = outRaster->params();
00696
00697 outRaster_params.nBands( channels.size() );
00698 if( inRaster->projection() != 0 ) {
00699 TeSharedPtr< TeProjection > proj( TeProjectionFactory::make(
00700 inRaster->projection()->params() ) );
00701 outRaster_params.projection( proj.nakedPointer() );
00702 }
00703 outRaster_params.boxResolution( inRaster->params().box().x1(),
00704 inRaster->params().box().y1(), inRaster->params().box().x2(),
00705 inRaster->params().box().y2(), inRaster->params().resx_,
00706 inRaster->params().resy_ );
00707
00708 outRaster_params.setPhotometric( TeRasterParams::TeMultiBand, -1 );
00709
00710 if( inRaster->params().useDummy_ ) {
00711 outRaster_params.setDummy( inRaster->params().dummy_[ 0 ], -1 );
00712 } else {
00713 outRaster_params.setDummy( 0, -1 );
00714 }
00715
00716 TEAGN_TRUE_OR_RETURN( outRaster->init( outRaster_params ),
00717 "Output raster reset error" );
00718
00719
00720
00721
00722 TePDITypes::TePDIRasterPtrType aux_raster1;
00723 if( iterations > 1 ) {
00724 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( outRaster,
00725 aux_raster1, 1, true, false, TeDOUBLE ),
00726 "Unable to create auxiliary raster 1" );
00727 }
00728
00729 TePDITypes::TePDIRasterPtrType aux_raster2;
00730 if( iterations > 2 ) {
00731 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( outRaster,
00732 aux_raster2, 1, true, false, TeDOUBLE ),
00733 "Unable to create auxiliary raster 2" );
00734 }
00735
00736
00737
00738 reset_maskmatrix( mask );
00739
00740
00741
00742 unsigned int raster_lines = (unsigned int)outRaster->params().nlines_;
00743 unsigned int raster_columns = (unsigned int)outRaster->params().ncols_;
00744
00745 reset_conv_buf( temp_maskmatrix_lines_, raster_columns );
00746
00747
00748
00749 if( double_buffer_ ) {
00750 delete[] double_buffer_;
00751 }
00752
00753 double_buffer_ =
00754 new double[ temp_maskmatrix_lines_ * temp_maskmatrix_columns_ ];
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764 unsigned int temp_bubble_bound;
00765
00766 unsigned int bubble_index;
00767 double temp_bubble_swap;
00768
00769
00770
00771 unsigned int mask_middle_off_lines =
00772 (unsigned int) floor( ((double)temp_maskmatrix_lines_) / 2. );
00773 unsigned int mask_middle_off_columns =
00774 (unsigned int) floor( ((double)temp_maskmatrix_columns_) / 2. );
00775
00776 unsigned int conv_column_bound = raster_columns - temp_maskmatrix_columns_ + 1;
00777 unsigned int conv_line_bound = raster_lines - temp_maskmatrix_lines_ + 1;
00778
00779 unsigned int mask_line;
00780 unsigned int mask_column;
00781 unsigned int raster_line;
00782 unsigned int conv_buf_column;
00783
00784 double out_channel_min_level;
00785 double out_channel_max_level;
00786
00787 unsigned int next_db_element_index = 0;
00788
00789
00790 double curr_mask_value = 0;
00791 double curr_cb_value = 0;
00792 double dummy_value = 0;
00793
00794 TePDITypes::TePDIRasterPtrType source_raster;
00795 TePDITypes::TePDIRasterPtrType target_raster;
00796
00797 StartProgInt( "Median", channels.size() * iterations *
00798 conv_line_bound );
00799
00800 for( unsigned int channels_index = 0 ;
00801 channels_index < channels.size() ;
00802 ++channels_index ) {
00803
00804 unsigned int current_input_channel = channels[ channels_index ];
00805 unsigned int curr_out_channel = 0;
00806
00807 if( inRaster_uses_dummy ) {
00808 dummy_value = inRaster->params().dummy_[ current_input_channel ];
00809 }
00810
00811 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeGetRasterMinMaxBounds(
00812 outRaster, channels_index, out_channel_min_level,
00813 out_channel_max_level ), "Unable to get raster channel level bounds" );
00814
00815 for( int iteration = 0 ; (int)iteration < iterations ; ++iteration ) {
00816 if( iteration == 0 ) {
00817
00818
00819 source_raster = inRaster;
00820 current_input_channel = channels[ channels_index ];
00821
00822 if( iterations > 1 ) {
00823 target_raster = aux_raster1;
00824 curr_out_channel = 0;
00825 } else {
00826 target_raster = outRaster;
00827 curr_out_channel = channels[ channels_index ];
00828 }
00829 } else if ( iteration == ( iterations - 1 ) ) {
00830
00831
00832 current_input_channel = 0;
00833 source_raster = target_raster;
00834
00835 target_raster = outRaster;
00836 curr_out_channel = channels[ channels_index ];
00837 } else {
00838
00839
00840 if( iteration == 1 ) {
00841 source_raster = target_raster;
00842 current_input_channel = 0;
00843
00844 target_raster = aux_raster1;
00845 curr_out_channel = 0;
00846 } else {
00847 TePDITypes::TePDIRasterPtrType swap_ptr = source_raster;
00848 source_raster = target_raster;
00849 current_input_channel = 0;
00850
00851 target_raster = swap_ptr;
00852 curr_out_channel = 0;
00853 }
00854 }
00855
00856
00857
00858 for( unsigned int line = 0 ; line < ( temp_maskmatrix_lines_ - 1 ) ; ++line ) {
00859 up_conv_buf( source_raster, line, current_input_channel );
00860 }
00861
00862
00863
00864 for( raster_line = 0 ; raster_line < conv_line_bound ; ++raster_line ) {
00865
00866
00867 TEAGN_FALSE_OR_RETURN( UpdateProgInt( ( channels_index * iterations *
00868 conv_line_bound ) +
00869 ( iteration * conv_line_bound ) + raster_line ),
00870 "Canceled by the user" );
00871
00872 up_conv_buf( source_raster, raster_line + temp_maskmatrix_lines_ - 1,
00873 current_input_channel );
00874
00875 for( conv_buf_column = 0 ; conv_buf_column < conv_column_bound ;
00876 ++conv_buf_column ) {
00877
00878
00879
00880 next_db_element_index = 0;
00881
00882 if( inRaster_uses_dummy ) {
00883 for( mask_line = 0; mask_line < temp_maskmatrix_lines_ ; ++mask_line ) {
00884 for( mask_column = 0; mask_column < temp_maskmatrix_columns_ ;
00885 ++mask_column ) {
00886
00887 curr_mask_value = temp_maskmatrix_[ mask_line ][ mask_column ];
00888 curr_cb_value = conv_buf_[ mask_line ][ conv_buf_column +
00889 mask_column ];
00890
00891 if( ( curr_mask_value != 0 ) &&
00892 ( curr_cb_value != dummy_value ) ) {
00893
00894 double_buffer_[ next_db_element_index ] =
00895 curr_mask_value * curr_cb_value;
00896
00897 ++next_db_element_index;
00898 }
00899 }
00900 }
00901 } else {
00902 for( mask_line = 0; mask_line < temp_maskmatrix_lines_ ; ++mask_line ) {
00903 for( mask_column = 0; mask_column < temp_maskmatrix_columns_ ;
00904 ++mask_column ) {
00905
00906 curr_mask_value = temp_maskmatrix_[ mask_line ][ mask_column ];
00907
00908 if( curr_mask_value != 0 ) {
00909 double_buffer_[ next_db_element_index ] =
00910 curr_mask_value *
00911 conv_buf_[ mask_line ][ conv_buf_column + mask_column ];
00912
00913 ++next_db_element_index;
00914 }
00915 }
00916 }
00917 }
00918
00919 if( next_db_element_index == 0 ) {
00920 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
00921 conv_buf_column + mask_middle_off_columns,
00922 raster_line + mask_middle_off_lines, dummy_value,
00923 curr_out_channel ), "Pixel mapping error" );
00924 } else if( next_db_element_index == 1 ) {
00925 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
00926 conv_buf_column + mask_middle_off_columns,
00927 raster_line + mask_middle_off_lines,
00928 double_buffer_[ 0 ], curr_out_channel ),
00929 "Pixel mapping error" );
00930 } else {
00931
00932
00933 temp_bubble_bound = next_db_element_index - 1;
00934
00935 while( temp_bubble_bound > 0 ) {
00936 for( bubble_index = 0 ; bubble_index < temp_bubble_bound ;
00937 ++bubble_index ) {
00938
00939 if( double_buffer_[ bubble_index ] >
00940 double_buffer_[ bubble_index + 1 ] ) {
00941
00942 temp_bubble_swap = double_buffer_[ bubble_index ];
00943 double_buffer_[ bubble_index ] =
00944 double_buffer_[ bubble_index + 1 ];
00945 double_buffer_[ bubble_index + 1 ] = temp_bubble_swap;
00946 }
00947 }
00948
00949 --temp_bubble_bound;
00950 }
00951
00952 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
00953 conv_buf_column + mask_middle_off_columns,
00954 raster_line + mask_middle_off_lines,
00955 double_buffer_[ ( next_db_element_index - 1 ) / 2 ],
00956 curr_out_channel ), "Pixel mapping error" );
00957 }
00958 }
00959 }
00960 }
00961 }
00962
00963 return true;
00964 }
00965
00966
00967 bool TePDIMorfFilter::RunMode()
00968 {
00969 TePDITypes::TePDIRasterPtrType inRaster;
00970 params_.GetParameter( "input_image", inRaster );
00971
00972 TePDITypes::TePDIRasterPtrType outRaster;
00973 params_.GetParameter( "output_image", outRaster );
00974
00975 std::vector< int > channels;
00976 params_.GetParameter( "channels", channels );
00977
00978 TePDIFilterMask::pointer mask;
00979 params_.GetParameter( "filter_mask", mask );
00980
00981 int iterations = 0;
00982 params_.GetParameter( "iterations", iterations );
00983
00984 bool inRaster_uses_dummy = inRaster->params().useDummy_;
00985
00986
00987
00988 TeRasterParams outRaster_params = outRaster->params();
00989
00990 outRaster_params.nBands( channels.size() );
00991 if( inRaster->projection() != 0 ) {
00992 TeSharedPtr< TeProjection > proj( TeProjectionFactory::make(
00993 inRaster->projection()->params() ) );
00994 outRaster_params.projection( proj.nakedPointer() );
00995 }
00996 outRaster_params.boxResolution( inRaster->params().box().x1(),
00997 inRaster->params().box().y1(), inRaster->params().box().x2(),
00998 inRaster->params().box().y2(), inRaster->params().resx_,
00999 inRaster->params().resy_ );
01000
01001 outRaster_params.setPhotometric( TeRasterParams::TeMultiBand, -1 );
01002
01003 if( inRaster->params().useDummy_ ) {
01004 outRaster_params.setDummy( inRaster->params().dummy_[ 0 ], -1 );
01005 } else {
01006 outRaster_params.setDummy( 0, -1 );
01007 }
01008
01009 TEAGN_TRUE_OR_RETURN( outRaster->init( outRaster_params ),
01010 "Output raster reset error" );
01011
01012
01013
01014
01015 TePDITypes::TePDIRasterPtrType aux_raster1;
01016 if( iterations > 1 ) {
01017 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( outRaster,
01018 aux_raster1, 1, true, false, TeDOUBLE ),
01019 "Unable to create auxiliary raster 1" );
01020 }
01021
01022 TePDITypes::TePDIRasterPtrType aux_raster2;
01023 if( iterations > 2 ) {
01024 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeAllocRAMRaster( outRaster,
01025 aux_raster2, 1, true, false, TeDOUBLE ),
01026 "Unable to create auxiliary raster 2" );
01027 }
01028
01029
01030
01031 reset_maskmatrix( mask );
01032
01033
01034
01035 unsigned int raster_lines = (unsigned int)outRaster->params().nlines_;
01036 unsigned int raster_columns = (unsigned int)outRaster->params().ncols_;
01037
01038 reset_conv_buf( temp_maskmatrix_lines_, raster_columns );
01039
01040
01041
01042 std::map< double, unsigned int > freqmap;
01043 std::map< double, unsigned int >::iterator freqmap_it;
01044 std::map< double, unsigned int >::iterator freqmap_it_end;
01045 double freqmap_highest_freq_value = 0;
01046 unsigned int freqmap_highest_freq = 0;
01047
01048
01049
01050 unsigned int mask_middle_off_lines =
01051 (unsigned int) floor( ((double)temp_maskmatrix_lines_) / 2. );
01052 unsigned int mask_middle_off_columns =
01053 (unsigned int) floor( ((double)temp_maskmatrix_columns_) / 2. );
01054
01055 unsigned int conv_column_bound = raster_columns - temp_maskmatrix_columns_ + 1;
01056 unsigned int conv_line_bound = raster_lines - temp_maskmatrix_lines_ + 1;
01057
01058 unsigned int mask_line = 0;
01059 unsigned int mask_column = 0;
01060 unsigned int raster_line = 0;
01061 unsigned int raster_col = 0;
01062 unsigned int conv_buf_column = 0;
01063
01064 double out_channel_min_level = 0;
01065 double out_channel_max_level = 0;
01066
01067
01068
01069
01070
01071
01072 double dummy_value = 0;
01073 double pixel_value = 0;
01074 double mask_apply_result = 0.0;
01075
01076 TePDITypes::TePDIRasterPtrType source_raster;
01077 TePDITypes::TePDIRasterPtrType target_raster;
01078
01079 StartProgInt( "Mede", channels.size() * iterations *
01080 conv_line_bound );
01081
01082 for( unsigned int channels_index = 0 ;
01083 channels_index < channels.size() ;
01084 ++channels_index ) {
01085
01086 unsigned int current_input_channel = channels[ channels_index ];
01087 unsigned int curr_out_channel = 0;
01088
01089 if( inRaster_uses_dummy ) {
01090 dummy_value = inRaster->params().dummy_[ current_input_channel ];
01091 }
01092 else
01093 {
01094 dummy_value = 0;
01095 }
01096
01097 TEAGN_TRUE_OR_RETURN( TePDIUtils::TeGetRasterMinMaxBounds(
01098 outRaster, channels_index, out_channel_min_level,
01099 out_channel_max_level ),
01100 "Unable to get raster channel level bounds" );
01101
01102 for( int iteration = 0 ; (int)iteration < iterations ;
01103 ++iteration )
01104 {
01105 if( iteration == 0 ) {
01106
01107
01108 source_raster = inRaster;
01109 current_input_channel = channels[ channels_index ];
01110
01111 if( iterations > 1 ) {
01112 target_raster = aux_raster1;
01113 curr_out_channel = 0;
01114 } else {
01115 target_raster = outRaster;
01116 curr_out_channel = channels[ channels_index ];
01117 }
01118 } else if ( iteration == ( iterations - 1 ) ) {
01119
01120
01121 current_input_channel = 0;
01122 source_raster = target_raster;
01123
01124 target_raster = outRaster;
01125 curr_out_channel = channels[ channels_index ];
01126 } else {
01127
01128
01129 if( iteration == 1 ) {
01130 source_raster = target_raster;
01131 current_input_channel = 0;
01132
01133 target_raster = aux_raster1;
01134 curr_out_channel = 0;
01135 } else {
01136 TePDITypes::TePDIRasterPtrType swap_ptr = source_raster;
01137 source_raster = target_raster;
01138 current_input_channel = 0;
01139
01140 target_raster = swap_ptr;
01141 curr_out_channel = 0;
01142 }
01143 }
01144
01145
01146
01147 for( raster_line = 0 ; raster_line < raster_lines ;
01148 ++raster_line )
01149 {
01150 if( source_raster->getElement( 0, raster_line, pixel_value,
01151 current_input_channel ) )
01152 {
01153 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01154 0, raster_line, pixel_value, curr_out_channel ),
01155 "Pixel writing error" );
01156 }
01157 else
01158 {
01159 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01160 0, raster_line, dummy_value, curr_out_channel ),
01161 "Pixel writing error" );
01162 }
01163
01164 if( source_raster->getElement( raster_columns - 1,
01165 raster_line, pixel_value,
01166 current_input_channel ) )
01167 {
01168 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01169 raster_columns - 1, raster_line, pixel_value,
01170 curr_out_channel ),
01171 "Pixel writing error" );
01172 }
01173 else
01174 {
01175 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01176 raster_columns - 1, raster_line, dummy_value,
01177 curr_out_channel ),
01178 "Pixel writing error" );
01179 }
01180 }
01181
01182
01183
01184 for( raster_col = 0 ; raster_col < raster_columns ;
01185 ++raster_col )
01186 {
01187 if( source_raster->getElement( raster_col, 0, pixel_value,
01188 current_input_channel ) )
01189 {
01190 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01191 raster_col, 0, pixel_value, curr_out_channel ),
01192 "Pixel writing error" );
01193 }
01194 else
01195 {
01196 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01197 raster_col, 0, dummy_value, curr_out_channel ),
01198 "Pixel writing error" );
01199 }
01200
01201 if( source_raster->getElement( raster_col,
01202 raster_lines - 1, pixel_value,
01203 current_input_channel ) )
01204 {
01205 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01206 raster_col, raster_lines - 1, pixel_value,
01207 curr_out_channel ),
01208 "Pixel writing error" );
01209 }
01210 else
01211 {
01212 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01213 raster_col, raster_lines - 1, dummy_value,
01214 curr_out_channel ),
01215 "Pixel writing error" );
01216 }
01217 }
01218
01219
01220
01221 for( unsigned int line = 0 ; line < ( temp_maskmatrix_lines_ - 1 ) ; ++line ) {
01222 up_conv_buf( source_raster, line, current_input_channel );
01223 }
01224
01225
01226
01227 for( raster_line = 0 ; raster_line < conv_line_bound ;
01228 ++raster_line )
01229 {
01230
01231
01232 TEAGN_FALSE_OR_RETURN( UpdateProgInt(
01233 ( channels_index * iterations *
01234 conv_line_bound ) +
01235 ( iteration * conv_line_bound ) + raster_line ),
01236 "Canceled by the user" );
01237
01238 up_conv_buf( source_raster, raster_line + temp_maskmatrix_lines_ - 1,
01239 current_input_channel );
01240
01241 for( conv_buf_column = 0 ; conv_buf_column <
01242 conv_column_bound ; ++conv_buf_column )
01243 {
01244 freqmap.clear();
01245
01246
01247
01248 if( inRaster_uses_dummy ) {
01249 for( mask_line = 0; mask_line < temp_maskmatrix_lines_ ; ++mask_line ) {
01250 for( mask_column = 0; mask_column < temp_maskmatrix_columns_ ;
01251 ++mask_column ) {
01252
01253 const double& curr_mask_value =
01254 temp_maskmatrix_[ mask_line ][ mask_column ];
01255 const double& curr_cb_value =
01256 conv_buf_[ mask_line ][ conv_buf_column +
01257 mask_column ];
01258
01259
01260 if( ( curr_mask_value != 0 ) &&
01261 ( curr_cb_value != dummy_value ) ) {
01262
01263 mask_apply_result = curr_mask_value *
01264 curr_cb_value;
01265
01266 freqmap[ mask_apply_result ] += 1;
01267 }
01268 }
01269 }
01270 } else {
01271 for( mask_line = 0; mask_line < temp_maskmatrix_lines_ ; ++mask_line ) {
01272 for( mask_column = 0; mask_column < temp_maskmatrix_columns_ ;
01273 ++mask_column ) {
01274
01275 const double& curr_mask_value =
01276 temp_maskmatrix_[ mask_line ][ mask_column ];
01277
01278 if( curr_mask_value != 0 ) {
01279 freqmap[ conv_buf_[ mask_line ][
01280 conv_buf_column + mask_column ] ] += 1;
01281 }
01282 }
01283 }
01284 }
01285
01286 if( freqmap.size() == 0 ) {
01287 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01288 conv_buf_column + mask_middle_off_columns,
01289 raster_line + mask_middle_off_lines, dummy_value,
01290 curr_out_channel ), "Pixel mapping error" );
01291 }
01292 else
01293 {
01294
01295 freqmap_highest_freq = 0;
01296 freqmap_it = freqmap.begin();
01297 freqmap_it_end = freqmap.end();
01298
01299 while( freqmap_it != freqmap_it_end )
01300 {
01301 if( freqmap_it->second > freqmap_highest_freq )
01302 {
01303 freqmap_highest_freq = freqmap_it->second;
01304 freqmap_highest_freq_value = freqmap_it->first;
01305 }
01306
01307 ++freqmap_it;
01308 }
01309
01310 TEAGN_TRUE_OR_RETURN( target_raster->setElement(
01311 conv_buf_column + mask_middle_off_columns,
01312 raster_line + mask_middle_off_lines,
01313 freqmap_highest_freq_value, curr_out_channel ),
01314 "Pixel mapping error" );
01315 }
01316 }
01317 }
01318 }
01319 }
01320
01321 return true;
01322 }
01323
01324
01325 void TePDIMorfFilter::ResetState( const TePDIParameters& params )
01326 {
01327 TePDIBufferedFilter::ResetState( params );
01328
01329 if( double_buffer_ ) {
01330 delete[] double_buffer_;
01331 double_buffer_ = 0;
01332 }
01333 }
01334
01335