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"
228 int main(
int argc,
char **argv) {
232 Optionpk<bool> disc_opt(
"circ",
"circular",
"circular disc kernel for dilation and erosion",
false);
234 Optionpk<std::string> method_opt(
"f",
"filter",
"filter function (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)");
235 Optionpk<std::string> resample_opt(
"r",
"resampling-method",
"Resampling method for shifting operation (near: nearest neighbour, bilinear: bi-linear interpolation).",
"near");
236 Optionpk<double> dimX_opt(
"dx",
"dx",
"filter kernel size in x, use odd values only", 3);
237 Optionpk<double> dimY_opt(
"dy",
"dy",
"filter kernel size in y, use odd values only", 3);
238 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");
239 Optionpk<std::string> wavelet_type_opt(
"wt",
"wavelet",
"wavelet type: daubechies,daubechies_centered, haar, haar_centered, bspline, bspline_centered",
"daubechies");
240 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);
241 Optionpk<int> savgolay_nl_opt(
"nl",
"nl",
"Number of leftward (past) data points used in Savitzky-Golay filter)", 2);
242 Optionpk<int> savgolay_nr_opt(
"nr",
"nr",
"Number of rightward (future) data points used in Savitzky-Golay filter)", 2);
243 Optionpk<int> savgolay_ld_opt(
"ld",
"ld",
"order of the derivative desired in Savitzky-Golay filter (e.g., ld=0 for smoothed function)", 0);
244 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);
245 Optionpk<short> class_opt(
"class",
"class",
"class value(s) to use for density, erosion, dilation, openening and closing, thresholding");
246 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);
247 Optionpk<double> nodata_opt(
"nodata",
"nodata",
"nodata value(s) (used for smoothnodata filter)");
248 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");
249 Optionpk<double> tapz_opt(
"tapz",
"tapz",
"taps used for spectral filtering");
250 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");
251 Optionpk<double> fwhm_opt(
"fwhm",
"fwhm",
"list of full width half to apply spectral filtering (-fwhm band1 -fwhm band2 ...)");
252 Optionpk<std::string> srf_opt(
"srf",
"srf",
"list of ASCII files containing spectral response functions (two columns: wavelength response)");
253 Optionpk<double> wavelengthIn_opt(
"win",
"wavelengthIn",
"list of wavelengths in input spectrum (-win band1 -win band2 ...)");
254 Optionpk<double> wavelengthOut_opt(
"wout",
"wavelengthOut",
"list of wavelengths in output spectrum (-wout band1 -wout band2 ...)");
255 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");
256 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",
"");
257 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate). Empty string: inherit from input image");
258 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");
259 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
260 Optionpk<short> down_opt(
"d",
"down",
"down sampling factor. Use value 1 for no downsampling). Use value n>1 for downsampling (aggregation)", 1);
261 Optionpk<string> beta_opt(
"beta",
"beta",
"ASCII file with beta for each class transition in Markov Random Field");
267 Optionpk<short> verbose_opt(
"v",
"verbose",
"verbose mode if > 0", 0,2);
269 resample_opt.setHide(1);
270 option_opt.setHide(1);
271 wavelet_type_opt.setHide(1);
272 family_opt.setHide(1);
273 savgolay_nl_opt.setHide(1);
274 savgolay_nr_opt.setHide(1);
275 savgolay_ld_opt.setHide(1);
276 savgolay_m_opt.setHide(1);
277 class_opt.setHide(1);
278 threshold_opt.setHide(1);
281 padding_opt.setHide(1);
282 wavelengthIn_opt.setHide(1);
283 wavelengthOut_opt.setHide(1);
291 interpolationType_opt.setHide(1);
292 otype_opt.setHide(1);
293 oformat_opt.setHide(1);
294 colorTable_opt.setHide(1);
299 doProcess=input_opt.retrieveOption(argc,argv);
300 output_opt.retrieveOption(argc,argv);
303 method_opt.retrieveOption(argc,argv);
304 srf_opt.retrieveOption(argc,argv);
305 fwhm_opt.retrieveOption(argc,argv);
306 dimX_opt.retrieveOption(argc,argv);
307 dimY_opt.retrieveOption(argc,argv);
308 dimZ_opt.retrieveOption(argc,argv);
309 nodata_opt.retrieveOption(argc,argv);
310 resample_opt.retrieveOption(argc,argv);
311 option_opt.retrieveOption(argc,argv);
312 wavelet_type_opt.retrieveOption(argc,argv);
313 family_opt.retrieveOption(argc,argv);
314 savgolay_nl_opt.retrieveOption(argc,argv);
315 savgolay_nr_opt.retrieveOption(argc,argv);
316 savgolay_ld_opt.retrieveOption(argc,argv);
317 savgolay_m_opt.retrieveOption(argc,argv);
318 class_opt.retrieveOption(argc,argv);
319 threshold_opt.retrieveOption(argc,argv);
320 tap_opt.retrieveOption(argc,argv);
321 tapz_opt.retrieveOption(argc,argv);
322 padding_opt.retrieveOption(argc,argv);
323 wavelengthIn_opt.retrieveOption(argc,argv);
324 wavelengthOut_opt.retrieveOption(argc,argv);
325 down_opt.retrieveOption(argc,argv);
326 beta_opt.retrieveOption(argc,argv);
332 interpolationType_opt.retrieveOption(argc,argv);
333 otype_opt.retrieveOption(argc,argv);
334 oformat_opt.retrieveOption(argc,argv);
335 colorTable_opt.retrieveOption(argc,argv);
336 disc_opt.retrieveOption(argc,argv);
337 verbose_opt.retrieveOption(argc,argv);
339 catch(
string predefinedString){
340 std::cout << predefinedString << std::endl;
345 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;
347 std::cout <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
352 vector<double> angle_opt;
356 if(input_opt.empty()){
357 cerr <<
"Error: no input file selected, use option -i" << endl;
360 if(output_opt.empty()){
361 cerr <<
"Error: no output file selected, use option -o" << endl;
364 input.open(input_opt[0]);
365 GDALDataType theType=GDT_Unknown;
367 cout <<
"possible output data types: ";
368 for(
int iType = 0; iType < GDT_TypeCount; ++iType){
370 cout <<
" " << GDALGetDataTypeName((GDALDataType)iType);
371 if( GDALGetDataTypeName((GDALDataType)iType) != NULL
372 && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
373 otype_opt[0].c_str()))
374 theType=(GDALDataType) iType;
376 if(theType==GDT_Unknown)
377 theType=input.getDataType();
380 std::cout << std::endl <<
"Output pixel type: " << GDALGetDataTypeName(theType) << endl;
382 string imageType=input.getImageType();
383 if(oformat_opt.size())
384 imageType=oformat_opt[0];
386 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
387 string theInterleave=
"INTERLEAVE=";
388 theInterleave+=input.getInterleave();
389 option_opt.push_back(theInterleave);
392 int nband=input.nrOfBand();
395 nband=fwhm_opt.size();
396 else if(srf_opt.size())
397 nband=srf_opt.size();
398 else if(tap_opt.size()||tapz_opt.size())
399 nband=input.nrOfBand();
401 if(method_opt.empty()){
402 cerr <<
"Error: no filter selected, use option -f" << endl;
405 switch(filter2d::Filter2d::getFilterType(method_opt[0])){
406 case(filter2d::dilate):
407 case(filter2d::erode):
408 case(filter2d::close):
409 case(filter2d::open):
410 case(filter2d::smooth):
413 assert(dimZ_opt[0]>1);
414 nband=input.nrOfBand();
417 case(filter2d::dwti):
418 case(filter2d::dwt_cut):
419 case(filter2d::smoothnodata):
421 nband=input.nrOfBand();
423 case(filter2d::savgolay):
424 nband=input.nrOfBand();
426 dimZ_opt.push_back(1);
427 case(filter2d::dwt_cut_from):
430 nband=input.nrOfBand();
431 assert(threshold_opt.size());
434 cerr <<
"filter not implemented in spatial domain" << endl;
439 assert(class_opt.size()>1);
441 std::cout <<
"opening output image " << output_opt[0] << std::endl;
442 nband=class_opt.size();
443 case(filter2d::ismin):
444 case(filter2d::ismax):
445 case(filter2d::shift):
446 case(filter2d::scramble):
447 case(filter2d::mode):
448 case(filter2d::sobelx):
449 case(filter2d::sobely):
450 case(filter2d::sobelxy):
451 case(filter2d::countid):
452 case(filter2d::order):
453 case(filter2d::density):
454 case(filter2d::homog):
455 case(filter2d::heterog):
458 cerr <<
"filter not implemented in spectral/temporal domain" << endl;
472 case(filter2d::mean):
476 case(filter2d::stdev):
477 case(filter2d::median):
478 case(filter2d::percentile):
479 case(filter2d::proportion):
481 if(dimZ_opt.size()==1)
485 nband=input.nrOfBand();
488 cerr <<
"filter not implemented" << endl;
497 std::cout <<
"opening output image " << output_opt[0] <<
" with " << nband <<
" bands" << std::endl;
498 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);
500 catch(
string errorstring){
501 cout << errorstring << endl;
504 output.setProjection(input.getProjection());
506 input.getGeoTransform(gt);
509 output.setGeoTransform(gt);
511 if(colorTable_opt.size()){
512 if(colorTable_opt[0]!=
"none"){
514 cout <<
"set colortable " << colorTable_opt[0] << endl;
515 assert(output.getDataType()==GDT_Byte);
516 output.setColorTable(colorTable_opt[0]);
519 else if(input.getColorTable()!=NULL)
520 output.setColorTable(input.getColorTable());
522 if(nodata_opt.size()){
523 for(
int iband=0;iband<output.nrOfBand();++iband)
524 output.GDALSetNoDataValue(nodata_opt[0],iband);
530 cout <<
"Set padding to " << padding_opt[0] << endl;
531 filter1d.setPadding(padding_opt[0]);
532 if(class_opt.size()){
534 std::cout<<
"class values: ";
535 for(
int iclass=0;iclass<class_opt.size();++iclass){
537 filter2d.pushClass(class_opt[iclass]);
539 filter1d.pushClass(class_opt[iclass]);
541 std::cout<< class_opt[iclass] <<
" ";
544 std::cout<< std::endl;
547 if(nodata_opt.size()){
549 std::cout<<
"mask values: ";
550 for(
int imask=0;imask<nodata_opt.size();++imask){
552 std::cout<< nodata_opt[imask] <<
" ";
553 filter1d.pushNoDataValue(nodata_opt[imask]);
554 filter2d.pushNoDataValue(nodata_opt[imask]);
557 std::cout<< std::endl;
560 ifstream tapfile(tap_opt[0].c_str());
564 for(
int j=0;j<dimY_opt[0];++j){
565 for(
int i=0;i<dimX_opt[0];++i){
566 tapfile >> taps[j][i];
570 std::cout <<
"taps: ";
571 for(
int j=0;j<dimY_opt[0];++j){
572 for(
int i=0;i<dimX_opt[0];++i){
573 std::cout<< taps[j][i] <<
" ";
575 std::cout<< std::endl;
578 filter2d.setTaps(taps);
580 filter2d.filter(input,output);
582 catch(
string errorstring){
583 cerr << errorstring << endl;
587 else if(tapz_opt.size()){
589 std::cout <<
"taps: ";
590 for(
int itap=0;itap<tapz_opt.size();++itap)
591 std::cout<< tapz_opt[itap] <<
" ";
592 std::cout<< std::endl;
594 filter1d.setTaps(tapz_opt);
595 filter1d.filter(input,output);
597 else if(fwhm_opt.size()){
599 std::cout <<
"spectral filtering to " << fwhm_opt.size() <<
" bands with provided fwhm " << std::endl;
600 assert(wavelengthOut_opt.size()==fwhm_opt.size());
601 assert(wavelengthIn_opt.size());
605 const char* pszMessage;
606 void* pProgressArg=NULL;
607 GDALProgressFunc pfnProgress=GDALTermProgress;
609 pfnProgress(progress,pszMessage,pProgressArg);
610 for(
int y=0;y<input.nrOfRow();++y){
611 if((y+1+down_opt[0]/2)%down_opt[0])
613 for(
int iband=0;iband<input.nrOfBand();++iband)
614 input.readData(lineInput[iband],GDT_Float64,y,iband);
615 filter1d.applyFwhm<
double>(wavelengthIn_opt,lineInput,wavelengthOut_opt,fwhm_opt, interpolationType_opt[0], lineOutput, down_opt[0], verbose_opt[0]);
616 for(
int iband=0;iband<output.nrOfBand();++iband){
618 output.writeData(lineOutput[iband],GDT_Float64,y/down_opt[0],iband);
620 catch(
string errorstring){
621 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
624 progress=(1.0+y)/output.nrOfRow();
625 pfnProgress(progress,pszMessage,pProgressArg);
628 else if(srf_opt.size()){
630 std::cout <<
"spectral filtering to " << srf_opt.size() <<
" bands with provided SRF " << std::endl;
631 assert(wavelengthIn_opt.size());
632 vector< Vector2d<double> > srf(srf_opt.size());
634 for(
int isrf=0;isrf<srf_opt.size();++isrf){
636 srfFile.open(srf_opt[isrf].c_str());
639 srf[isrf][0].push_back(0);
640 srf[isrf][1].push_back(0);
641 srf[isrf][0].push_back(1);
642 srf[isrf][1].push_back(0);
644 srf[isrf][0].push_back(v);
646 srf[isrf][1].push_back(v);
650 srf[isrf][0].push_back(srf[isrf][0].back()+1);
651 srf[isrf][1].push_back(0);
652 srf[isrf][0].push_back(srf[isrf][0].back()+1);
653 srf[isrf][1].push_back(0);
655 cout <<
"srf file details: " << srf[isrf][0].size() <<
" wavelengths defined" << endl;
657 assert(output.nrOfBand()==srf.size());
658 double centreWavelength=0;
660 const char* pszMessage;
661 void* pProgressArg=NULL;
662 GDALProgressFunc pfnProgress=GDALTermProgress;
664 pfnProgress(progress,pszMessage,pProgressArg);
665 for(
int y=0;y<input.nrOfRow();++y){
666 if((y+1+down_opt[0]/2)%down_opt[0])
668 for(
int iband=0;iband<input.nrOfBand();++iband)
669 input.readData(lineInput[iband],GDT_Float64,y,iband);
670 for(
int isrf=0;isrf<srf.size();++isrf){
671 vector<double> lineOutput(output.nrOfCol());
674 centreWavelength=filter1d.applySrf<
double>(wavelengthIn_opt,lineInput,srf[isrf], interpolationType_opt[0], lineOutput, delta, normalize);
676 std::cout <<
"centre wavelength srf " << isrf <<
": " << centreWavelength << std::endl;
678 output.writeData(lineOutput,GDT_Float64,y/down_opt[0],isrf);
680 catch(
string errorstring){
681 cerr << errorstring <<
"in srf " << srf_opt[isrf] <<
", line " << y << endl;
685 progress=(1.0+y)/output.nrOfRow();
686 pfnProgress(progress,pszMessage,pProgressArg);
691 switch(filter2d::Filter2d::getFilterType(method_opt[0])){
692 case(filter2d::dilate):
694 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
700 std::cout<<
"1-D filtering: dilate" << std::endl;
701 filter1d.morphology(input,output,
"dilate",dimZ_opt[0],verbose_opt[0]);
704 filter2d.morphology(input,output,
"dilate",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
706 catch(
string errorstring){
707 cerr << errorstring << endl;
710 case(filter2d::erode):
712 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
716 if(dimZ_opt.size()>0){
718 std::cout<<
"1-D filtering: dilate" << std::endl;
719 filter1d.morphology(input,output,
"erode",dimZ_opt[0]);
722 filter2d.morphology(input,output,
"erode",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
725 catch(
string errorstring){
726 cerr << errorstring << endl;
729 case(filter2d::close):{
731 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
736 tmpout.open(
"/vsimem/dilation.tif",input.nrOfCol(),input.nrOfRow(),input.nrOfBand(),input.getDataType(),input.getImageType());
739 filter1d.morphology(input,tmpout,
"dilate",dimZ_opt[0]);
742 filter2d.morphology(input,tmpout,
"dilate",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
745 catch(std::string errorString){
746 std::cout<< errorString;
751 tmpin.open(
"/vsimem/dilation.tif");
754 filter1d.morphology(tmpin,output,
"erode",dimZ_opt[0]);
757 filter2d.morphology(tmpin,output,
"erode",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
760 catch(
string errorstring){
761 cerr << errorstring << endl;
766 case(filter2d::open):{
768 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
772 tmpout.open(
"/vsimem/erosion.tif",input.nrOfCol(),input.nrOfRow(),input.nrOfBand(),input.getDataType(),input.getImageType());
775 filter1d.morphology(input,tmpout,
"erode",dimZ_opt[0]);
778 filter2d.morphology(input,tmpout,
"erode",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
781 catch(std::string errorString){
782 std::cout<< errorString;
788 tmpin.open(
"/vsimem/erosion.tif");
790 filter1d.morphology(tmpin,output,
"dilate",dimZ_opt[0]);
793 filter2d.morphology(tmpin,output,
"dilate",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
798 catch(
string errorstring){
799 cerr << errorstring << endl;
803 case(filter2d::homog):{
805 filter2d.doit(input,output,
"homog",dimX_opt[0],dimY_opt[0],down_opt[0],disc_opt[0]);
807 catch(
string errorstring){
808 cerr << errorstring << endl;
812 case(filter2d::heterog):{
814 filter2d.doit(input,output,
"heterog",dimX_opt[0],dimY_opt[0],down_opt[0],disc_opt[0]);
816 catch(
string errorstring){
817 cerr << errorstring << endl;
821 case(filter2d::shift):{
823 std::cerr <<
"Error: down option not supported for shift operator" << std::endl;
826 assert(input.nrOfBand());
827 assert(input.nrOfCol());
828 assert(input.nrOfRow());
830 filter2d.shift(input,output,dimX_opt[0],dimY_opt[0],threshold_opt[0],filter2d::Filter2d::getResampleType(resample_opt[0]));
832 catch(
string errorstring){
833 cerr << errorstring << endl;
859 case(filter2d::mrf):{
861 std::cout <<
"Markov Random Field filtering" << std::endl;
868 vector<int> cols(class_opt.size());
869 for(
int iclass=0;iclass<class_opt.size();++iclass)
871 betaReader.readData(beta,cols);
873 std::cout <<
"using values for beta:" << std::endl;
874 for(
int iclass1=0;iclass1<class_opt.size();++iclass1)
875 std::cout <<
" " << iclass1 <<
" (" << class_opt[iclass1] <<
")";
876 std::cout << std::endl;
877 for(
int iclass1=0;iclass1<class_opt.size();++iclass1){
878 std::cout << iclass1 <<
" (" << class_opt[iclass1] <<
")";
879 for(
int iclass2=0;iclass2<class_opt.size();++iclass2)
880 std::cout <<
" " << beta[iclass2][iclass1] <<
" (" << class_opt[iclass2] <<
")";
881 std::cout << std::endl;
884 filter2d.mrf(input, output, dimX_opt[0], dimY_opt[0], beta,
true, down_opt[0], verbose_opt[0]);
887 filter2d.mrf(input, output, dimX_opt[0], dimY_opt[0], 1,
true, down_opt[0], verbose_opt[0]);
889 catch(
string errorstring){
890 cerr << errorstring << endl;
894 case(filter2d::sobelx):{
896 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
909 filter2d.setTaps(theTaps);
911 filter2d.filter(input,output,
true,
true);
913 catch(
string errorstring){
914 cerr << errorstring << endl;
918 case(filter2d::sobely):{
920 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
933 filter2d.setTaps(theTaps);
935 filter2d.filter(input,output,
true,
true);
937 catch(
string errorstring){
938 cerr << errorstring << endl;
942 case(filter2d::sobelxy):{
944 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
957 filter2d.setTaps(theTaps);
959 filter2d.filter(input,output,
true,
true);
961 catch(
string errorstring){
962 cerr << errorstring << endl;
966 case(filter2d::sobelyx):{
968 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
981 filter2d.setTaps(theTaps);
983 filter2d.filter(input,output,
true,
true);
985 catch(
string errorstring){
986 cerr << errorstring << endl;
990 case(filter2d::smooth):{
992 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
998 std::cout<<
"1-D filtering: smooth" << std::endl;
999 filter1d.smooth(input,output,dimZ_opt[0]);
1002 filter2d.smooth(input,output,dimX_opt[0],dimY_opt[0]);
1005 catch(
string errorstring){
1006 cerr << errorstring << endl;
1010 case(filter2d::smoothnodata):{
1012 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1016 if(dimZ_opt.size()){
1018 std::cout<<
"1-D filtering: smooth" << std::endl;
1019 filter1d.smoothNoData(input,interpolationType_opt[0],output);
1023 std::cout<<
"2-D filtering: smooth" << std::endl;
1024 filter2d.smoothNoData(input,output,dimX_opt[0],dimY_opt[0]);
1027 catch(
string errorstring){
1028 cerr << errorstring << endl;
1032 case(filter2d::dwt):
1034 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1038 if(dimZ_opt.size()){
1040 std::cout<<
"DWT in spectral domain" << std::endl;
1041 filter1d.dwtForward(input, output, wavelet_type_opt[0], family_opt[0]);
1044 filter2d.dwtForward(input, output, wavelet_type_opt[0], family_opt[0]);
1046 catch(
string errorstring){
1047 cerr << errorstring << endl;
1050 case(filter2d::dwti):
1052 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1056 if(dimZ_opt.size()){
1058 std::cout<<
"inverse DWT in spectral domain" << std::endl;
1059 filter1d.dwtInverse(input, output, wavelet_type_opt[0], family_opt[0]);
1062 filter2d.dwtInverse(input, output, wavelet_type_opt[0], family_opt[0]);
1064 catch(
string errorstring){
1065 cerr << errorstring << endl;
1068 case(filter2d::dwt_cut):
1070 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1073 if(dimZ_opt.size()){
1075 std::cout<<
"DWT approximation in spectral domain" << std::endl;
1076 filter1d.dwtCut(input, output, wavelet_type_opt[0], family_opt[0], threshold_opt[0]);
1079 filter2d.dwtCut(input, output, wavelet_type_opt[0], family_opt[0], threshold_opt[0]);
1081 case(filter2d::dwt_cut_from):
1083 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
1087 if(dimZ_opt.size()){
1089 std::cout<<
"DWT approximation in spectral domain" << std::endl;
1090 filter1d.dwtCutFrom(input, output, wavelet_type_opt[0], family_opt[0], static_cast<int>(threshold_opt[0]));
1093 string errorString=
"Error: this filter is not supported in 2D";
1097 catch(
string errorstring){
1098 cerr << errorstring << endl;
1101 case(filter2d::savgolay):{
1102 assert(savgolay_nl_opt.size());
1103 assert(savgolay_nr_opt.size());
1104 assert(savgolay_ld_opt.size());
1105 assert(savgolay_m_opt.size());
1107 std::cout <<
"Calculating Savitzky-Golay coefficients: " << endl;
1108 filter1d.getSavGolayCoefficients(tapz_opt, input.nrOfBand(), savgolay_nl_opt[0], savgolay_nr_opt[0], savgolay_ld_opt[0], savgolay_m_opt[0]);
1110 std::cout <<
"taps (size is " << tapz_opt.size() <<
"): ";
1111 for(
int itap=0;itap<tapz_opt.size();++itap)
1112 std::cout<< tapz_opt[itap] <<
" ";
1113 std::cout<< std::endl;
1115 filter1d.setTaps(tapz_opt);
1116 filter1d.filter(input,output);
1119 case(filter2d::percentile):
1120 case(filter2d::threshold):
1121 assert(threshold_opt.size());
1123 filter1d.setThresholds(threshold_opt);
1125 filter2d.setThresholds(threshold_opt);
1126 case(filter2d::density):
1127 filter2d.setClasses(class_opt);
1129 std::cout <<
"classes set" << std::endl;
1132 if(dimZ_opt.size()){
1134 filter1d.stat(input,output,method_opt[0]);
1136 assert(down_opt[0]==1);
1137 filter1d.filter(input,output,method_opt[0],dimZ_opt[0]);
1141 filter2d.doit(input,output,method_opt[0],dimX_opt[0],dimY_opt[0],down_opt[0],disc_opt[0]);
1143 catch(
string errorstring){
1144 cerr << errorstring << endl;