1 #ifndef ossimFilter_HEADER
2 #define ossimFilter_HEADER
3 #include <math.h>
4 #include <ossim/matrix/newmat.h>
5 #include <ossim/base/ossimRtti.h>
6 #include <ossim/base/ossimCommon.h>
7 
8 class ossimFilter
9 {
10 public:
ossimFilter()11    ossimFilter()
12       {}
~ossimFilter()13    virtual ~ossimFilter() {}
14 
15    virtual double filter (double x, double support)const = 0;
16    /*!
17     * Will call the filter method to create a
18     * convolution matrix.  This matrix will not
19     * have normalized weights.
20     *
21     * Will generate a matrix by creating an outer
22     * product of the 1-D filter array.  This matrix
23     * will be square width-by-width.
24     *
25     * note:  the matrix is a new matrix and needs to
26     *        be destroyed by the caller
27     */
28    virtual NEWMAT::Matrix *newMatrix(long width=3,
29                                      double middle=0.0,
30                                      double scale=0.0)const;
31    virtual void createMatrix(NEWMAT::Matrix& m,
32                              long width=3,
33                              double middle=0.0,
34                              double scale=0.0)const;
35 
36    virtual NEWMAT::RowVector *newVector(long width,
37                                         double middle=0.0,
38                                         double scale = 1.0)const;
Sinc(double x)39    static double Sinc(double x)
40       {
41          if (x != 0.0)
42          {
43             x*=M_PI;
44             return(sin(x)/x);
45          }
46 
47          return(1.0);
48       }
Sinc(double x,double)49    static double Sinc(double x, double /* support */ )
50       {
51          if (x != 0.0)
52          {
53             x*=M_PI;
54             return(sin(x)/x);
55          }
56 
57          return(1.0);
58       }
59 
60    virtual double getSupport()const=0;
61 
62 TYPE_DATA
63 };
64 
65 class ossimBoxFilter : public ossimFilter
66 {
67 public:
ossimBoxFilter()68    ossimBoxFilter (){}
~ossimBoxFilter()69    virtual ~ossimBoxFilter() {}
70 
filter(double x,double)71    virtual double filter (double x, double /* support */ )const
72       {
73          if (x < -0.5)
74             return(0.0);
75          if (x < 0.5)
76             return(1.0);
77          return(0.0);
78       }
getSupport()79    virtual double getSupport()const
80       {
81          return .5;
82       }
83 TYPE_DATA
84 };
85 
86 class ossimSincFilter : public ossimFilter
87 {
88 public:
ossimSincFilter()89    ossimSincFilter(){}
~ossimSincFilter()90    virtual ~ossimSincFilter(){}
filter(double x,double)91    double filter(double x, double /* support */ )const
92       {
93          x*=M_PI;
94          if (x != 0.0)
95             return(sin(x)/x);
96          return(1.0);
97       }
getSupport()98    virtual double getSupport()const
99       {
100          return 1.0;
101       }
102 TYPE_DATA
103 };
104 
105 class ossimBellFilter : public ossimFilter
106 {
107 public:
ossimBellFilter()108    ossimBellFilter(){}
~ossimBellFilter()109    virtual ~ossimBellFilter(){}
getSupport()110    virtual double getSupport()const
111       {
112          return 1.5;
113       }
filter(double value,double)114    virtual double filter(double value, double /* support */ )const
115       {
116          if(value < 0) value = -value;
117          if(value < .5) return(.75 - (value * value));
118          if(value < 1.5) {
119             value = (value - 1.5);
120             return(.5 * (value * value));
121          }
122          return(0.0);
123       }
124 TYPE_DATA
125 };
126 
127 class ossimNearestNeighborFilter: public ossimBoxFilter
128 {
129 public:
ossimNearestNeighborFilter()130    ossimNearestNeighborFilter (){}
~ossimNearestNeighborFilter()131    virtual ~ossimNearestNeighborFilter() {}
132 
getSupport()133    virtual double getSupport()const
134       {
135          return 0.0;
136       }
137 TYPE_DATA
138 };
139 
140 
141 class ossimBesselOrderOneFilter : public ossimFilter
142 {
143 public:
ossimBesselOrderOneFilter()144    ossimBesselOrderOneFilter(){}
~ossimBesselOrderOneFilter()145    virtual ~ossimBesselOrderOneFilter(){}
146    virtual double filter(double value, double /* support */ )const;
getSupport()147    virtual double getSupport()const
148       {
149          return 1.0;
150       }
151 TYPE_DATA
152 };
153 class ossimBesselFilter : public ossimFilter
154 {
155 public:
ossimBesselFilter()156    ossimBesselFilter(){}
~ossimBesselFilter()157    virtual ~ossimBesselFilter(){}
filter(double x,double support)158    virtual double filter(double x, double support)const
159       {
160          if (x == 0.0)
161          {
162             return(M_PI/4.0);
163          }
164 
165          return(ossimBesselOrderOneFilter().filter((M_PI*x)/(2.0*x), support));
166       }
getSupport()167    virtual double getSupport()const
168       {
169          return 1.0;
170       }
171 
172 TYPE_DATA
173 };
174 
175 class ossimBlackmanFilter : public ossimFilter
176 {
177 public:
ossimBlackmanFilter()178     ossimBlackmanFilter (){}
~ossimBlackmanFilter()179     virtual ~ossimBlackmanFilter() {}
180 
filter(double x,double)181     virtual double filter (double x, double /* support */ ) const
182         {
183            return(0.42+0.50*cos(M_PI*x)+0.08*cos(2.0*M_PI*x));
184         }
getSupport()185    virtual double getSupport()const
186       {
187          return 1.0;
188       }
189 TYPE_DATA
190 };
191 
192 class ossimBlackmanSincFilter : public ossimBlackmanFilter
193 {
194 public:
ossimBlackmanSincFilter()195     ossimBlackmanSincFilter (){}
~ossimBlackmanSincFilter()196     virtual ~ossimBlackmanSincFilter() {}
197 
filter(double x,double support)198     virtual double filter (double x, double support) const
199         {
200            return ((ossimBlackmanFilter::filter(x/support,support))*
201                    (ossimSincFilter().filter(x, support)));
202         }
getSupport()203    virtual double getSupport()const
204       {
205          return 4.0;
206       }
207 TYPE_DATA
208 };
209 
210 class ossimBlackmanBesselFilter : public ossimBlackmanFilter
211 {
212 public:
ossimBlackmanBesselFilter()213     ossimBlackmanBesselFilter(){}
~ossimBlackmanBesselFilter()214     virtual ~ossimBlackmanBesselFilter() {}
215 
filter(double x,double support)216     virtual double filter (double x, double support) const
217         {
218            return ((ossimBlackmanFilter::filter(x/support,support))*
219                    (ossimBesselFilter().filter(x, support)));
220         }
getSupport()221    virtual double getSupport()const
222       {
223          return 3.2383;
224       }
225 TYPE_DATA
226 };
227 
228 
229 class ossimCatromFilter : public ossimFilter
230 {
231 public:
ossimCatromFilter()232    ossimCatromFilter(){}
~ossimCatromFilter()233    virtual ~ossimCatromFilter(){}
filter(double x,double)234    double filter(double x, double /* support */ )const
235       {
236          if (x < -2.0)
237             return(0.0);
238          if (x < -1.0)
239             return(0.5*(4.0+x*(8.0+x*(5.0+x))));
240          if (x < 0.0)
241             return(0.5*(2.0+x*x*(-5.0-3.0*x)));
242          if (x < 1.0)
243             return(0.5*(2.0+x*x*(-5.0+3.0*x)));
244          if (x < 2.0)
245             return(0.5*(4.0+x*(-8.0+x*(5.0-x))));
246          return(0.0);
247       }
getSupport()248    virtual double getSupport()const
249       {
250          return 2.0;
251       }
252 TYPE_DATA
253 };
254 
255 class ossimCubicFilter : public ossimFilter
256 {
257 public:
ossimCubicFilter()258    ossimCubicFilter(){}
~ossimCubicFilter()259    virtual ~ossimCubicFilter(){}
filter(double x,double)260    double filter(double x, double /* support */ )const
261       {
262          if (x < -2.0)
263             return(0.0);
264          if (x < -1.0)
265             return((2.0+x)*(2.0+x)*(2.0+x)/6.0);
266          if (x < 0.0)
267             return((4.0+x*x*(-6.0-3.0*x))/6.0);
268          if (x < 1.0)
269             return((4.0+x*x*(-6.0+3.0*x))/6.0);
270          if (x < 2.0)
271             return((2.0-x)*(2.0-x)*(2.0-x)/6.0);
272          return(0.0);
273       }
getSupport()274    virtual double getSupport()const
275       {
276          return 2.0;
277       }
278 TYPE_DATA
279 };
280 
281 class ossimBSplineFilter : public ossimFilter
282 {
283 public:
ossimBSplineFilter()284    ossimBSplineFilter(){}
~ossimBSplineFilter()285    virtual ~ossimBSplineFilter(){}
filter(double value,double)286    virtual double filter(double value, double /* support */ )const
287       {
288 	double tt;
289 
290 	if(value < 0) value = -value;
291 	if(value < 1) {
292 		tt = value * value;
293 		return((.5 * tt * value) - tt + (2.0 / 3.0));
294 	} else if(value < 2) {
295 		value = 2 - value;
296 		return((1.0 / 6.0) * (value * value * value));
297 	}
298 	return(0.0);
299       }
getSupport()300    virtual double getSupport()const
301       {
302          return 2.0;
303       }
304 TYPE_DATA
305 };
306 
307 class ossimGaussianFilter : public ossimFilter
308 {
309 public:
ossimGaussianFilter()310     ossimGaussianFilter (){}
~ossimGaussianFilter()311     virtual ~ossimGaussianFilter() {}
312 
filter(double x,double)313     virtual double filter (double x, double /* support */ ) const
314         {
315            return(exp(-2.0*x*x)*sqrt(2.0/M_PI));
316         }
getSupport()317    virtual double getSupport()const
318       {
319          return 1.25;
320       }
321 TYPE_DATA
322 };
323 
324 class ossimHanningFilter : public ossimFilter
325 {
326 public:
ossimHanningFilter()327    ossimHanningFilter(){}
~ossimHanningFilter()328    virtual ~ossimHanningFilter(){}
filter(double x,double)329    double filter(double x, double /* support */ )const
330       {
331          return(0.5+0.5*cos(M_PI*x));
332       }
getSupport()333    virtual double getSupport()const
334       {
335          return 1.0;
336       }
337 TYPE_DATA
338 };
339 
340 class ossimHammingFilter : public ossimFilter
341 {
342 public:
ossimHammingFilter()343     ossimHammingFilter (){}
~ossimHammingFilter()344     virtual ~ossimHammingFilter() {}
345 
filter(double x,double)346     virtual double filter (double x, double /* support */ ) const
347         {
348            return(0.54+0.46*cos(M_PI*x));
349         }
getSupport()350    virtual double getSupport()const
351       {
352          return 1.0;
353       }
354 TYPE_DATA
355 };
356 
357 class ossimHermiteFilter : public ossimFilter
358 {
359 public:
ossimHermiteFilter()360    ossimHermiteFilter(){}
~ossimHermiteFilter()361    virtual ~ossimHermiteFilter(){}
filter(double x,double)362    double filter(double x, double /* support */ )const
363       {
364          if (x < -1.0)
365             return(0.0);
366          if (x < 0.0)
367             return((2.0*(-x)-3.0)*(-x)*(-x)+1.0);
368          if (x < 1.0)
369             return((2.0*x-3.0)*x*x+1.0);
370          return(0.0);
371       }
getSupport()372    virtual double getSupport()const
373       {
374          return 1.0;
375       }
376 TYPE_DATA
377 };
378 
379 
380 class ossimLanczosFilter : public ossimFilter
381 {
382 public:
ossimLanczosFilter()383    ossimLanczosFilter(){}
~ossimLanczosFilter()384    virtual ~ossimLanczosFilter(){}
filter(double x,double)385    double filter(double x, double /* support */ )const
386       {
387          if (x < -3.0)
388             return(0.0);
389          if (x < 0.0)
390             return(Sinc(-x,getSupport())*Sinc(-x/3.0,getSupport()));
391          if (x < 3.0)
392             return(Sinc(x,getSupport())*Sinc(x/3.0,getSupport()));
393          return(0.0);
394       }
getSupport()395    virtual double getSupport()const
396       {
397          return 3.0;
398       }
399 TYPE_DATA
400 };
401 
402 class ossimMagicFilter : public ossimFilter
403 {
404 public:
ossimMagicFilter()405    ossimMagicFilter(){}
~ossimMagicFilter()406    virtual ~ossimMagicFilter(){}
filter(double x,double)407    double filter(double x, double /* support */ )const
408       {
409          if (x <= -1.5)
410             return(0.0);
411          if (x <= -0.5)
412           return (0.5*ossim::square(x + 1.5));
413          if (x <=0.5)
414             return (0.75-ossim::square(x));
415          if(x <= 0.75)
416             return (0.5*ossim::square(x-1.5));
417 
418          return(0.0);
419       }
getSupport()420    virtual double getSupport()const
421       {
422          return 1.5;
423       }
424 TYPE_DATA
425 };
426 
427 class ossimMitchellFilter : public ossimFilter
428 {
429 public:
ossimMitchellFilter()430    ossimMitchellFilter(){}
~ossimMitchellFilter()431    virtual ~ossimMitchellFilter(){}
filter(double x,double)432    double filter(double x, double /* support */ )const
433       {
434 #define MITCHELL_B   (1.0/3.0)
435 #define MITCHELL_C   (1.0/3.0)
436 #define MITCHELL_P0  ((  6.0- 2.0*MITCHELL_B       )/6.0)
437 #define MITCHELL_P2  ((-18.0+12.0*MITCHELL_B+ 6.0*MITCHELL_C)/6.0)
438 #define MITCHELL_P3  (( 12.0- 9.0*MITCHELL_B- 6.0*MITCHELL_C)/6.0)
439 #define MITCHELL_Q0  ((       8.0*MITCHELL_B+24.0*MITCHELL_C)/6.0)
440 #define MITCHELL_Q1  ((     -12.0*MITCHELL_B-48.0*MITCHELL_C)/6.0)
441 #define MITCHELL_Q2  ((       6.0*MITCHELL_B+30.0*MITCHELL_C)/6.0)
442 #define MITCHELL_Q3  ((     - 1.0*MITCHELL_B- 6.0*MITCHELL_C)/6.0)
443 
444          if (x < -2.0)
445             return(0.0);
446          if (x < -1.0)
447             return(MITCHELL_Q0-x*(MITCHELL_Q1-x*(MITCHELL_Q2-x*MITCHELL_Q3)));
448          if (x < 0.0)
449             return(MITCHELL_P0+x*x*(MITCHELL_P2-x*MITCHELL_P3));
450          if (x < 1.0)
451             return(MITCHELL_P0+x*x*(MITCHELL_P2+x*MITCHELL_P3));
452          if (x < 2.0)
453             return(MITCHELL_Q0+x*(MITCHELL_Q1+x*(MITCHELL_Q2+x*MITCHELL_Q3)));
454          return(0.0);
455       }
getSupport()456    virtual double getSupport()const
457       {
458          return 2.0;
459       }
460 TYPE_DATA
461 };
462 
463 class ossimQuadraticFilter : public ossimFilter
464 {
465 public:
ossimQuadraticFilter()466    ossimQuadraticFilter(){}
~ossimQuadraticFilter()467    virtual ~ossimQuadraticFilter(){}
filter(double x,double)468    double filter(double x, double /* support */ )const
469       {
470          if (x < -1.5)
471             return(0.0);
472          if (x < -0.5)
473             return(0.5*(x+1.5)*(x+1.5));
474          if (x < 0.5)
475             return(0.75-x*x);
476          if (x < 1.5)
477             return(0.5*(x-1.5)*(x-1.5));
478          return(0.0);
479       }
getSupport()480    double getSupport()const
481       {
482          return 1.5;
483       }
484 TYPE_DATA
485 };
486 
487 class ossimTriangleFilter : public ossimFilter
488 {
489 public:
ossimTriangleFilter()490    ossimTriangleFilter(){}
~ossimTriangleFilter()491    virtual ~ossimTriangleFilter() {}
492 
filter(double x,double)493    virtual double filter (double x, double /* support */ )const
494       {
495          if (x < -1.0)
496             return(0.0);
497          if (x < 0.0)
498             return(1.0+x);
499          if (x < 1.0)
500             return(1.0-x);
501          return(0.0);
502       }
getSupport()503    virtual double getSupport()const
504       {
505          return 1.0;
506       }
507 TYPE_DATA
508 };
509 
510 
511 #endif
512