pktools  2.6.5
Processing Kernel for geospatial data
Filter_old.h
1 /**********************************************************************
2 Filter.h: class for filtering
3 Copyright (C) 2008-2012 Pieter Kempeneers
4 
5 This file is part of pktools
6 
7 pktools is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11 
12 pktools is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with pktools. If not, see <http://www.gnu.org/licenses/>.
19 ***********************************************************************/
20 #ifndef _MYFILTER_H_
21 #define _MYFILTER_H_
22 
23 #include <vector>
24 #include <iostream>
25 extern "C" {
26 #include <gsl/gsl_sort.h>
27 #include <gsl/gsl_wavelet.h>
28 }
29 #include "StatFactory.h"
30 #include "imageclasses/ImgReaderGdal.h"
31 #include "imageclasses/ImgWriterGdal.h"
32 
33 namespace filter
34 {
35 
36  enum FILTER_TYPE { median=0, var=1 , min=2, max=3, sum=4, mean=5, minmax=6, dilate=7, erode=8, close=9, open=10, homog=11, sobelx=12, sobely=13, sobelxy=14, sobelyx=-14, smooth=15, density=16, majority=17, mixed=18, smoothnodata=19, threshold=20, ismin=21, ismax=22, heterog=23, order=24, stdev=25, dwt=26, dwti=27, dwt_cut=28, dwt_cut_from=29};
37 
38  enum PADDING { symmetric=0, replicate=1, circular=2, constant=3};
39 
40 class Filter
41 {
42 public:
43  Filter(void);
44  Filter(const std::vector<double> &taps);
45  virtual ~Filter(){};
46  static PADDING getPadding(const std::string& padString){
47  std::map<std::string, PADDING> padMap;
48  padMap["constant"]=filter::constant;
49  padMap["symmetric"]=filter::symmetric;
50  padMap["replicate"]=filter::replicate;
51  padMap["circular"]=filter::circular;
52  return(padMap[padString]);
53  };
54 
55  static const gsl_wavelet_type* getWaveletType(const std::string waveletType){
56  if(waveletType=="daubechies") return(gsl_wavelet_daubechies);
57  if(waveletType=="daubechies_centered") return(gsl_wavelet_daubechies_centered);
58  if(waveletType=="haar") return(gsl_wavelet_haar);
59  if(waveletType=="haar_centered") return(gsl_wavelet_haar_centered);
60  if(waveletType=="bspline") return(gsl_wavelet_bspline);
61  if(waveletType=="bspline_centered") return(gsl_wavelet_bspline_centered);
62  }
63  static FILTER_TYPE getFilterType(const std::string filterType){
64  std::map<std::string, FILTER_TYPE> m_filterMap;
65  initFilterMap(m_filterMap);
66  return m_filterMap[filterType];
67  };
68  void setTaps(const std::vector<double> &taps, bool normalize=true);
69  void pushClass(short theClass=1){m_class.push_back(theClass);};
70  void pushMask(short theMask=0){m_mask.push_back(theMask);};
71  template<class T> void filter(const std::vector<T>& input, std::vector<T>& output);
72  template<class T> void filter(const std::vector<T>& input, std::vector<T>& output, const std::string& method, int dim);
73  template<class T> void smooth(const std::vector<T>& input, std::vector<T>& output, short dim);
74  template<class T> void filter(T* input, int inputSize, std::vector<T>& output);
75  template<class T> void smooth(T* input, int inputSize, std::vector<T>& output, short dim);
76  template<class T> void morphology(const std::vector<T>& input, std::vector<T>& output, const std::string& method, int dim, bool verbose=false);
77  void morphology(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& method, int dim, short verbose=0);
78  void filter(const ImgReaderGdal& input, ImgWriterGdal& output);
79  void stat(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& method);
80  void filter(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& method, int dim);
81  void smooth(const ImgReaderGdal& input, ImgWriterGdal& output, short dim);
82  double getCentreWavelength(const std::vector<double> &wavelengthIn, const Vector2d<double>& srf, const std::string& interpolationType, double delta=1.0, bool verbose=false);
83  template<class T> double applySrf(const std::vector<double> &wavelengthIn, const std::vector<T>& input, const Vector2d<double>& srf, const std::string& interpolationType, T& output, double delta=1.0, bool normalize=false, bool verbose=false);
84  template<class T> double applySrf(const std::vector<double> &wavelengthIn, const Vector2d<T>& input, const Vector2d<double>& srf, const std::string& interpolationType, std::vector<T>& output, double delta=1.0, bool normalize=false, int down=1, bool transposeInput=false, bool verbose=false);
85 
86  template<class T> void applyFwhm(const std::vector<double> &wavelengthIn, const std::vector<T>& input, const std::vector<double> &wavelengthOut, const std::vector<double> &fwhm, const std::string& interpolationType, std::vector<T>& output, bool verbose=false);
87  template<class T> void applyFwhm(const std::vector<double> &wavelengthIn, const Vector2d<T>& input, const std::vector<double> &wavelengthOut, const std::vector<double> &fwhm, const std::string& interpolationType, Vector2d<T>& output, int down=1, bool verbose=false);
88  void dwtForward(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& wavelet_type, int family);
89  void dwtInverse(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& wavelet_type, int family);
90  void dwtCut(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& wavelet_type, int family, double cut);
91  void dwtForward(std::vector<double>& data, const std::string& wavelet_type, int family);
92  void dwtInverse(std::vector<double>& data, const std::string& wavelet_type, int family);
93  void dwtCut(std::vector<double>& data, const std::string& wavelet_type, int family, double cut);
94  void dwtCutFrom(const ImgReaderGdal& input, ImgWriterGdal& output, const std::string& wavelet_type, int family, int band);
95 
96 private:
97 
98  static void initFilterMap(std::map<std::string, FILTER_TYPE>& m_filterMap){
99  //initialize Map
100  m_filterMap["dwt"]=filter::dwt;
101  m_filterMap["dwti"]=filter::dwti;
102  m_filterMap["dwt_cut"]=filter::dwt_cut;
103  m_filterMap["dwt_cut_from"]=filter::dwt_cut_from;
104  m_filterMap["stdev"]=filter::stdev;
105  m_filterMap["var"]=filter::var;
106  m_filterMap["min"]=filter::min;
107  m_filterMap["max"]=filter::max;
108  m_filterMap["sum"]=filter::sum;
109  m_filterMap["mean"]=filter::mean;
110  m_filterMap["minmax"]=filter::minmax;
111  m_filterMap["dilate"]=filter::dilate;
112  m_filterMap["erode"]=filter::erode;
113  m_filterMap["close"]=filter::close;
114  m_filterMap["open"]=filter::open;
115  m_filterMap["homog"]=filter::homog;
116  m_filterMap["sobelx"]=filter::sobelx;
117  m_filterMap["sobely"]=filter::sobely;
118  m_filterMap["sobelxy"]=filter::sobelxy;
119  m_filterMap["sobelyx"]=filter::sobelyx;
120  m_filterMap["smooth"]=filter::smooth;
121  m_filterMap["density"]=filter::density;
122  m_filterMap["majority"]=filter::majority;
123  m_filterMap["mixed"]=filter::mixed;
124  m_filterMap["smoothnodata"]=filter::smoothnodata;
125  m_filterMap["threshold"]=filter::threshold;
126  m_filterMap["ismin"]=filter::ismin;
127  m_filterMap["ismax"]=filter::ismax;
128  m_filterMap["heterog"]=filter::heterog;
129  m_filterMap["order"]=filter::order;
130  m_filterMap["median"]=filter::median;
131  }
132 
133  std::vector<double> m_taps;
134  std::vector<short> m_class;
135  std::vector<short> m_mask;
136  std::string m_padding;
137 };
138 
139 //input[band], output
140 //returns wavelength for which srf is maximum
141  template<class T> double Filter::applySrf(const std::vector<double> &wavelengthIn, const std::vector<T>& input, const Vector2d<double>& srf, const std::string& interpolationType, T& output, double delta, bool normalize, bool verbose)
142 {
143  assert(srf.size()==2);//[0]: wavelength, [1]: response function
144  int nband=srf[0].size();
145  double start=floor(wavelengthIn[0]);
146  double end=ceil(wavelengthIn.back());
147  if(verbose)
148  std::cout << "wavelengths in [" << start << "," << end << "]" << std::endl << std::flush;
149 
151 
152  gsl_interp_accel *acc;
153  stat.allocAcc(acc);
154  gsl_spline *spline;
155  stat.getSpline(interpolationType,nband,spline);
156  stat.initSpline(spline,&(srf[0][0]),&(srf[1][0]),nband);
157  if(verbose)
158  std::cout << "calculating norm of srf" << std::endl << std::flush;
159  double norm=0;
160  norm=gsl_spline_eval_integ(spline,srf[0].front(),srf[0].back(),acc);
161  if(verbose)
162  std::cout << "norm of srf: " << norm << std::endl << std::flush;
163  gsl_spline_free(spline);
164  gsl_interp_accel_free(acc);
165  //interpolate input and srf to delta
166 
167  std::vector<double> wavelength_fine;
168  for(double win=floor(wavelengthIn[0]);win<=ceil(wavelengthIn.back());win+=delta)
169  wavelength_fine.push_back(win);
170 
171  if(verbose)
172  std::cout << "interpolate wavelengths to " << wavelength_fine.size() << " entries " << std::endl;
173  std::vector<double> srf_fine;//spectral response function, interpolated for wavelength_fine
174 
175  stat.interpolateUp(srf[0],srf[1],wavelength_fine,interpolationType,srf_fine,verbose);
176  assert(srf_fine.size()==wavelength_fine.size());
177 
178  gsl_interp_accel *accOut;
179  stat.allocAcc(accOut);
180  gsl_spline *splineOut;
181  stat.getSpline(interpolationType,wavelength_fine.size(),splineOut);
182  assert(splineOut);
183 
184  assert(wavelengthIn.size()==input.size());
185  std::vector<double> input_fine;
186  std::vector<double> product(wavelength_fine.size());
187  std::vector<double> wavelengthOut(wavelength_fine.size());
188  stat.interpolateUp(wavelengthIn,input,wavelength_fine,interpolationType,input_fine,verbose);
189 
190  if(verbose)
191  std::cout << "input_fine.size(): " << input_fine.size() << std::endl;
192  for(int iband=0;iband<input_fine.size();++iband){
193  product[iband]=input_fine[iband]*srf_fine[iband];
194  wavelengthOut[iband]=wavelength_fine[iband]*srf_fine[iband];
195  }
196 
197  assert(input_fine.size()==srf_fine.size());
198  assert(input_fine.size()==wavelength_fine.size());
199  stat.initSpline(splineOut,&(wavelength_fine[0]),&(product[0]),wavelength_fine.size());
200  if(normalize)
201  output=gsl_spline_eval_integ(splineOut,start,end,accOut)/norm;
202  else
203  output=gsl_spline_eval_integ(splineOut,start,end,accOut);
204 
205  stat.initSpline(splineOut,&(wavelength_fine[0]),&(wavelengthOut[0]),wavelength_fine.size());
206  double centreWavelength=gsl_spline_eval_integ(splineOut,start,end,accOut)/norm;
207 
208  gsl_spline_free(splineOut);
209  gsl_interp_accel_free(accOut);
210 
211  // double maxResponse=0;
212  // int maxIndex=0;
213  // for(int index=0;index<srf[1].size();++index){
214  // if(maxResponse<srf[1][index]){
215  // maxResponse=srf[1][index];
216  // maxIndex=index;
217  // }
218  // }
219  // return(srf[0][maxIndex]);
220  return(centreWavelength);
221 }
222 
223 //input[band][sample], output[sample] (if !transposeInput)
224 //returns wavelength for which srf is maximum
225  template<class T> double Filter::applySrf(const std::vector<double> &wavelengthIn, const Vector2d<T>& input, const Vector2d<double>& srf, const std::string& interpolationType, std::vector<T>& output, double delta, bool normalize, int down, bool transposeInput, bool verbose)
226 {
227  assert(srf.size()==2);//[0]: wavelength, [1]: response function
228  int nband=srf[0].size();
229  unsigned int nsample=(transposeInput)? input.size():input[0].size();
230  output.resize((nsample+down-1)/down);
231  double start=floor(wavelengthIn[0]);
232  double end=ceil(wavelengthIn.back());
233  if(verbose)
234  std::cout << "wavelengths in [" << start << "," << end << "]" << std::endl << std::flush;
235 
237 
238  gsl_interp_accel *acc;
239  stat.allocAcc(acc);
240  gsl_spline *spline;
241  stat.getSpline(interpolationType,nband,spline);
242  stat.initSpline(spline,&(srf[0][0]),&(srf[1][0]),nband);
243  if(verbose)
244  std::cout << "calculating norm of srf" << std::endl << std::flush;
245  double norm=0;
246  norm=gsl_spline_eval_integ(spline,srf[0].front(),srf[0].back(),acc);
247  if(verbose)
248  std::cout << "norm of srf: " << norm << std::endl << std::flush;
249  gsl_spline_free(spline);
250  gsl_interp_accel_free(acc);
251  //interpolate input and srf to delta
252 
253  std::vector<double> wavelength_fine;
254  for(double win=floor(wavelengthIn[0]);win<=ceil(wavelengthIn.back());win+=delta)
255  wavelength_fine.push_back(win);
256 
257  if(verbose)
258  std::cout << "interpolate wavelengths to " << wavelength_fine.size() << " entries " << std::endl;
259  std::vector<double> srf_fine;//spectral response function, interpolated for wavelength_fine
260 
261  stat.interpolateUp(srf[0],srf[1],wavelength_fine,interpolationType,srf_fine,verbose);
262  assert(srf_fine.size()==wavelength_fine.size());
263 
264  gsl_interp_accel *accOut;
265  stat.allocAcc(accOut);
266  gsl_spline *splineOut;
267  stat.getSpline(interpolationType,wavelength_fine.size(),splineOut);
268  assert(splineOut);
269 
270  std::vector<double> wavelengthOut;
271  double centreWavelength=0;
272  for(int isample=0;isample<nsample;++isample){
273  if((isample+1+down/2)%down)
274  continue;
275  std::vector<T> inputValues;
276  if(transposeInput)
277  inputValues=input[isample];
278  else
279  input.selectCol(isample,inputValues);
280  assert(wavelengthIn.size()==inputValues.size());
281  std::vector<double> input_fine;
282  std::vector<double> product(wavelength_fine.size());
283  stat.interpolateUp(wavelengthIn,inputValues,wavelength_fine,interpolationType,input_fine,verbose);
284 
285  for(int iband=0;iband<input_fine.size();++iband){
286  product[iband]=input_fine[iband]*srf_fine[iband];
287  if(wavelengthOut.size()<input_fine.size())
288  wavelengthOut.push_back(wavelength_fine[iband]*srf_fine[iband]);
289  }
290 
291  assert(input_fine.size()==srf_fine.size());
292  assert(input_fine.size()==wavelength_fine.size());
293  stat.initSpline(splineOut,&(wavelength_fine[0]),&(product[0]),wavelength_fine.size());
294  if(normalize)
295  output[isample/down]=gsl_spline_eval_integ(splineOut,start,end,accOut)/norm;
296  else
297  output[isample/down]=gsl_spline_eval_integ(splineOut,start,end,accOut);
298 
299  stat.initSpline(splineOut,&(wavelength_fine[0]),&(wavelengthOut[0]),wavelength_fine.size());
300  if(centreWavelength>0);
301  else
302  centreWavelength=gsl_spline_eval_integ(splineOut,start,end,accOut)/norm;
303  }
304  gsl_spline_free(splineOut);
305  gsl_interp_accel_free(accOut);
306 
307  // double maxResponse=0;
308  // int maxIndex=0;
309  // for(int index=0;index<srf[1].size();++index){
310  // if(maxResponse<srf[1][index]){
311  // maxResponse=srf[1][index];
312  // maxIndex=index;
313  // }
314  // }
315  // return(srf[0][maxIndex]);
316  return(centreWavelength);
317 }
318 
319 template<class T> void Filter::applyFwhm(const std::vector<double> &wavelengthIn, const std::vector<T>& input, const std::vector<double> &wavelengthOut, const std::vector<double> &fwhm, const std::string& interpolationType, std::vector<T>& output, bool verbose){
320  double delta=1;//1 nm resolution
321  std::vector<double> stddev(fwhm.size());
322  for(int index=0;index<fwhm.size();++index)
323  stddev[index]=fwhm[index]/2.0/sqrt(2*log(2.0));//http://mathworld.wolfram.com/FullWidthatHalfMaximum.html
324  assert(wavelengthOut.size()==fwhm.size());
325  assert(wavelengthIn.size()==input.size());
326  assert(wavelengthIn[0]<=wavelengthOut[0]);
327  assert(wavelengthIn.back()>=wavelengthOut.back());
329  std::vector<double> input_fine;
330  std::vector<double> wavelength_fine;
331  for(double win=floor(wavelengthIn[0]);win<=ceil(wavelengthIn.back());win+=delta)
332  wavelength_fine.push_back(win);
333  if(verbose){
334  for(int index=0;index<wavelength_fine.size();++index)
335  std::cout << " " << wavelength_fine[index];
336  std::cout << std::endl;
337  std::cout << "interpolate input wavelength to " << delta << " nm resolution (size=" << wavelength_fine.size() << ")" << std::endl;
338  }
339  stat.interpolateUp(wavelengthIn,input,wavelength_fine,interpolationType,input_fine,verbose);
340  int nbandIn=wavelength_fine.size();
341 
342  int nbandOut=wavelengthOut.size();
343  output.resize(nbandOut);
344  Vector2d<double> tf(nbandIn,nbandOut);
345  for(int indexOut=0;indexOut<nbandOut;++indexOut){
346  double norm=0;
347  for(int indexIn=0;indexIn<nbandIn;++indexIn){
348  // tf(indexIn,indexOut)=
349  tf[indexIn][indexOut]=
350  exp((wavelengthOut[indexOut]-wavelength_fine[indexIn])
351  *(wavelength_fine[indexIn]-wavelengthOut[indexOut])
352  /2.0/stddev[indexOut]
353  /stddev[indexOut]);
354  tf[indexIn][indexOut]/=sqrt(2.0*M_PI);
355  tf[indexIn][indexOut]/=stddev[indexOut];
356  norm+=tf[indexIn][indexOut];
357  }
358  output[indexOut]=0;
359  for(int indexIn=0;indexIn<nbandIn;++indexIn)
360  output[indexOut]+=input_fine[indexIn]*tf[indexIn][indexOut]/norm;
361  }
362 }
363 
364 
365  //input[inBand][sample], output[outBand][sample]
366  template<class T> void Filter::applyFwhm(const std::vector<double> &wavelengthIn, const Vector2d<T>& input, const std::vector<double> &wavelengthOut, const std::vector<double> &fwhm, const std::string& interpolationType, Vector2d<T>& output, int down, bool verbose){
367  double delta=1;//1 nm resolution
368  std::vector<double> stddev(fwhm.size());
369  for(int index=0;index<fwhm.size();++index)
370  stddev[index]=fwhm[index]/2.0/sqrt(2*log(2.0));//http://mathworld.wolfram.com/FullWidthatHalfMaximum.html
372  std::vector<double> wavelength_fine;
373  for(double win=floor(wavelengthIn[0]);win<=ceil(wavelengthIn.back());win+=delta)
374  wavelength_fine.push_back(win);
375  assert(wavelengthOut.size()==fwhm.size());
376  assert(wavelengthIn[0]<=wavelengthOut[0]);
377  assert(wavelengthIn.back()>=wavelengthOut.back());
378  if(verbose){
379  for(int index=0;index<wavelength_fine.size();++index)
380  std::cout << " " << wavelength_fine[index];
381  std::cout << std::endl;
382  std::cout << "interpolate input wavelength to " << delta << " nm resolution (size=" << wavelength_fine.size() << ")" << std::endl;
383  }
384  int nbandIn=wavelength_fine.size();
385  int nbandOut=wavelengthOut.size();
386  output.resize(nbandOut,(input[0].size()+down-1)/down);
387 
388  Vector2d<double> tf(nbandIn,nbandOut);
389  std::vector<double> norm(nbandOut);
390  for(int indexOut=0;indexOut<nbandOut;++indexOut){
391  norm[indexOut]=0;
392  for(int indexIn=0;indexIn<nbandIn;++indexIn){
393  tf[indexIn][indexOut]=
394  exp((wavelengthOut[indexOut]-wavelength_fine[indexIn])
395  *(wavelength_fine[indexIn]-wavelengthOut[indexOut])
396  /2.0/stddev[indexOut]
397  /stddev[indexOut]);
398  tf[indexIn][indexOut]/=sqrt(2.0*M_PI);
399  tf[indexIn][indexOut]/=stddev[indexOut];
400  norm[indexOut]+=tf[indexIn][indexOut];
401  }
402  }
403 
404  for(int isample=0;isample<input[0].size();++isample){
405  if((isample+1+down/2)%down)
406  continue;
407  std::vector<T> inputValues;
408  input.selectCol(isample,inputValues);
409  assert(wavelengthIn.size()==inputValues.size());
410  for(int indexOut=0;indexOut<nbandOut;++indexOut){
411  std::vector<double> input_fine;
412  stat.interpolateUp(wavelengthIn,inputValues,wavelength_fine,interpolationType,input_fine,verbose);
413  output[indexOut][(isample+down-1)/down]=0;
414  for(int indexIn=0;indexIn<nbandIn;++indexIn){
415  output[indexOut][(isample+down-1)/down]+=input_fine[indexIn]*tf[indexIn][indexOut]/norm[indexOut];
416  }
417  }
418  }
419 }
420 
421  template<class T> void Filter::smooth(const std::vector<T>& input, std::vector<T>& output, short dim)
422 {
423  assert(dim>0);
424  m_taps.resize(dim);
425  for(int itap=0;itap<dim;++itap)
426  m_taps[itap]=1.0/dim;
427  filter(input,output);
428  }
429 
430 template<class T> void Filter::filter(const std::vector<T>& input, std::vector<T>& output)
431 {
432  assert(input.size()>m_taps.size());
433  output.resize(input.size());
434  int i=0;
435  //start: extend input with mirrored version of itself
436  for(i=0;i<m_taps.size()/2;++i){
437  //todo:introduce nodata
438  output[i]=m_taps[m_taps.size()/2]*input[i];
439  for(int t=1;t<=m_taps.size()/2;++t){
440  output[i]+=m_taps[m_taps.size()/2+t]*input[i+t];
441  if(i>=t)
442  output[i]+=m_taps[m_taps.size()/2-t]*input[i-t];
443  else{
444  switch(getPadding(m_padding)){
445  case(replicate):
446  output[i]+=m_taps[m_taps.size()/2-t]*input[0];
447  break;
448  case(circular):
449  output[i]+=m_taps[m_taps.size()/2-t]*input[input.size()+i-t];
450  break;
451  case(constant):
452  output[i]+=m_taps[m_taps.size()/2-t]*0;
453  break;
454  case(symmetric):
455  default:
456  output[i]+=m_taps[m_taps.size()/2-t]*input[t-i];
457  break;
458  }
459  }
460  //output[i]+=(m_taps[m_taps.size()/2+t]+m_taps[m_taps.size()/2-t])*input[i+t];
461  }
462  }
463  //main
464  for(i=m_taps.size()/2;i<input.size()-m_taps.size()/2;++i){
465  //todo:introduce nodata
466  T leaveOut=(*(m_taps.begin()))*input[i-m_taps.size()/2];
467  T include=(m_taps.back())*input[i+m_taps.size()/2];
468  output[i]=0;
469  for(int t=0;t<m_taps.size();++t)
470  output[i]+=input[i-m_taps.size()/2+t]*m_taps[t];
471  }
472  //end: extend input with mirrored version of itself
473  for(i=input.size()-m_taps.size()/2;i<input.size();++i){
474  //todo:introduce nodata
475  output[i]=m_taps[m_taps.size()/2]*input[i];
476  //todo:introduce nodata
477  for(int t=1;t<=m_taps.size()/2;++t){
478  output[i]+=m_taps[m_taps.size()/2-t]*input[i-t];
479  if(i+t<input.size())
480  output[i]+=m_taps[m_taps.size()/2+t]*input[i+t];
481  else{
482  switch(getPadding(m_padding)){
483  case(replicate):
484  output[i]+=m_taps[m_taps.size()/2+t]*input.back();
485  break;
486  case(circular):
487  output[i]+=m_taps[m_taps.size()/2+t]*input[t-1];
488  break;
489  case(constant):
490  output[i]+=m_taps[m_taps.size()/2+t]*0;
491  break;
492  case(symmetric):
493  default:
494  output[i]+=m_taps[m_taps.size()/2+t]*input[i-t];
495  break;
496  }
497  }
498  //output[i]+=(m_taps[m_taps.size()/2+t]+m_taps[m_taps.size()/2-t])*input[i-t];
499  }
500  }
501 }
502 
503  template<class T> void Filter::filter(const std::vector<T>& input, std::vector<T>& output, const std::string& method, int dim)
504 {
505  bool verbose=false;
506  assert(dim);
507  output.resize(input.size());
508  int i=0;
510  std::vector<T> statBuffer;
511  short binValue=0;
512  //start: extend input with mirrored version of itself
513  for(i=0;i<dim/2;++i){
514  binValue=0;
515  for(int iclass=0;iclass<m_class.size();++iclass){
516  if(input[i]==m_class[iclass]){
517  binValue=m_class[0];
518  break;
519  }
520  }
521  if(m_class.size())
522  statBuffer.push_back(binValue);
523  else
524  statBuffer.push_back(input[i]);
525 
526  for(int t=1;t<=dim/2;++t){
527  T theValue=input[i+t];
528  for(int iclass=0;iclass<m_class.size();++iclass){
529  if(theValue==m_class[iclass]){
530  binValue=m_class[0];
531  break;
532  }
533  }
534  if(m_class.size())
535  statBuffer.push_back(binValue);
536  else
537  statBuffer.push_back(theValue);
538 
539  if(i>=t){
540  theValue=input[i-t];
541  }
542  else{
543  switch(getPadding(m_padding)){
544  case(replicate):
545  theValue=input[0];
546  break;
547  case(circular):
548  theValue=input[input.size()+i-t];
549  break;
550  case(constant):
551  theValue=0;
552  break;
553  case(symmetric):
554  default:
555  theValue=input[t-i];
556  break;
557  }
558  }
559  for(int iclass=0;iclass<m_class.size();++iclass){
560  if(theValue==m_class[iclass]){
561  binValue=m_class[0];
562  break;
563  }
564  }
565  if(m_class.size())
566  statBuffer.push_back(binValue);
567  else
568  statBuffer.push_back(theValue);
569  }
570 
571  switch(getFilterType(method)){
572  case(filter::median):
573  output[i]=stat.median(statBuffer);
574  break;
575  case(filter::min):
576  output[i]=stat.mymin(statBuffer);
577  break;
578  case(filter::max):
579  output[i]=stat.mymax(statBuffer);
580  break;
581  case(filter::sum):
582  output[i]=sqrt(stat.sum(statBuffer));
583  break;
584  case(filter::var):
585  output[i]=stat.var(statBuffer);
586  break;
587  case(filter::mean):
588  output[i]=stat.mean(statBuffer);
589  break;
590  default:
591  std::string errorString="method not supported";
592  throw(errorString);
593  break;
594  }
595  }
596  //main
597  statBuffer.clear();
598  for(i=dim/2;i<input.size()-dim/2;++i){
599  binValue=0;
600  for(int t=0;t<dim;++t){
601  for(int iclass=0;iclass<m_class.size();++iclass){
602  if(input[i-dim/2+t]==m_class[iclass]){
603  binValue=m_class[0];
604  break;
605  }
606  }
607  if(m_class.size())
608  statBuffer.push_back(binValue);
609  else
610  statBuffer.push_back(input[i-dim/2+t]);
611  }
612  switch(getFilterType(method)){
613  case(filter::median):
614  output[i]=stat.median(statBuffer);
615  break;
616  case(filter::min):
617  output[i]=stat.mymin(statBuffer);
618  break;
619  case(filter::max):
620  output[i]=stat.mymax(statBuffer);
621  break;
622  case(filter::sum):
623  output[i]=sqrt(stat.sum(statBuffer));
624  break;
625  case(filter::var):
626  output[i]=stat.var(statBuffer);
627  break;
628  case(filter::mean):
629  output[i]=stat.mean(statBuffer);
630  break;
631  default:
632  std::string errorString="method not supported";
633  throw(errorString);
634  break;
635  }
636  statBuffer.clear();
637  }
638  //end: extend input with mirrored version of itself
639  for(i=input.size()-dim/2;i<input.size();++i){
640  binValue=0;
641  for(int iclass=0;iclass<m_class.size();++iclass){
642  if(input[i]==m_class[iclass]){
643  binValue=m_class[0];
644  break;
645  }
646  }
647  if(m_class.size())
648  statBuffer.push_back(binValue);
649  else
650  statBuffer.push_back(input[i]);
651 
652  for(int t=1;t<=dim/2;++t){
653  T theValue=input[i-t];
654  for(int iclass=0;iclass<m_class.size();++iclass){
655  if(theValue==m_class[iclass]){
656  binValue=m_class[0];
657  break;
658  }
659  }
660  if(m_class.size())
661  statBuffer.push_back(binValue);
662  else
663  statBuffer.push_back(theValue);
664  if(i+t<input.size())
665  theValue=input[i+t];
666  else{
667  switch(getPadding(m_padding)){
668  replicate:
669  theValue=input.back();
670  break;
671  circular:
672  theValue=input[t-1];
673  break;
674  constant:
675  theValue=0;
676  break;
677  symmetric:
678  default:
679  theValue=input[i-t];
680  break;
681  }
682  }
683  for(int iclass=0;iclass<m_class.size();++iclass){
684  if(theValue==m_class[iclass]){
685  binValue=m_class[0];
686  break;
687  }
688  }
689  if(m_class.size())
690  statBuffer.push_back(binValue);
691  else
692  statBuffer.push_back(theValue);
693  }
694  switch(getFilterType(method)){
695  case(filter::median):
696  output[i]=stat.median(statBuffer);
697  break;
698  case(filter::min):
699  output[i]=stat.mymin(statBuffer);
700  break;
701  case(filter::max):
702  output[i]=stat.mymax(statBuffer);
703  break;
704  case(filter::sum):
705  output[i]=sqrt(stat.sum(statBuffer));
706  break;
707  case(filter::var):
708  output[i]=stat.var(statBuffer);
709  break;
710  case(filter::mean):
711  output[i]=stat.mean(statBuffer);
712  break;
713  default:
714  std::string errorString="method not supported";
715  throw(errorString);
716  break;
717  }
718  }
719  }
720 
721 
722  //todo: this function is redundant, can be incorporated within filter
723  template<class T> void Filter::morphology(const std::vector<T>& input, std::vector<T>& output, const std::string& method, int dim, bool verbose)
724 {
725  assert(dim);
726  output.resize((input.size());
727  int i=0;
729  std::vector<T> statBuffer;
730  short binValue=0;
731  //start: extend input with mirrored version of itself
732  for(i=0;i<dim/2;++i){
733  binValue=0;
734  for(int iclass=0;iclass<m_class.size();++iclass){
735  if(input[i]==m_class[iclass]){
736  binValue=m_class[0];
737  break;
738  }
739  }
740  if(m_class.size())
741  statBuffer.push_back(binValue);
742  else
743  statBuffer.push_back(input[i]);
744  for(int t=1;t<=dim/2;++t){
745  binValue=0;
746  for(int iclass=0;iclass<m_class.size();++iclass){
747  if(input[i+t]==m_class[iclass]){
748  binValue=m_class[0];
749  break;
750  }
751  }
752  if(m_class.size()){
753  statBuffer.push_back(binValue);
754  statBuffer.push_back(binValue);
755  }
756  else{
757  statBuffer.push_back(input[i+t]);
758  statBuffer.push_back(input[i+t]);
759  }
760  }
761  /* assert(statBuffer.size()==dim); */
762  switch(getFilterType(method)){
763  case(filter::dilate):
764  output[i]=stat.mymax(statBuffer);
765  break;
766  case(filter::erode):
767  output[i]=stat.mymin(statBuffer);
768  break;
769  default:
770  std::string errorString="method not supported";
771  throw(errorString);
772  break;
773  }
774  if(verbose){
775  std::cout << "buffer: ";
776  for(int ibuf=0;ibuf<statBuffer.size();++ibuf)
777  std::cout << statBuffer[ibuf] << " ";
778  std::cout << "->" << output[i] << std::endl;
779  }
780  }
781  //main
782  statBuffer.clear();
783  for(i=dim/2;i<input.size()-dim/2;++i){
784  binValue=0;
785  for(int t=0;t<dim;++t){
786  for(int iclass=0;iclass<m_class.size();++iclass){
787  if(input[i-dim/2+t]==m_class[iclass]){
788  binValue=m_class[0];
789  break;
790  }
791  }
792  if(m_class.size())
793  statBuffer.push_back(binValue);
794  else
795  statBuffer.push_back(input[i-dim/2+t]);
796  }
797  /* assert(statBuffer.size()==dim); */
798  switch(getFilterType(method)){
799  case(filter::dilate):
800  output[i]=stat.mymax(statBuffer);
801  break;
802  case(filter::erode):
803  output[i]=stat.mymin(statBuffer);
804  break;
805  default:
806  std::string errorString="method not supported";
807  throw(errorString);
808  break;
809  }
810  if(verbose){
811  std::cout << "buffer: ";
812  for(int ibuf=0;ibuf<statBuffer.size();++ibuf)
813  std::cout << statBuffer[ibuf] << " ";
814  std::cout << "->" << output[i] << std::endl;
815  }
816  statBuffer.clear();
817  }
818  //end: extend input with mirrored version of itself
819  for(i=input.size()-dim/2;i<input.size();++i){
820  binValue=0;
821  for(int iclass=0;iclass<m_class.size();++iclass){
822  if(input[i]==m_class[iclass]){
823  binValue=m_class[0];
824  break;
825  }
826  }
827  if(m_class.size())
828  statBuffer.push_back(binValue);
829  else
830  statBuffer.push_back(input[i]);
831  for(int t=1;t<=dim/2;++t){
832  binValue=0;
833  for(int iclass=0;iclass<m_class.size();++iclass){
834  if(input[i-t]==m_class[iclass]){
835  binValue=m_class[0];
836  break;
837  }
838  }
839  if(m_class.size()){
840  statBuffer.push_back(binValue);
841  statBuffer.push_back(binValue);
842  }
843  else{
844  statBuffer.push_back(input[i-t]);
845  statBuffer.push_back(input[i-t]);
846  }
847  }
848  }
849  switch(getFilterType(method)){
850  case(filter::dilate):
851  output[i]=stat.mymax(statBuffer);
852  break;
853  case(filter::erode):
854  output[i]=stat.mymin(statBuffer);
855  break;
856  default:
857  std::string errorString="method not supported";
858  throw(errorString);
859  break;
860  }
861  if(verbose){
862  std::cout << "buffer: ";
863  for(int ibuf=0;ibuf<statBuffer.size();++ibuf)
864  std::cout << statBuffer[ibuf] << " ";
865  std::cout << "->" << output[i] << std::endl;
866  }
867  }
868 }
869 
870  template<class T> void Filter::smooth(T* input, int inputSize, std::vector<T>& output, short dim)
871 {
872  assert(dim>0);
873  m_taps.resize(dim);
874  for(int itap=0;itap<dim;++itap)
875  m_taps[itap]=1.0/dim;
876  filter(input,output);
877  }
878 
879 template<class T> void Filter::filter(T* input, int inputSize, std::vector<T>& output)
880 {
881  output.resize((inputSize);
882  int i=0;
883  //start: extend input with mirrored version of itself
884  for(i=0;i<m_taps.size()/2;++i){
885  output[i]=m_taps[m_taps.size()/2]*input[i];
886  for(int t=1;t<=m_taps.size()/2;++t)
887  output[i]+=(m_taps[m_taps.size()/2+t]+m_taps[m_taps.size()/2-t])*input[i+t];
888  }
889  //main
890  for(i=m_taps.size()/2;i<inputSize-m_taps.size()/2;++i){
891  T leaveOut=(*(m_taps.begin()))*input[i-m_taps.size()/2];
892  T include=(m_taps.back())*input[i+m_taps.size()/2];
893  output[i]=0;
894  for(int t=0;t<m_taps.size();++t)
895  output[i]+=input[i-m_taps.size()/2+t]*m_taps[t];
896  }
897  //end: extend input with mirrored version of itself
898  for(i=inputSize-m_taps.size()/2;i<inputSize;++i){
899  output[i]=m_taps[m_taps.size()/2]*input[i];
900  for(int t=1;t<=m_taps.size()/2;++t)
901  output[i]+=(m_taps[m_taps.size()/2+t]+m_taps[m_taps.size()/2-t])*input[i-t];
902  }
903 }
904 }
905 
906 #endif /* _MYFILTER_H_ */