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"
121 int main(
int argc,
char **argv) {
125 Optionpk<bool> disc_opt(
"circ",
"circular",
"circular disc kernel for dilation and erosion",
false);
127 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), smooth, density, countid, mode (majority voting, only for classes), smoothnodata (smooth nodata values only) values, threshold local filtering, ismin, ismax, order (rank pixels in order), stdev, mrf, dwt, dwti, dwt_cut, dwt_cut_from, scramble, shift, savgolay, percentile)");
128 Optionpk<std::string> resample_opt(
"r",
"resampling-method",
"Resampling method for shifting operation (near: nearest neighbour, bilinear: bi-linear interpolation).",
"near");
129 Optionpk<double> dimX_opt(
"dx",
"dx",
"filter kernel size in x, better use odd value to avoid image shift", 3);
130 Optionpk<double> dimY_opt(
"dy",
"dy",
"filter kernel size in y, better use odd value to avoid image shift", 3);
131 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");
132 Optionpk<std::string> wavelet_type_opt(
"wt",
"wavelet",
"wavelet type: daubechies,daubechies_centered, haar, haar_centered, bspline, bspline_centered",
"daubechies");
133 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);
134 Optionpk<int> savgolay_nl_opt(
"nl",
"nl",
"Number of leftward (past) data points used in Savitzky-Golay filter)", 2);
135 Optionpk<int> savgolay_nr_opt(
"nr",
"nr",
"Number of rightward (future) data points used in Savitzky-Golay filter)", 2);
136 Optionpk<int> savgolay_ld_opt(
"ld",
"ld",
"order of the derivative desired in Savitzky-Golay filter (e.g., ld=0 for smoothed function)", 0);
137 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);
138 Optionpk<short> class_opt(
"class",
"class",
"class value(s) to use for density, erosion, dilation, openening and closing, thresholding");
139 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);
140 Optionpk<double> nodata_opt(
"nodata",
"nodata",
"nodata value(s) (used for smoothnodata filter)");
141 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");
142 Optionpk<double> tapz_opt(
"tapz",
"tapz",
"taps used for spectral filtering");
143 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");
144 Optionpk<double> fwhm_opt(
"fwhm",
"fwhm",
"list of full width half to apply spectral filtering (-fwhm band1 -fwhm band2 ...)");
145 Optionpk<std::string> srf_opt(
"srf",
"srf",
"list of ASCII files containing spectral response functions (two columns: wavelength response)");
146 Optionpk<double> wavelengthIn_opt(
"win",
"wavelengthIn",
"list of wavelengths in input spectrum (-win band1 -win band2 ...)");
147 Optionpk<double> wavelengthOut_opt(
"wout",
"wavelengthOut",
"list of wavelengths in output spectrum (-wout band1 -wout band2 ...)");
148 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");
149 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",
"");
150 Optionpk<string> oformat_opt(
"of",
"oformat",
"Output image format (see also gdal_translate). Empty string: inherit from input image");
151 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");
152 Optionpk<string> option_opt(
"co",
"co",
"Creation option for output file. Multiple options can be specified.");
153 Optionpk<short> down_opt(
"d",
"down",
"down sampling factor. Use value 1 for no downsampling). Use value n>1 for downsampling (aggregation)", 1);
154 Optionpk<string> beta_opt(
"beta",
"beta",
"ASCII file with beta for each class transition in Markov Random Field");
160 Optionpk<short> verbose_opt(
"v",
"verbose",
"verbose mode if > 0", 0,2);
162 resample_opt.setHide(1);
163 option_opt.setHide(1);
164 wavelet_type_opt.setHide(1);
165 family_opt.setHide(1);
166 savgolay_nl_opt.setHide(1);
167 savgolay_nr_opt.setHide(1);
168 savgolay_ld_opt.setHide(1);
169 savgolay_m_opt.setHide(1);
170 class_opt.setHide(1);
171 threshold_opt.setHide(1);
174 padding_opt.setHide(1);
175 wavelengthIn_opt.setHide(1);
176 wavelengthOut_opt.setHide(1);
184 interpolationType_opt.setHide(1);
185 otype_opt.setHide(1);
186 oformat_opt.setHide(1);
187 colorTable_opt.setHide(1);
192 doProcess=input_opt.retrieveOption(argc,argv);
193 output_opt.retrieveOption(argc,argv);
196 method_opt.retrieveOption(argc,argv);
197 srf_opt.retrieveOption(argc,argv);
198 fwhm_opt.retrieveOption(argc,argv);
199 dimX_opt.retrieveOption(argc,argv);
200 dimY_opt.retrieveOption(argc,argv);
201 dimZ_opt.retrieveOption(argc,argv);
202 nodata_opt.retrieveOption(argc,argv);
203 resample_opt.retrieveOption(argc,argv);
204 option_opt.retrieveOption(argc,argv);
205 wavelet_type_opt.retrieveOption(argc,argv);
206 family_opt.retrieveOption(argc,argv);
207 savgolay_nl_opt.retrieveOption(argc,argv);
208 savgolay_nr_opt.retrieveOption(argc,argv);
209 savgolay_ld_opt.retrieveOption(argc,argv);
210 savgolay_m_opt.retrieveOption(argc,argv);
211 class_opt.retrieveOption(argc,argv);
212 threshold_opt.retrieveOption(argc,argv);
213 tap_opt.retrieveOption(argc,argv);
214 tapz_opt.retrieveOption(argc,argv);
215 padding_opt.retrieveOption(argc,argv);
216 wavelengthIn_opt.retrieveOption(argc,argv);
217 wavelengthOut_opt.retrieveOption(argc,argv);
218 down_opt.retrieveOption(argc,argv);
219 beta_opt.retrieveOption(argc,argv);
225 interpolationType_opt.retrieveOption(argc,argv);
226 otype_opt.retrieveOption(argc,argv);
227 oformat_opt.retrieveOption(argc,argv);
228 colorTable_opt.retrieveOption(argc,argv);
229 disc_opt.retrieveOption(argc,argv);
230 verbose_opt.retrieveOption(argc,argv);
232 catch(
string predefinedString){
233 std::cout << predefinedString << std::endl;
238 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;
240 std::cout <<
"short option -h shows basic options only, use long option --help to show all options" << std::endl;
245 vector<double> angle_opt;
249 if(input_opt.empty()){
250 cerr <<
"Error: no input file selected, use option -i" << endl;
253 if(output_opt.empty()){
254 cerr <<
"Error: no output file selected, use option -o" << endl;
257 input.open(input_opt[0]);
258 GDALDataType theType=GDT_Unknown;
260 cout <<
"possible output data types: ";
261 for(
int iType = 0; iType < GDT_TypeCount; ++iType){
263 cout <<
" " << GDALGetDataTypeName((GDALDataType)iType);
264 if( GDALGetDataTypeName((GDALDataType)iType) != NULL
265 && EQUAL(GDALGetDataTypeName((GDALDataType)iType),
266 otype_opt[0].c_str()))
267 theType=(GDALDataType) iType;
269 if(theType==GDT_Unknown)
270 theType=input.getDataType();
273 std::cout << std::endl <<
"Output pixel type: " << GDALGetDataTypeName(theType) << endl;
275 string imageType=input.getImageType();
276 if(oformat_opt.size())
277 imageType=oformat_opt[0];
279 if(option_opt.findSubstring(
"INTERLEAVE=")==option_opt.end()){
280 string theInterleave=
"INTERLEAVE=";
281 theInterleave+=input.getInterleave();
282 option_opt.push_back(theInterleave);
285 int nband=input.nrOfBand();
288 nband=fwhm_opt.size();
289 else if(srf_opt.size())
290 nband=srf_opt.size();
291 else if(tap_opt.size()||tapz_opt.size())
292 nband=input.nrOfBand();
294 if(method_opt.empty()){
295 cerr <<
"Error: no filter selected, use option -f" << endl;
298 switch(filter2d::Filter2d::getFilterType(method_opt[0])){
299 case(filter2d::dilate):
300 case(filter2d::erode):
301 case(filter2d::close):
302 case(filter2d::open):
303 case(filter2d::smooth):
306 assert(dimZ_opt[0]>1);
307 nband=input.nrOfBand();
310 case(filter2d::dwti):
311 case(filter2d::dwt_cut):
312 case(filter2d::smoothnodata):
314 nband=input.nrOfBand();
316 case(filter2d::savgolay):
317 nband=input.nrOfBand();
319 dimZ_opt.push_back(1);
320 case(filter2d::dwt_cut_from):
323 nband=input.nrOfBand();
324 assert(threshold_opt.size());
327 cerr <<
"filter not implemented in spectral/temporal domain" << endl;
332 assert(class_opt.size()>1);
334 std::cout <<
"opening output image " << output_opt[0] << std::endl;
335 nband=class_opt.size();
336 case(filter2d::ismin):
337 case(filter2d::ismax):
338 case(filter2d::shift):
339 case(filter2d::scramble):
340 case(filter2d::mode):
341 case(filter2d::sobelx):
342 case(filter2d::sobely):
343 case(filter2d::sobelxy):
344 case(filter2d::countid):
345 case(filter2d::order):
346 case(filter2d::density):
347 case(filter2d::homog):
348 case(filter2d::heterog):
351 cerr <<
"filter not implemented in spectral/temporal domain" << endl;
365 case(filter2d::mean):
369 case(filter2d::stdev):
370 case(filter2d::median):
371 case(filter2d::percentile):
373 if(dimZ_opt.size()==1)
377 nband=input.nrOfBand();
380 cerr <<
"filter not implemented" << endl;
389 std::cout <<
"opening output image " << output_opt[0] <<
" with " << nband <<
" bands" << std::endl;
390 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);
392 catch(
string errorstring){
393 cout << errorstring << endl;
396 output.setProjection(input.getProjection());
398 input.getGeoTransform(gt);
401 output.setGeoTransform(gt);
403 if(colorTable_opt.size()){
404 if(colorTable_opt[0]!=
"none"){
406 cout <<
"set colortable " << colorTable_opt[0] << endl;
407 assert(output.getDataType()==GDT_Byte);
408 output.setColorTable(colorTable_opt[0]);
411 else if(input.getColorTable()!=NULL)
412 output.setColorTable(input.getColorTable());
414 if(nodata_opt.size()){
415 for(
int iband=0;iband<output.nrOfBand();++iband)
416 output.GDALSetNoDataValue(nodata_opt[0],iband);
422 cout <<
"Set padding to " << padding_opt[0] << endl;
423 filter1d.setPadding(padding_opt[0]);
424 if(class_opt.size()){
426 std::cout<<
"class values: ";
427 for(
int iclass=0;iclass<class_opt.size();++iclass){
429 filter2d.pushClass(class_opt[iclass]);
431 filter1d.pushClass(class_opt[iclass]);
433 std::cout<< class_opt[iclass] <<
" ";
436 std::cout<< std::endl;
439 if(nodata_opt.size()){
441 std::cout<<
"mask values: ";
442 for(
int imask=0;imask<nodata_opt.size();++imask){
444 std::cout<< nodata_opt[imask] <<
" ";
445 filter1d.pushNoDataValue(nodata_opt[imask]);
446 filter2d.pushNoDataValue(nodata_opt[imask]);
449 std::cout<< std::endl;
452 ifstream tapfile(tap_opt[0].c_str());
456 for(
int j=0;j<dimY_opt[0];++j){
457 for(
int i=0;i<dimX_opt[0];++i){
458 tapfile >> taps[j][i];
462 std::cout <<
"taps: ";
463 for(
int j=0;j<dimY_opt[0];++j){
464 for(
int i=0;i<dimX_opt[0];++i){
465 std::cout<< taps[j][i] <<
" ";
467 std::cout<< std::endl;
470 filter2d.setTaps(taps);
472 filter2d.filter(input,output);
474 catch(
string errorstring){
475 cerr << errorstring << endl;
479 else if(tapz_opt.size()){
481 std::cout <<
"taps: ";
482 for(
int itap=0;itap<tapz_opt.size();++itap)
483 std::cout<< tapz_opt[itap] <<
" ";
484 std::cout<< std::endl;
486 filter1d.setTaps(tapz_opt);
487 filter1d.filter(input,output);
489 else if(fwhm_opt.size()){
491 std::cout <<
"spectral filtering to " << fwhm_opt.size() <<
" bands with provided fwhm " << std::endl;
492 assert(wavelengthOut_opt.size()==fwhm_opt.size());
493 assert(wavelengthIn_opt.size());
497 const char* pszMessage;
498 void* pProgressArg=NULL;
499 GDALProgressFunc pfnProgress=GDALTermProgress;
501 pfnProgress(progress,pszMessage,pProgressArg);
502 for(
int y=0;y<input.nrOfRow();++y){
503 if((y+1+down_opt[0]/2)%down_opt[0])
505 for(
int iband=0;iband<input.nrOfBand();++iband)
506 input.readData(lineInput[iband],GDT_Float64,y,iband);
507 filter1d.applyFwhm<
double>(wavelengthIn_opt,lineInput,wavelengthOut_opt,fwhm_opt, interpolationType_opt[0], lineOutput, down_opt[0], verbose_opt[0]);
508 for(
int iband=0;iband<output.nrOfBand();++iband){
510 output.writeData(lineOutput[iband],GDT_Float64,y/down_opt[0],iband);
512 catch(
string errorstring){
513 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
516 progress=(1.0+y)/output.nrOfRow();
517 pfnProgress(progress,pszMessage,pProgressArg);
520 else if(srf_opt.size()){
522 std::cout <<
"spectral filtering to " << srf_opt.size() <<
" bands with provided SRF " << std::endl;
523 assert(wavelengthIn_opt.size());
524 vector< Vector2d<double> > srf(srf_opt.size());
526 for(
int isrf=0;isrf<srf_opt.size();++isrf){
528 srfFile.open(srf_opt[isrf].c_str());
531 srf[isrf][0].push_back(0);
532 srf[isrf][1].push_back(0);
533 srf[isrf][0].push_back(1);
534 srf[isrf][1].push_back(0);
536 srf[isrf][0].push_back(v);
538 srf[isrf][1].push_back(v);
542 srf[isrf][0].push_back(srf[isrf][0].back()+1);
543 srf[isrf][1].push_back(0);
544 srf[isrf][0].push_back(srf[isrf][0].back()+1);
545 srf[isrf][1].push_back(0);
547 cout <<
"srf file details: " << srf[isrf][0].size() <<
" wavelengths defined" << endl;
549 assert(output.nrOfBand()==srf.size());
550 double centreWavelength=0;
552 const char* pszMessage;
553 void* pProgressArg=NULL;
554 GDALProgressFunc pfnProgress=GDALTermProgress;
556 pfnProgress(progress,pszMessage,pProgressArg);
557 for(
int y=0;y<input.nrOfRow();++y){
558 if((y+1+down_opt[0]/2)%down_opt[0])
560 for(
int iband=0;iband<input.nrOfBand();++iband)
561 input.readData(lineInput[iband],GDT_Float64,y,iband);
562 for(
int isrf=0;isrf<srf.size();++isrf){
563 vector<double> lineOutput(output.nrOfCol());
566 centreWavelength=filter1d.applySrf<
double>(wavelengthIn_opt,lineInput,srf[isrf], interpolationType_opt[0], lineOutput, delta, normalize);
568 std::cout <<
"centre wavelength srf " << isrf <<
": " << centreWavelength << std::endl;
570 output.writeData(lineOutput,GDT_Float64,y/down_opt[0],isrf);
572 catch(
string errorstring){
573 cerr << errorstring <<
"in srf " << srf_opt[isrf] <<
", line " << y << endl;
577 progress=(1.0+y)/output.nrOfRow();
578 pfnProgress(progress,pszMessage,pProgressArg);
583 switch(filter2d::Filter2d::getFilterType(method_opt[0])){
584 case(filter2d::dilate):
586 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
592 std::cout<<
"1-D filtering: dilate" << std::endl;
593 filter1d.morphology(input,output,
"dilate",dimZ_opt[0],verbose_opt[0]);
596 filter2d.morphology(input,output,
"dilate",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
598 catch(
string errorstring){
599 cerr << errorstring << endl;
602 case(filter2d::erode):
604 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
608 if(dimZ_opt.size()>0){
610 std::cout<<
"1-D filtering: dilate" << std::endl;
611 filter1d.morphology(input,output,
"erode",dimZ_opt[0]);
614 filter2d.morphology(input,output,
"erode",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
617 catch(
string errorstring){
618 cerr << errorstring << endl;
621 case(filter2d::close):{
623 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
628 tmpout.open(
"/vsimem/dilation.tif",input.nrOfCol(),input.nrOfRow(),input.nrOfBand(),input.getDataType(),input.getImageType());
631 filter1d.morphology(input,tmpout,
"dilate",dimZ_opt[0]);
634 filter2d.morphology(input,tmpout,
"dilate",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
637 catch(std::string errorString){
638 std::cout<< errorString;
643 tmpin.open(
"/vsimem/dilation.tif");
646 filter1d.morphology(tmpin,output,
"erode",dimZ_opt[0]);
649 filter2d.morphology(tmpin,output,
"erode",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
652 catch(
string errorstring){
653 cerr << errorstring << endl;
658 case(filter2d::open):{
660 std::cerr <<
"Error: down option not supported for morphological operator" << std::endl;
664 tmpout.open(
"/vsimem/erosion.tif",input.nrOfCol(),input.nrOfRow(),input.nrOfBand(),input.getDataType(),input.getImageType());
667 filter1d.morphology(input,tmpout,
"erode",dimZ_opt[0]);
670 filter2d.morphology(input,tmpout,
"erode",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
673 catch(std::string errorString){
674 std::cout<< errorString;
680 tmpin.open(
"/vsimem/erosion.tif");
682 filter1d.morphology(tmpin,output,
"dilate",dimZ_opt[0]);
685 filter2d.morphology(tmpin,output,
"dilate",dimX_opt[0],dimY_opt[0],angle_opt,disc_opt[0]);
690 catch(
string errorstring){
691 cerr << errorstring << endl;
695 case(filter2d::homog):{
697 filter2d.doit(input,output,
"homog",dimX_opt[0],dimY_opt[0],down_opt[0],disc_opt[0]);
699 catch(
string errorstring){
700 cerr << errorstring << endl;
704 case(filter2d::heterog):{
706 filter2d.doit(input,output,
"heterog",dimX_opt[0],dimY_opt[0],down_opt[0],disc_opt[0]);
708 catch(
string errorstring){
709 cerr << errorstring << endl;
713 case(filter2d::shift):{
715 std::cerr <<
"Error: down option not supported for shift operator" << std::endl;
718 assert(input.nrOfBand());
719 assert(input.nrOfCol());
720 assert(input.nrOfRow());
722 filter2d.shift(input,output,dimX_opt[0],dimY_opt[0],threshold_opt[0],filter2d::Filter2d::getResampleType(resample_opt[0]));
724 catch(
string errorstring){
725 cerr << errorstring << endl;
751 case(filter2d::mrf):{
753 std::cout <<
"Markov Random Field filtering" << std::endl;
760 vector<int> cols(class_opt.size());
761 for(
int iclass=0;iclass<class_opt.size();++iclass)
763 betaReader.readData(beta,cols);
765 std::cout <<
"using values for beta:" << std::endl;
766 for(
int iclass1=0;iclass1<class_opt.size();++iclass1)
767 std::cout <<
" " << iclass1 <<
" (" << class_opt[iclass1] <<
")";
768 std::cout << std::endl;
769 for(
int iclass1=0;iclass1<class_opt.size();++iclass1){
770 std::cout << iclass1 <<
" (" << class_opt[iclass1] <<
")";
771 for(
int iclass2=0;iclass2<class_opt.size();++iclass2)
772 std::cout <<
" " << beta[iclass2][iclass1] <<
" (" << class_opt[iclass2] <<
")";
773 std::cout << std::endl;
776 filter2d.mrf(input, output, dimX_opt[0], dimY_opt[0], beta,
true, down_opt[0], verbose_opt[0]);
779 filter2d.mrf(input, output, dimX_opt[0], dimY_opt[0], 1,
true, down_opt[0], verbose_opt[0]);
781 catch(
string errorstring){
782 cerr << errorstring << endl;
786 case(filter2d::sobelx):{
788 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
801 filter2d.setTaps(theTaps);
803 filter2d.filter(input,output,
true,
true);
805 catch(
string errorstring){
806 cerr << errorstring << endl;
810 case(filter2d::sobely):{
812 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
825 filter2d.setTaps(theTaps);
827 filter2d.filter(input,output,
true,
true);
829 catch(
string errorstring){
830 cerr << errorstring << endl;
834 case(filter2d::sobelxy):{
836 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
849 filter2d.setTaps(theTaps);
851 filter2d.filter(input,output,
true,
true);
853 catch(
string errorstring){
854 cerr << errorstring << endl;
858 case(filter2d::sobelyx):{
860 std::cerr <<
"Error: down option not supported for sobel edge detection" << std::endl;
873 filter2d.setTaps(theTaps);
875 filter2d.filter(input,output,
true,
true);
877 catch(
string errorstring){
878 cerr << errorstring << endl;
882 case(filter2d::smooth):{
884 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
890 std::cout<<
"1-D filtering: smooth" << std::endl;
891 filter1d.smooth(input,output,dimZ_opt[0]);
894 filter2d.smooth(input,output,dimX_opt[0],dimY_opt[0]);
897 catch(
string errorstring){
898 cerr << errorstring << endl;
902 case(filter2d::smoothnodata):{
904 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
910 std::cout<<
"1-D filtering: smooth" << std::endl;
911 filter1d.smoothNoData(input,interpolationType_opt[0],output);
915 std::cout<<
"2-D filtering: smooth" << std::endl;
916 filter2d.smoothNoData(input,output,dimX_opt[0],dimY_opt[0]);
919 catch(
string errorstring){
920 cerr << errorstring << endl;
926 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
932 std::cout<<
"DWT in spectral domain" << std::endl;
933 filter1d.dwtForward(input, output, wavelet_type_opt[0], family_opt[0]);
936 filter2d.dwtForward(input, output, wavelet_type_opt[0], family_opt[0]);
938 catch(
string errorstring){
939 cerr << errorstring << endl;
942 case(filter2d::dwti):
944 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
950 std::cout<<
"inverse DWT in spectral domain" << std::endl;
951 filter1d.dwtInverse(input, output, wavelet_type_opt[0], family_opt[0]);
954 filter2d.dwtInverse(input, output, wavelet_type_opt[0], family_opt[0]);
956 catch(
string errorstring){
957 cerr << errorstring << endl;
960 case(filter2d::dwt_cut):
962 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
967 std::cout<<
"DWT approximation in spectral domain" << std::endl;
968 filter1d.dwtCut(input, output, wavelet_type_opt[0], family_opt[0], threshold_opt[0]);
971 filter2d.dwtCut(input, output, wavelet_type_opt[0], family_opt[0], threshold_opt[0]);
973 case(filter2d::dwt_cut_from):
975 std::cerr <<
"Error: down option not supported for this filter" << std::endl;
981 std::cout<<
"DWT approximation in spectral domain" << std::endl;
982 filter1d.dwtCutFrom(input, output, wavelet_type_opt[0], family_opt[0], static_cast<int>(threshold_opt[0]));
985 string errorString=
"Error: this filter is not supported in 2D";
989 catch(
string errorstring){
990 cerr << errorstring << endl;
993 case(filter2d::savgolay):{
994 assert(savgolay_nl_opt.size());
995 assert(savgolay_nr_opt.size());
996 assert(savgolay_ld_opt.size());
997 assert(savgolay_m_opt.size());
999 std::cout <<
"Calculating Savitzky-Golay coefficients: " << endl;
1000 filter1d.getSavGolayCoefficients(tapz_opt, input.nrOfBand(), savgolay_nl_opt[0], savgolay_nr_opt[0], savgolay_ld_opt[0], savgolay_m_opt[0]);
1002 std::cout <<
"taps (size is " << tapz_opt.size() <<
"): ";
1003 for(
int itap=0;itap<tapz_opt.size();++itap)
1004 std::cout<< tapz_opt[itap] <<
" ";
1005 std::cout<< std::endl;
1007 filter1d.setTaps(tapz_opt);
1008 filter1d.filter(input,output);
1011 case(filter2d::percentile):
1012 case(filter2d::threshold):
1013 assert(threshold_opt.size());
1015 filter1d.setThresholds(threshold_opt);
1017 filter2d.setThresholds(threshold_opt);
1018 case(filter2d::density):
1019 filter2d.setClasses(class_opt);
1021 std::cout <<
"classes set" << std::endl;
1024 if(dimZ_opt.size()){
1026 filter1d.stat(input,output,method_opt[0]);
1028 assert(down_opt[0]==1);
1029 filter1d.filter(input,output,method_opt[0],dimZ_opt[0]);
1033 filter2d.doit(input,output,method_opt[0],dimX_opt[0],dimY_opt[0],down_opt[0],disc_opt[0]);
1035 catch(
string errorstring){
1036 cerr << errorstring << endl;