25 #include <sys/types.h>
27 #include "base/Optionpk.h"
28 #include "base/Vector2d.h"
29 #include "algorithms/Filter2d.h"
30 #include "algorithms/Filter.h"
31 #include "fileclasses/FileReaderAscii.h"
32 #include "imageclasses/ImgReaderGdal.h"
33 #include "imageclasses/ImgWriterGdal.h"
35 #include "algorithms/StatFactory.h"
229 int main(
int argc,
char **argv) {
233 Optionpk<bool> disc_opt(
"circ",
"circular",
"circular disc kernel for dilation and erosion",
false);
235 Optionpk<std::string> method_opt(
"f",
"filter",
"filter function (nvalid, median, var, min, max, sum, mean, dilate, erode, close, open, homog (central pixel must be identical to all other pixels within window), heterog (central pixel must be different than all other pixels within window), sobelx (horizontal edge detection), sobely (vertical edge detection), sobelxy (diagonal edge detection NE-SW),sobelyx (diagonal edge detection NW-SE), density, countid, mode (majority voting, only for classes), smoothnodata (smooth nodata values only) values, ismin, ismax, order (rank pixels in order), stdev, mrf, dwt, dwti, dwt_cut, dwt_cut_from, scramble, shift, savgolay, percentile, proportion)");
236 Optionpk<std::string> resample_opt(
"r",
"resampling-method",
"Resampling method for shifting operation (near: nearest neighbour, bilinear: bi-linear interpolation).",
"near");
237 Optionpk<double> dimX_opt(
"dx",
"dx",
"filter kernel size in x, use odd values only", 3);
238 Optionpk<double> dimY_opt(
"dy",
"dy",
"filter kernel size in y, use odd values only", 3);
239 Optionpk<int> dimZ_opt(
"dz",
"dz",
"filter kernel size in z (spectral/temporal dimension), must be odd (example: 3).. Set dz>0 if 1-D filter must be used in band domain");
240 Optionpk<std::string> wavelet_type_opt(
"wt",
"wavelet",
"wavelet type: daubechies,daubechies_centered, haar, haar_centered, bspline, bspline_centered",
"daubechies");
241 Optionpk<int> family_opt(
"wf",
"family",
"wavelet family (vanishing moment, see also http://www.gnu.org/software/gsl/manual/html_node/DWT-Initialization.html)", 4);
242 Optionpk<int> savgolay_nl_opt(
"nl",
"nl",
"Number of leftward (past) data points used in Savitzky-Golay filter)", 2);
243 Optionpk<int> savgolay_nr_opt(
"nr",
"nr",
"Number of rightward (future) data points used in Savitzky-Golay filter)", 2);
244 Optionpk<int> savgolay_ld_opt(
"ld",
"ld",
"order of the derivative desired in Savitzky-Golay filter (e.g., ld=0 for smoothed function)", 0);
245 Optionpk<int> savgolay_m_opt(
"m",
"m",
"order of the smoothing polynomial in Savitzky-Golay filter, also equal to the highest conserved moment; usual values are m = 2 or m = 4)", 2);
246 Optionpk<short> class_opt(
"class",
"class",
"class value(s) to use for density, erosion, dilation, openening and closing, thresholding");
247 Optionpk<double> threshold_opt(
"t",
"threshold",
"threshold value(s) to use for threshold filter (one for each class), or threshold to cut for dwt_cut (use 0 to keep all) or dwt_cut_from, or sigma for shift", 0);
248 Optionpk<double> nodata_opt(
"nodata",
"nodata",
"nodata value(s) (used for smoothnodata filter)");
249 Optionpk<std::string> tap_opt(
"tap",
"tap",
"text file containing taps used for spatial filtering (from ul to lr). Use dimX and dimY to specify tap dimensions in x and y. Leave empty for not using taps");
250 Optionpk<double> tapz_opt(
"tapz",
"tapz",
"taps used for spectral filtering");
251 Optionpk<string> padding_opt(
"pad",
"pad",
"Padding method for filtering (how to handle edge effects). Choose between: symmetric, replicate, circular, zero (pad with 0).",
"symmetric");
252 Optionpk<double> fwhm_opt(
"fwhm",
"fwhm",
"list of full width half to apply spectral filtering (-fwhm band1 -fwhm band2 ...)");
253 Optionpk<std::string> srf_opt(
"srf",
"srf",
"list of ASCII files containing spectral response functions (two columns: wavelength response)");
254 Optionpk<double> wavelengthIn_opt(
"win",
"wavelengthIn",
"list of wavelengths in input spectrum (-win band1 -win band2 ...)");
255 Optionpk<double> wavelengthOut_opt(
"wout",
"wavelengthOut",
"list of wavelengths in output spectrum (-wout band1 -wout band2 ...)");
256 Optionpk<std::string> interpolationType_opt(
"interp",
"interp",
"type of interpolation for spectral filtering (see http://www.gnu.org/software/gsl/manual/html_node/Interpolation-Types.html)",
"akima");
257 Optionpk<std::string> otype_opt(
"ot",
"otype",
"Data type for output image ({Byte/Int16/UInt16/UInt32/Int32/Float32/Float64/CInt16/CInt32/CFloat32/CFloat64}). Empty string: inherit type from input image",
"");
258 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate).",
"GTiff");
259 Optionpk<string> colorTable_opt(
"ct",
"ct",
"color table (file with 5 columns: id R G B ALFA (0: transparent, 255: solid). Use none to ommit color table");
260 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
261 Optionpk<short> down_opt(
"d",
"down",
"down sampling factor. Use value 1 for no downsampling). Use value n>1 for downsampling (aggregation)", 1);
262 Optionpk<string> beta_opt(
"beta",
"beta",
"ASCII file with beta for each class transition in Markov Random Field");
268 Optionpk<short> verbose_opt(
"v",
"verbose",
"verbose mode if > 0", 0,2);
270 resample_opt.setHide(1);
271 option_opt.setHide(1);
272 wavelet_type_opt.setHide(1);
273 family_opt.setHide(1);
274 savgolay_nl_opt.setHide(1);
275 savgolay_nr_opt.setHide(1);
276 savgolay_ld_opt.setHide(1);
277 savgolay_m_opt.setHide(1);
278 class_opt.setHide(1);
279 threshold_opt.setHide(1);
282 padding_opt.setHide(1);
283 wavelengthIn_opt.setHide(1);
284 wavelengthOut_opt.setHide(1);
292 interpolationType_opt.setHide(1);
293 otype_opt.setHide(1);
294 oformat_opt.setHide(1);
295 colorTable_opt.setHide(1);
300 doProcess=input_opt.retrieveOption(argc,argv);
301 output_opt.retrieveOption(argc,argv);
304 method_opt.retrieveOption(argc,argv);
305 srf_opt.retrieveOption(argc,argv);
306 fwhm_opt.retrieveOption(argc,argv);
307 dimX_opt.retrieveOption(argc,argv);
308 dimY_opt.retrieveOption(argc,argv);
309 dimZ_opt.retrieveOption(argc,argv);
310 nodata_opt.retrieveOption(argc,argv);
311 resample_opt.retrieveOption(argc,argv);
312 option_opt.retrieveOption(argc,argv);
313 wavelet_type_opt.retrieveOption(argc,argv);
314 family_opt.retrieveOption(argc,argv);
315 savgolay_nl_opt.retrieveOption(argc,argv);
316 savgolay_nr_opt.retrieveOption(argc,argv);
317 savgolay_ld_opt.retrieveOption(argc,argv);
318 savgolay_m_opt.retrieveOption(argc,argv);
319 class_opt.retrieveOption(argc,argv);
320 threshold_opt.retrieveOption(argc,argv);
321 tap_opt.retrieveOption(argc,argv);
322 tapz_opt.retrieveOption(argc,argv);
323 padding_opt.retrieveOption(argc,argv);
324 wavelengthIn_opt.retrieveOption(argc,argv);
325 wavelengthOut_opt.retrieveOption(argc,argv);
326 down_opt.retrieveOption(argc,argv);
327 beta_opt.retrieveOption(argc,argv);
333 interpolationType_opt.retrieveOption(argc,argv);
334 otype_opt.retrieveOption(argc,argv);
335 oformat_opt.retrieveOption(argc,argv);
336 colorTable_opt.retrieveOption(argc,argv);
337 disc_opt.retrieveOption(argc,argv);
338 verbose_opt.retrieveOption(argc,argv);
340 catch(
string predefinedString){
341 std::cout << predefinedString << std::endl;
346 cout <<
"Usage: pkfilter -i input -o ouptut [-f filter | -perc value | -srf file [-srf file]* -win wavelength [-win wavelength]* | -wout wavelength -fwhm value [-wout wavelength -fwhm value]* -win wavelength [-win wavelength]*]" << endl;
348 std::cout <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
353 vector<double> angle_opt;
357 if(input_opt.empty()){
358 cerr <<
"Error: no input file selected, use option -i" << endl;
361 if(output_opt.empty()){
362 cerr <<
"Error: no output file selected, use option -o" << endl;
365 input.open(input_opt[0]);
366 GDALDataType theType=GDT_Unknown;
368 cout <<
"possible output data types: ";
369 for(
int iType = 0; iType < GDT_TypeCount; ++iType){
371 cout <<
" " << GDALGetDataTypeName((GDALDataType)iType);
372 if( GDALGetDataTypeName((GDALDataType)iType) != NULL
373 && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
374 otype_opt[0].c_str()))
375 theType=(GDALDataType) iType;
377 if(theType==GDT_Unknown)
378 theType=input.getDataType();
381 std::cout << std::endl <<
"Output pixel type: " << GDALGetDataTypeName(theType) << endl;
384 if(oformat_opt.size())
385 imageType=oformat_opt[0];
387 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
388 string theInterleave=
"INTERLEAVE=";
389 theInterleave+=input.getInterleave();
390 option_opt.push_back(theInterleave);
393 int nband=input.nrOfBand();
396 nband=fwhm_opt.size();
397 else if(srf_opt.size())
398 nband=srf_opt.size();
399 else if(tap_opt.size()||tapz_opt.size())
400 nband=input.nrOfBand();
402 if(method_opt.empty()){
403 cerr <<
"Error: no filter selected, use option -f" << endl;
406 switch(filter2d::Filter2d::getFilterType(method_opt[0])){
407 case(filter2d::dilate):
408 case(filter2d::erode):
409 case(filter2d::close):
410 case(filter2d::open):
411 case(filter2d::smooth):
414 assert(dimZ_opt[0]>1);
415 nband=input.nrOfBand();
418 case(filter2d::dwti):
419 case(filter2d::dwt_cut):
420 case(filter2d::smoothnodata):
422 nband=input.nrOfBand();
424 case(filter2d::savgolay):
425 nband=input.nrOfBand();
427 dimZ_opt.push_back(1);
428 case(filter2d::dwt_cut_from):
431 nband=input.nrOfBand();
432 assert(threshold_opt.size());
435 cerr <<
"filter not implemented in spatial domain" << endl;
440 assert(class_opt.size()>1);
442 std::cout <<
"opening output image " << output_opt[0] << std::endl;
443 nband=class_opt.size();
444 case(filter2d::ismin):
445 case(filter2d::ismax):
446 case(filter2d::shift):
447 case(filter2d::scramble):
448 case(filter2d::mode):
449 case(filter2d::sobelx):
450 case(filter2d::sobely):
451 case(filter2d::sobelxy):
452 case(filter2d::countid):
453 case(filter2d::order):
454 case(filter2d::density):
455 case(filter2d::homog):
456 case(filter2d::heterog):
459 cerr <<
"filter not implemented in spectral/temporal domain" << endl;
473 case(filter2d::mean):
477 case(filter2d::stdev):
478 case(filter2d::nvalid):
479 case(filter2d::median):
480 case(filter2d::percentile):
481 case(filter2d::proportion):
483 if(dimZ_opt.size()==1)
487 nband=input.nrOfBand();
490 cerr <<
"filter not implemented" << endl;
499 std::cout <<
"opening output image " << output_opt[0] <<
" with " << nband <<
" bands" << std::endl;
500 output.open(output_opt[0],(input.nrOfCol()+down_opt[0]-1)/down_opt[0],(input.nrOfRow()+down_opt[0]-1)/down_opt[0],nband,theType,imageType,option_opt);
502 catch(
string errorstring){
503 cout << errorstring << endl;
506 output.setProjection(input.getProjection());
508 input.getGeoTransform(gt);
511 output.setGeoTransform(gt);
513 if(colorTable_opt.size()){
514 if(colorTable_opt[0]!=
"none"){
516 cout <<
"set colortable " << colorTable_opt[0] << endl;
517 assert(output.getDataType()==GDT_Byte);
518 output.setColorTable(colorTable_opt[0]);
521 else if(input.getColorTable()!=NULL)
522 output.setColorTable(input.getColorTable());
524 if(nodata_opt.size()){
525 for(
int iband=0;iband<output.nrOfBand();++iband)
526 output.GDALSetNoDataValue(nodata_opt[0],iband);
532 cout <<
"Set padding to " << padding_opt[0] << endl;
533 filter1d.setPadding(padding_opt[0]);
534 if(class_opt.size()){
536 std::cout<<
"class values: ";
537 for(
int iclass=0;iclass<class_opt.size();++iclass){
539 filter2d.pushClass(class_opt[iclass]);
541 filter1d.pushClass(class_opt[iclass]);
543 std::cout<< class_opt[iclass] <<
" ";
546 std::cout<< std::endl;
549 if(nodata_opt.size()){
551 std::cout<<
"mask values: ";
552 for(
int imask=0;imask<nodata_opt.size();++imask){
554 std::cout<< nodata_opt[imask] <<
" ";
555 filter1d.pushNoDataValue(nodata_opt[imask]);
556 filter2d.pushNoDataValue(nodata_opt[imask]);
559 std::cout<< std::endl;
562 ifstream tapfile(tap_opt[0].c_str());
566 for(
int j=0;j<dimY_opt[0];++j){
567 for(
int i=0;i<dimX_opt[0];++i){
568 tapfile >> taps[j][i];
572 std::cout <<
"taps: ";
573 for(
int j=0;j<dimY_opt[0];++j){
574 for(
int i=0;i<dimX_opt[0];++i){
575 std::cout<< taps[j][i] <<
" ";
577 std::cout<< std::endl;
580 filter2d.setTaps(taps);
582 filter2d.filter(input,output);
584 catch(
string errorstring){
585 cerr << errorstring << endl;
589 else if(tapz_opt.size()){
591 std::cout <<
"taps: ";
592 for(
int itap=0;itap<tapz_opt.size();++itap)
593 std::cout<< tapz_opt[itap] <<
" ";
594 std::cout<< std::endl;
596 filter1d.setTaps(tapz_opt);
597 filter1d.filter(input,output);
599 else if(fwhm_opt.size()){
601 std::cout <<
"spectral filtering to " << fwhm_opt.size() <<
" bands with provided fwhm " << std::endl;
602 assert(wavelengthOut_opt.size()==fwhm_opt.size());
603 assert(wavelengthIn_opt.size());
607 const char* pszMessage;
608 void* pProgressArg=NULL;
609 GDALProgressFunc pfnProgress=GDALTermProgress;
611 pfnProgress(progress,pszMessage,pProgressArg);
612 for(
int y=0;y<input.nrOfRow();++y){
613 if((y+1+down_opt[0]/2)%down_opt[0])
615 for(
int iband=0;iband<input.nrOfBand();++iband)
616 input.readData(lineInput[iband],GDT_Float64,y,iband);
617 filter1d.applyFwhm<
double>(wavelengthIn_opt,lineInput,wavelengthOut_opt,fwhm_opt, interpolationType_opt[0], lineOutput, down_opt[0], verbose_opt[0]);
618 for(
int iband=0;iband<output.nrOfBand();++iband){
620 output.writeData(lineOutput[iband],GDT_Float64,y/down_opt[0],iband);
622 catch(
string errorstring){
623 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
626 progress=(1.0+y)/output.nrOfRow();
627 pfnProgress(progress,pszMessage,pProgressArg);
630 else if(srf_opt.size()){
632 std::cout <<
"spectral filtering to " << srf_opt.size() <<
" bands with provided SRF " << std::endl;
633 assert(wavelengthIn_opt.size());
634 vector< Vector2d<double> > srf(srf_opt.size());
636 for(
int isrf=0;isrf<srf_opt.size();++isrf){
638 srfFile.open(srf_opt[isrf].c_str());
641 srf[isrf][0].push_back(0);
642 srf[isrf][1].push_back(0);
643 srf[isrf][0].push_back(1);
644 srf[isrf][1].push_back(0);
646 srf[isrf][0].push_back(v);
648 srf[isrf][1].push_back(v);
652 srf[isrf][0].push_back(srf[isrf][0].back()+1);
653 srf[isrf][1].push_back(0);
654 srf[isrf][0].push_back(srf[isrf][0].back()+1);
655 srf[isrf][1].push_back(0);
657 cout <<
"srf file details: " << srf[isrf][0].size() <<
" wavelengths defined" << endl;
659 assert(output.nrOfBand()==srf.size());
660 double centreWavelength=0;
662 const char* pszMessage;
663 void* pProgressArg=NULL;
664 GDALProgressFunc pfnProgress=GDALTermProgress;
666 pfnProgress(progress,pszMessage,pProgressArg);
667 for(
int y=0;y<input.nrOfRow();++y){
668 if((y+1+down_opt[0]/2)%down_opt[0])
670 for(
int iband=0;iband<input.nrOfBand();++iband)
671 input.readData(lineInput[iband],GDT_Float64,y,iband);
672 for(
int isrf=0;isrf<srf.size();++isrf){
673 vector<double> lineOutput(output.nrOfCol());
676 centreWavelength=filter1d.applySrf<
double>(wavelengthIn_opt,lineInput,srf[isrf], interpolationType_opt[0], lineOutput, delta, normalize);
678 std::cout <<
"centre wavelength srf " << isrf <<
": " << centreWavelength << std::endl;
680 output.writeData(lineOutput,GDT_Float64,y/down_opt[0],isrf);
682 catch(
string errorstring){
683 cerr << errorstring <<
"in srf " << srf_opt[isrf] <<
", line " << y << endl;
687 progress=(1.0+y)/output.nrOfRow();
688 pfnProgress(progress,pszMessage,pProgressArg);
693 switch(filter2d::Filter2d::getFilterType(method_opt[0])){
694 case(filter2d::dilate):
696 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
702 std::cout<<
"1-D filtering: dilate" << std::endl;
703 filter1d.morphology(input,output,
"dilate",dimZ_opt[0],verbose_opt[0]);
706 filter2d.morphology(input,output,
"dilate",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
708 catch(
string errorstring){
709 cerr << errorstring << endl;
712 case(filter2d::erode):
714 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
718 if(dimZ_opt.size()>0){
720 std::cout<<
"1-D filtering: dilate" << std::endl;
721 filter1d.morphology(input,output,
"erode",dimZ_opt[0]);
724 filter2d.morphology(input,output,
"erode",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
727 catch(
string errorstring){
728 cerr << errorstring << endl;
731 case(filter2d::close):{
733 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
738 tmpout.open(
"/vsimem/dilation.tif",input.nrOfCol(),input.nrOfRow(),input.nrOfBand(),input.getDataType(),input.getImageType());
741 filter1d.morphology(input,tmpout,
"dilate",dimZ_opt[0]);
744 filter2d.morphology(input,tmpout,
"dilate",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
747 catch(std::string errorString){
748 std::cout<< errorString;
753 tmpin.open(
"/vsimem/dilation.tif");
756 filter1d.morphology(tmpin,output,
"erode",dimZ_opt[0]);
759 filter2d.morphology(tmpin,output,
"erode",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
762 catch(
string errorstring){
763 cerr << errorstring << endl;
768 case(filter2d::open):{
770 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
774 tmpout.open(
"/vsimem/erosion.tif",input.nrOfCol(),input.nrOfRow(),input.nrOfBand(),input.getDataType(),input.getImageType());
777 filter1d.morphology(input,tmpout,
"erode",dimZ_opt[0]);
780 filter2d.morphology(input,tmpout,
"erode",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
783 catch(std::string errorString){
784 std::cout<< errorString;
790 tmpin.open(
"/vsimem/erosion.tif");
792 filter1d.morphology(tmpin,output,
"dilate",dimZ_opt[0]);
795 filter2d.morphology(tmpin,output,
"dilate",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
800 catch(
string errorstring){
801 cerr << errorstring << endl;
805 case(filter2d::homog):{
807 filter2d.doit(input,output,
"homog",dimX_opt[0],dimY_opt[0],down_opt[0],disc_opt[0]);
809 catch(
string errorstring){
810 cerr << errorstring << endl;
814 case(filter2d::heterog):{
816 filter2d.doit(input,output,
"heterog",dimX_opt[0],dimY_opt[0],down_opt[0],disc_opt[0]);
818 catch(
string errorstring){
819 cerr << errorstring << endl;
823 case(filter2d::shift):{
825 std::cerr <<
"Error: down option not supported for shift operator" << std::endl;
828 assert(input.nrOfBand());
829 assert(input.nrOfCol());
830 assert(input.nrOfRow());
832 filter2d.shift(input,output,dimX_opt[0],dimY_opt[0],threshold_opt[0],filter2d::Filter2d::getResampleType(resample_opt[0]));
834 catch(
string errorstring){
835 cerr << errorstring << endl;
861 case(filter2d::mrf):{
863 std::cout <<
"Markov Random Field filtering" << std::endl;
870 vector<int> cols(class_opt.size());
871 for(
int iclass=0;iclass<class_opt.size();++iclass)
873 betaReader.readData(beta,cols);
875 std::cout <<
"using values for beta:" << std::endl;
876 for(
int iclass1=0;iclass1<class_opt.size();++iclass1)
877 std::cout <<
" " << iclass1 <<
" (" << class_opt[iclass1] <<
")";
878 std::cout << std::endl;
879 for(
int iclass1=0;iclass1<class_opt.size();++iclass1){
880 std::cout << iclass1 <<
" (" << class_opt[iclass1] <<
")";
881 for(
int iclass2=0;iclass2<class_opt.size();++iclass2)
882 std::cout <<
" " << beta[iclass2][iclass1] <<
" (" << class_opt[iclass2] <<
")";
883 std::cout << std::endl;
886 filter2d.mrf(input, output, dimX_opt[0], dimY_opt[0], beta,
true, down_opt[0], verbose_opt[0]);
889 filter2d.mrf(input, output, dimX_opt[0], dimY_opt[0], 1,
true, down_opt[0], verbose_opt[0]);
891 catch(
string errorstring){
892 cerr << errorstring << endl;
896 case(filter2d::sobelx):{
898 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
911 filter2d.setTaps(theTaps);
913 filter2d.filter(input,output,
true,
true);
915 catch(
string errorstring){
916 cerr << errorstring << endl;
920 case(filter2d::sobely):{
922 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
935 filter2d.setTaps(theTaps);
937 filter2d.filter(input,output,
true,
true);
939 catch(
string errorstring){
940 cerr << errorstring << endl;
944 case(filter2d::sobelxy):{
946 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
959 filter2d.setTaps(theTaps);
961 filter2d.filter(input,output,
true,
true);
963 catch(
string errorstring){
964 cerr << errorstring << endl;
968 case(filter2d::sobelyx):{
970 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
983 filter2d.setTaps(theTaps);
985 filter2d.filter(input,output,
true,
true);
987 catch(
string errorstring){
988 cerr << errorstring << endl;
992 case(filter2d::smooth):{
994 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1000 std::cout<<
"1-D filtering: smooth" << std::endl;
1001 filter1d.smooth(input,output,dimZ_opt[0]);
1004 filter2d.smooth(input,output,dimX_opt[0],dimY_opt[0]);
1007 catch(
string errorstring){
1008 cerr << errorstring << endl;
1012 case(filter2d::smoothnodata):{
1014 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1018 if(dimZ_opt.size()){
1020 std::cout<<
"1-D filtering: smooth" << std::endl;
1021 filter1d.smoothNoData(input,interpolationType_opt[0],output);
1025 std::cout<<
"2-D filtering: smooth" << std::endl;
1026 filter2d.smoothNoData(input,output,dimX_opt[0],dimY_opt[0]);
1029 catch(
string errorstring){
1030 cerr << errorstring << endl;
1034 case(filter2d::dwt):
1036 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1040 if(dimZ_opt.size()){
1042 std::cout<<
"DWT in spectral domain" << std::endl;
1043 filter1d.dwtForward(input, output, wavelet_type_opt[0], family_opt[0]);
1046 filter2d.dwtForward(input, output, wavelet_type_opt[0], family_opt[0]);
1048 catch(
string errorstring){
1049 cerr << errorstring << endl;
1052 case(filter2d::dwti):
1054 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1058 if(dimZ_opt.size()){
1060 std::cout<<
"inverse DWT in spectral domain" << std::endl;
1061 filter1d.dwtInverse(input, output, wavelet_type_opt[0], family_opt[0]);
1064 filter2d.dwtInverse(input, output, wavelet_type_opt[0], family_opt[0]);
1066 catch(
string errorstring){
1067 cerr << errorstring << endl;
1070 case(filter2d::dwt_cut):
1072 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1075 if(dimZ_opt.size()){
1077 std::cout<<
"DWT approximation in spectral domain" << std::endl;
1078 filter1d.dwtCut(input, output, wavelet_type_opt[0], family_opt[0], threshold_opt[0]);
1081 filter2d.dwtCut(input, output, wavelet_type_opt[0], family_opt[0], threshold_opt[0]);
1083 case(filter2d::dwt_cut_from):
1085 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1089 if(dimZ_opt.size()){
1091 std::cout<<
"DWT approximation in spectral domain" << std::endl;
1092 filter1d.dwtCutFrom(input, output, wavelet_type_opt[0], family_opt[0], static_cast<int>(threshold_opt[0]));
1095 string errorString=
"Error: this filter is not supported in 2D";
1099 catch(
string errorstring){
1100 cerr << errorstring << endl;
1103 case(filter2d::savgolay):{
1104 assert(savgolay_nl_opt.size());
1105 assert(savgolay_nr_opt.size());
1106 assert(savgolay_ld_opt.size());
1107 assert(savgolay_m_opt.size());
1109 std::cout <<
"Calculating Savitzky-Golay coefficients: " << endl;
1110 filter1d.getSavGolayCoefficients(tapz_opt, input.nrOfBand(), savgolay_nl_opt[0], savgolay_nr_opt[0], savgolay_ld_opt[0], savgolay_m_opt[0]);
1112 std::cout <<
"taps (size is " << tapz_opt.size() <<
"): ";
1113 for(
int itap=0;itap<tapz_opt.size();++itap)
1114 std::cout<< tapz_opt[itap] <<
" ";
1115 std::cout<< std::endl;
1117 filter1d.setTaps(tapz_opt);
1118 filter1d.filter(input,output);
1121 case(filter2d::percentile):
1122 case(filter2d::threshold):
1123 assert(threshold_opt.size());
1125 filter1d.setThresholds(threshold_opt);
1127 filter2d.setThresholds(threshold_opt);
1128 case(filter2d::density):
1129 filter2d.setClasses(class_opt);
1131 std::cout <<
"classes set" << std::endl;
1134 if(dimZ_opt.size()){
1136 filter1d.stat(input,output,method_opt[0]);
1138 assert(down_opt[0]==1);
1139 filter1d.filter(input,output,method_opt[0],dimZ_opt[0]);
1143 filter2d.doit(input,output,method_opt[0],dimX_opt[0],dimY_opt[0],down_opt[0],disc_opt[0]);
1145 catch(
string errorstring){
1146 cerr << errorstring << endl;