27 filter::Filter::Filter(
void)
28 : m_padding(
"symmetric")
33 filter::Filter::Filter(
const vector<double> &taps)
34 : m_padding(
"symmetric")
39 void filter::Filter::setTaps(
const vector<double> &taps,
bool normalize)
41 m_taps.resize(taps.size());
43 for(
int itap=0;itap<taps.size();++itap)
46 for(
int itap=0;itap<taps.size();++itap)
47 m_taps[itap]=taps[itap]/norm;
51 assert(m_taps.size()%2);
54 int filter::Filter::pushNoDataValue(
double noDataValue)
56 if(find(m_noDataValues.begin(),m_noDataValues.end(),noDataValue)==m_noDataValues.end())
57 m_noDataValues.push_back(noDataValue);
58 return(m_noDataValues.size());
61 void filter::Filter::dwtForward(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family){
62 const char* pszMessage;
63 void* pProgressArg=NULL;
64 GDALProgressFunc pfnProgress=GDALTermProgress;
66 pfnProgress(progress,pszMessage,pProgressArg);
69 for(
int y=0;y<input.nrOfRow();++y){
70 for(
int iband=0;iband<input.nrOfBand();++iband)
71 input.readData(lineInput[iband],GDT_Float64,y,iband);
72 vector<double> pixelInput(input.nrOfBand());
73 for(
int x=0;x<input.nrOfCol();++x){
74 pixelInput=lineInput.selectCol(x);
75 dwtForward(pixelInput,wavelet_type,family);
76 for(
int iband=0;iband<input.nrOfBand();++iband)
77 lineOutput[iband][x]=pixelInput[iband];
79 for(
int iband=0;iband<input.nrOfBand();++iband){
81 output.writeData(lineOutput[iband],GDT_Float64,y,iband);
83 catch(
string errorstring){
84 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
87 progress=(1.0+y)/output.nrOfRow();
88 pfnProgress(progress,pszMessage,pProgressArg);
92 void filter::Filter::dwtInverse(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family){
93 const char* pszMessage;
94 void* pProgressArg=NULL;
95 GDALProgressFunc pfnProgress=GDALTermProgress;
97 pfnProgress(progress,pszMessage,pProgressArg);
100 for(
int y=0;y<input.nrOfRow();++y){
101 for(
int iband=0;iband<input.nrOfBand();++iband)
102 input.readData(lineInput[iband],GDT_Float64,y,iband);
103 vector<double> pixelInput(input.nrOfBand());
104 for(
int x=0;x<input.nrOfCol();++x){
105 pixelInput=lineInput.selectCol(x);
106 dwtInverse(pixelInput,wavelet_type,family);
107 for(
int iband=0;iband<input.nrOfBand();++iband)
108 lineOutput[iband][x]=pixelInput[iband];
110 for(
int iband=0;iband<input.nrOfBand();++iband){
112 output.writeData(lineOutput[iband],GDT_Float64,y,iband);
114 catch(
string errorstring){
115 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
118 progress=(1.0+y)/output.nrOfRow();
119 pfnProgress(progress,pszMessage,pProgressArg);
123 void filter::Filter::dwtCut(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family,
double cut){
124 const char* pszMessage;
125 void* pProgressArg=NULL;
126 GDALProgressFunc pfnProgress=GDALTermProgress;
128 pfnProgress(progress,pszMessage,pProgressArg);
131 for(
int y=0;y<input.nrOfRow();++y){
132 for(
int iband=0;iband<input.nrOfBand();++iband)
133 input.readData(lineInput[iband],GDT_Float64,y,iband);
134 vector<double> pixelInput(input.nrOfBand());
135 for(
int x=0;x<input.nrOfCol();++x){
136 pixelInput=lineInput.selectCol(x);
137 dwtCut(pixelInput,wavelet_type,family,cut);
138 for(
int iband=0;iband<input.nrOfBand();++iband)
139 lineOutput[iband][x]=pixelInput[iband];
141 for(
int iband=0;iband<input.nrOfBand();++iband){
143 output.writeData(lineOutput[iband],GDT_Float64,y,iband);
145 catch(
string errorstring){
146 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
149 progress=(1.0+y)/output.nrOfRow();
150 pfnProgress(progress,pszMessage,pProgressArg);
154 void filter::Filter::dwtCutFrom(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& wavelet_type,
int family,
int band){
155 const char* pszMessage;
156 void* pProgressArg=NULL;
157 GDALProgressFunc pfnProgress=GDALTermProgress;
159 pfnProgress(progress,pszMessage,pProgressArg);
162 for(
int y=0;y<input.nrOfRow();++y){
163 for(
int iband=0;iband<input.nrOfBand();++iband)
164 input.readData(lineInput[iband],GDT_Float64,y,iband);
165 vector<double> pixelInput(input.nrOfBand());
166 for(
int x=0;x<input.nrOfCol();++x){
167 pixelInput=lineInput.selectCol(x);
168 dwtForward(pixelInput,wavelet_type,family);
169 for(
int iband=0;iband<input.nrOfBand();++iband){
173 dwtInverse(pixelInput,wavelet_type,family);
174 for(
int iband=0;iband<input.nrOfBand();++iband)
175 lineOutput[iband][x]=pixelInput[iband];
177 for(
int iband=0;iband<input.nrOfBand();++iband){
179 output.writeData(lineOutput[iband],GDT_Float64,y,iband);
181 catch(
string errorstring){
182 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
185 progress=(1.0+y)/output.nrOfRow();
186 pfnProgress(progress,pszMessage,pProgressArg);
191 void filter::Filter::dwtForward(std::vector<double>& data,
const std::string& wavelet_type,
int family){
192 int origsize=data.size();
194 while(data.size()&(data.size()-1))
195 data.push_back(data.back());
197 int nsize=data.size();
199 gsl_wavelet_workspace *work;
201 w=gsl_wavelet_alloc(getWaveletType(wavelet_type),family);
202 work=gsl_wavelet_workspace_alloc(nsize);
203 gsl_wavelet_transform_forward(w,&(data[0]),1,nsize,work);
204 data.erase(data.begin()+origsize,data.end());
205 gsl_wavelet_free (w);
206 gsl_wavelet_workspace_free (work);
210 void filter::Filter::dwtInverse(std::vector<double>& data,
const std::string& wavelet_type,
int family){
211 int origsize=data.size();
213 while(data.size()&(data.size()-1))
214 data.push_back(data.back());
215 int nsize=data.size();
217 gsl_wavelet_workspace *work;
219 w=gsl_wavelet_alloc(getWaveletType(wavelet_type),family);
220 work=gsl_wavelet_workspace_alloc(nsize);
221 gsl_wavelet_transform_inverse(w,&(data[0]),1,nsize,work);
222 data.erase(data.begin()+origsize,data.end());
223 gsl_wavelet_free (w);
224 gsl_wavelet_workspace_free (work);
228 void filter::Filter::dwtCut(std::vector<double>& data,
const std::string& wavelet_type,
int family,
double cut){
229 int origsize=data.size();
231 while(data.size()&(data.size()-1))
232 data.push_back(data.back());
233 int nsize=data.size();
235 gsl_wavelet_workspace *work;
237 w=gsl_wavelet_alloc(getWaveletType(wavelet_type),family);
238 work=gsl_wavelet_workspace_alloc(nsize);
239 gsl_wavelet_transform_forward(w,&(data[0]),1,nsize,work);
240 std::vector<double> abscoeff(data.size());
241 size_t* p=
new size_t[data.size()];
242 for(
int index=0;index<data.size();++index){
243 abscoeff[index]=fabs(data[index]);
245 int nc=(100-cut)/100.0*nsize;
246 gsl_sort_index(p,&(abscoeff[0]),1,nsize);
247 for(
int i=0;(i+nc)<nsize;i++)
249 gsl_wavelet_transform_inverse(w,&(data[0]),1,nsize,work);
250 data.erase(data.begin()+origsize,data.end());
252 gsl_wavelet_free (w);
253 gsl_wavelet_workspace_free (work);
256 void filter::Filter::morphology(
const ImgReaderGdal& input,
ImgWriterGdal& output,
const std::string& method,
int dim,
short verbose)
261 const char* pszMessage;
262 void* pProgressArg=NULL;
263 GDALProgressFunc pfnProgress=GDALTermProgress;
265 pfnProgress(progress,pszMessage,pProgressArg);
266 for(
int y=0;y<input.nrOfRow();++y){
267 for(
int iband=0;iband<input.nrOfBand();++iband)
268 input.readData(lineInput[iband],GDT_Float64,y,iband);
269 vector<double> pixelInput(input.nrOfBand());
270 vector<double> pixelOutput(input.nrOfBand());
271 for(
int x=0;x<input.nrOfCol();++x){
272 pixelInput=lineInput.selectCol(x);
273 filter(pixelInput,pixelOutput,method,dim);
275 for(
int iband=0;iband<input.nrOfBand();++iband)
276 lineOutput[iband][x]=pixelOutput[iband];
278 for(
int iband=0;iband<input.nrOfBand();++iband){
280 output.writeData(lineOutput[iband],GDT_Float64,y,iband);
282 catch(
string errorstring){
283 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
286 progress=(1.0+y)/output.nrOfRow();
287 pfnProgress(progress,pszMessage,pProgressArg);
295 const char* pszMessage;
296 void* pProgressArg=NULL;
297 GDALProgressFunc pfnProgress=GDALTermProgress;
299 pfnProgress(progress,pszMessage,pProgressArg);
300 for(
int y=0;y<input.nrOfRow();++y){
301 for(
int iband=0;iband<input.nrOfBand();++iband)
302 input.readData(lineInput[iband],GDT_Float64,y,iband);
303 vector<double> pixelInput(input.nrOfBand());
304 vector<double> pixelOutput(input.nrOfBand());
305 for(
int x=0;x<input.nrOfCol();++x){
306 pixelInput=lineInput.selectCol(x);
307 smoothNoData(pixelInput,interpolationType,pixelOutput);
308 for(
int iband=0;iband<input.nrOfBand();++iband)
309 lineOutput[iband][x]=pixelOutput[iband];
311 for(
int iband=0;iband<input.nrOfBand();++iband){
313 output.writeData(lineOutput[iband],GDT_Float64,y,iband);
315 catch(
string errorstring){
316 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
319 progress=(1.0+y)/output.nrOfRow();
320 pfnProgress(progress,pszMessage,pProgressArg);
328 for(
int itap=0;itap<dim;++itap)
329 m_taps[itap]=1.0/dim;
330 filter(input,output);
337 const char* pszMessage;
338 void* pProgressArg=NULL;
339 GDALProgressFunc pfnProgress=GDALTermProgress;
341 pfnProgress(progress,pszMessage,pProgressArg);
342 for(
int y=0;y<input.nrOfRow();++y){
343 for(
int iband=0;iband<input.nrOfBand();++iband)
344 input.readData(lineInput[iband],GDT_Float64,y,iband);
345 vector<double> pixelInput(input.nrOfBand());
346 vector<double> pixelOutput(input.nrOfBand());
347 for(
int x=0;x<input.nrOfCol();++x){
348 pixelInput=lineInput.selectCol(x);
349 filter(pixelInput,pixelOutput);
350 for(
int iband=0;iband<input.nrOfBand();++iband)
351 lineOutput[iband][x]=pixelOutput[iband];
353 for(
int iband=0;iband<input.nrOfBand();++iband){
355 output.writeData(lineOutput[iband],GDT_Float64,y,iband);
357 catch(
string errorstring){
358 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
361 progress=(1.0+y)/output.nrOfRow();
362 pfnProgress(progress,pszMessage,pProgressArg);
369 assert(output.nrOfCol()==input.nrOfCol());
370 vector<double> lineOutput(output.nrOfCol());
372 stat.setNoDataValues(m_noDataValues);
373 const char* pszMessage;
374 void* pProgressArg=NULL;
375 GDALProgressFunc pfnProgress=GDALTermProgress;
377 pfnProgress(progress,pszMessage,pProgressArg);
378 for(
int y=0;y<input.nrOfRow();++y){
379 for(
int iband=0;iband<input.nrOfBand();++iband)
380 input.readData(lineInput[iband],GDT_Float64,y,iband);
381 vector<double> pixelInput(input.nrOfBand());
382 for(
int x=0;x<input.nrOfCol();++x){
383 pixelInput=lineInput.selectCol(x);
384 switch(getFilterType(method)){
385 case(filter::median):
386 lineOutput[x]=stat.median(pixelInput);
389 lineOutput[x]=stat.mymin(pixelInput);
392 lineOutput[x]=stat.mymax(pixelInput);
395 lineOutput[x]=stat.sum(pixelInput);
398 lineOutput[x]=stat.var(pixelInput);
401 lineOutput[x]=sqrt(stat.var(pixelInput));
404 lineOutput[x]=stat.mean(pixelInput);
406 case(filter::percentile):
407 assert(m_threshold.size());
408 lineOutput[x]=stat.percentile(pixelInput,pixelInput.begin(),pixelInput.end(),m_threshold[0]);
411 std::string errorString=
"method not supported";
417 output.writeData(lineOutput,GDT_Float64,y);
419 catch(
string errorstring){
420 cerr << errorstring <<
"in line " << y << endl;
422 progress=(1.0+y)/output.nrOfRow();
423 pfnProgress(progress,pszMessage,pProgressArg);
431 const char* pszMessage;
432 void* pProgressArg=NULL;
433 GDALProgressFunc pfnProgress=GDALTermProgress;
435 pfnProgress(progress,pszMessage,pProgressArg);
436 for(
int y=0;y<input.nrOfRow();++y){
437 for(
int iband=0;iband<input.nrOfBand();++iband)
438 input.readData(lineInput[iband],GDT_Float64,y,iband);
439 vector<double> pixelInput(input.nrOfBand());
440 vector<double> pixelOutput;
441 for(
int x=0;x<input.nrOfCol();++x){
442 pixelInput=lineInput.selectCol(x);
443 filter(pixelInput,pixelOutput,method,dim);
444 for(
int iband=0;iband<pixelOutput.size();++iband){
445 lineOutput[iband][x]=pixelOutput[iband];
450 for(
int iband=0;iband<input.nrOfBand();++iband){
452 output.writeData(lineOutput[iband],GDT_Float64,y,iband);
454 catch(
string errorstring){
455 cerr << errorstring <<
"in band " << iband <<
", line " << y << endl;
458 progress=(1.0+y)/output.nrOfRow();
459 pfnProgress(progress,pszMessage,pProgressArg);
463 void filter::Filter::getSavGolayCoefficients(vector<double> &tapz,
int np,
int nl,
int nr,
int ld,
int m) {
464 int j, k, imj, ipj, kk, mm;
468 vector<double> tmpc(np);
469 if(np < nl + nr + 1 || nl < 0 || nr < 0 || ld > m || nl + nr < m) {
470 cerr <<
"bad args in savgol" << endl;
473 vector<int> indx(m + 1, 0);
474 vector<double> a((m + 1) * (m + 1), 0.0);
475 vector<double> b(m + 1, 0.0);
477 for(ipj = 0; ipj <= (m << 1); ++ipj) {
478 sum = (ipj ? 0.0 : 1.0);
479 for(k = 1; k <= nr; ++k)
480 sum += (
int)pow((
double)k, (
double)ipj);
481 for(k = 1; k <= nl; ++k)
482 sum += (
int)pow((
double) - k, (
double)ipj);
483 mm = (ipj < 2 * m - ipj ? ipj : 2 * m - ipj);
484 for(imj = -mm; imj <= mm; imj += 2)
485 a[(ipj + imj) / 2 * (m + 1) + (ipj - imj) / 2] = sum;
489 for(j = 0; j < m + 1; ++j)
496 for(k = -nl; k <= nr; ++k) {
500 for(mm = 1; mm <= m; ++mm)
501 sum += b[mm] * (fac *= k);
508 tapz.resize(nl+1+nr);
510 tapz[tapz.size()/2]=tmpc[0];
512 for(k=1;k<=tapz.size()/2;++k)
513 tapz[tapz.size()/2-k]=tmpc[k];
515 for(k=1;k<=tapz.size()/2;++k)
516 tapz[tapz.size()/2+k]=tmpc[np-k];
519 void filter::Filter::ludcmp(vector<double> &a, vector<int> &indx,
double &d) {
520 const double TINY = 1.0e-20;
521 int i, imax = -1, j, k;
522 double big, dum, sum, temp;
525 vector<double> vv(n, 0.0);
528 for(i = 0; i < n; ++i) {
530 for(j = 0; j < n; ++j)
531 if((temp = fabs(a[i * n + j])) > big) big = temp;
534 cerr <<
"Singular matrix in routine ludcmp" << endl;
540 for(j = 0; j < n; ++j) {
541 for(i = 0; i < j; ++i) {
543 for(k = 0; k < i; ++k)
544 sum -= a[i * n + k] * a[k * n + j];
548 for(i = j; i < n; ++i) {
550 for(k = 0; k < j; ++k)
551 sum -= a[i * n + k] * a[k * n + j];
553 if((dum = vv[i] * fabs(sum)) >= big) {
560 for(k = 0; k < n; ++k) {
561 dum = a[imax * n + k];
562 a[imax * n + k] = a[j * n + k];
569 if(a[j * n + j] == 0.0) a[j * n + j] = TINY;
571 dum = 1. / a[j * n + j];
572 for(i = j + 1; i < n; ++i)
578 void filter::Filter::lubksb(vector<double> &a, vector<int> &indx, vector<double> &b) {
579 int i, ii = 0, ip, j;
583 for(i = 0; i < n; ++i) {
588 for(j = ii - 1; j < i; ++j)
589 sum -= a[i * n + j] * b[j];
594 for(i = n - 1; i >= 0; --i) {
596 for(j = i + 1; j < n; ++j)
597 sum -= a[i * n + j] * b[j];
598 b[i] = sum / a[i * n + i];
602 double filter::Filter::getCentreWavelength(
const std::vector<double> &wavelengthIn,
const Vector2d<double>& srf,
const std::string& interpolationType,
double delta,
bool verbose)
604 assert(srf.size()==2);
605 int nband=srf[0].size();
606 double start=floor(wavelengthIn[0]);
607 double end=ceil(wavelengthIn.back());
609 std::cout <<
"wavelengths in [" << start <<
"," << end <<
"]" << std::endl << std::flush;
613 gsl_interp_accel *acc;
616 stat.getSpline(interpolationType,nband,spline);
617 stat.initSpline(spline,&(srf[0][0]),&(srf[1][0]),nband);
619 std::cout <<
"calculating norm of srf" << std::endl << std::flush;
621 norm=gsl_spline_eval_integ(spline,srf[0].front(),srf[0].back(),acc);
623 std::cout <<
"norm of srf: " << norm << std::endl << std::flush;
624 gsl_spline_free(spline);
625 gsl_interp_accel_free(acc);
626 std::vector<double> wavelength_fine;
627 for(
double win=floor(wavelengthIn[0]);win<=ceil(wavelengthIn.back());win+=delta)
628 wavelength_fine.push_back(win);
631 std::cout <<
"interpolate wavelengths to " << wavelength_fine.size() <<
" entries " << std::endl;
632 std::vector<double> srf_fine;
634 stat.interpolateUp(srf[0],srf[1],wavelength_fine,interpolationType,srf_fine,verbose);
635 assert(srf_fine.size()==wavelength_fine.size());
637 gsl_interp_accel *accOut;
638 stat.allocAcc(accOut);
639 gsl_spline *splineOut;
640 stat.getSpline(interpolationType,wavelength_fine.size(),splineOut);
643 std::vector<double> wavelengthOut(wavelength_fine.size());
645 for(
int iband=0;iband<wavelengthOut.size();++iband)
646 wavelengthOut[iband]=wavelength_fine[iband]*srf_fine[iband];
648 stat.initSpline(splineOut,&(wavelength_fine[0]),&(wavelengthOut[0]),wavelength_fine.size());
649 double centreWavelength=gsl_spline_eval_integ(splineOut,start,end,accOut)/norm;
651 gsl_spline_free(splineOut);
652 gsl_interp_accel_free(accOut);
654 return(centreWavelength);