OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimFilter.cpp
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % ZZZZZ OOO OOO M M %
7 % ZZ O O O O MM MM %
8 % ZZZ O O O O M M M %
9 % ZZ O O O O M M %
10 % ZZZZZ OOO OOO M M %
11 % %
12 % %
13 % ImageMagick Image Zoom Methods %
14 % %
15 % %
16 % Software Design %
17 % John Cristy %
18 % July 1992 %
19 % %
20 % %
21 % Copyright (C) 2000 ImageMagick Studio, a non-profit organization dedicated %
22 % to making software imaging solutions freely available. %
23 % %
24 % Permission is hereby granted, free of charge, to any person obtaining a %
25 % copy of this software and associated documentation files ("ImageMagick"), %
26 % to deal in ImageMagick without restriction, including without limitation %
27 % the rights to use, copy, modify, merge, publish, distribute, sublicense, %
28 % and/or sell copies of ImageMagick, and to permit persons to whom the %
29 % ImageMagick is furnished to do so, subject to the following conditions: %
30 % %
31 % The above copyright notice and this permission notice shall be included in %
32 % all copies or substantial portions of ImageMagick. %
33 % %
34 % The software is provided "as is", without warranty of any kind, express or %
35 % implied, including but not limited to the warranties of merchantability, %
36 % fitness for a particular purpose and noninfringement. In no event shall %
37 % ImageMagick Studio be liable for any claim, damages or other liability, %
38 % whether in an action of contract, tort or otherwise, arising from, out of %
39 % or in connection with ImageMagick or the use or other dealings in %
40 % ImageMagick. %
41 % %
42 % Except as contained in this notice, the name of the ImageMagick Studio %
43 % shall not be used in advertising or otherwise to promote the sale, use or %
44 % other dealings in ImageMagick without prior written authorization from the %
45 % ImageMagick Studio. %
46 % %
47 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
48 %
49 %
50 %
51 */
54 #include <ossim/matrix/newmat.h>
55 #include <iostream>
56 
57 
58 RTTI_DEF(ossimFilter, "ossimFilter");
59 RTTI_DEF1(ossimBoxFilter, "ossimBoxFilter",ossimFilter);
60 RTTI_DEF1(ossimSincFilter, "ossimSincFilter",ossimFilter);
61 RTTI_DEF1(ossimBellFilter, "ossimBellFilter",ossimFilter);
62 RTTI_DEF1(ossimNearestNeighborFilter, "ossimNearestNeighborFilter",ossimFilter);
63 RTTI_DEF1(ossimBesselFilter, "ossimBesselFilter",ossimFilter);
64 RTTI_DEF1(ossimBesselOrderOneFilter, "ossimBesselOrderOneFilter",ossimFilter);
65 RTTI_DEF1(ossimBlackmanFilter, "ossimBlackmanFilter",ossimFilter);
66 RTTI_DEF1(ossimBlackmanSincFilter, "ossimBlackmanSincFilter",ossimFilter);
67 RTTI_DEF1(ossimBlackmanBesselFilter, "ossimBlackmanBesselFilter",ossimFilter);
68 RTTI_DEF1(ossimCatromFilter, "ossimCatromFilter",ossimFilter);
69 RTTI_DEF1(ossimCubicFilter, "ossimCubicFilter",ossimFilter);
70 RTTI_DEF1(ossimBSplineFilter, "ossimBSplineFilter",ossimFilter);
71 RTTI_DEF1(ossimGaussianFilter, "ossimGaussianFilter",ossimFilter);
72 RTTI_DEF1(ossimHanningFilter, "ossimHanningFilter",ossimFilter);
73 RTTI_DEF1(ossimHammingFilter, "ossimHammingFilter",ossimFilter);
74 RTTI_DEF1(ossimHermiteFilter, "ossimHermiteFilter",ossimFilter);
75 RTTI_DEF1(ossimLanczosFilter, "ossimLanczosFilter",ossimFilter);
76 RTTI_DEF1(ossimMitchellFilter, "ossimMitchellFilter",ossimFilter);
77 RTTI_DEF1(ossimQuadraticFilter, "ossimQuadraticFilter",ossimFilter);
78 RTTI_DEF1(ossimTriangleFilter, "ossimTriangleFilter",ossimFilter);
79 RTTI_DEF1(ossimMagicFilter, "ossimMagicFilter",ossimFilter);
80 /*
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 % %
83 % %
84 % %
85 + B e s s e l O r d e r O n e %
86 % %
87 % %
88 % %
89 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
90 %
91 % Method BesselOrderOne computes the Bessel function of x of the first kind
92 % of order 0:
93 %
94 % Reduce x to |x| since j1(x)= -j1(-x), and for x in (0,8]
95 %
96 % j1(x) = x*j1(x);
97 %
98 % For x in (8,inf)
99 %
100 % j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
101 %
102 % where x1 = x-3*pi/4. Compute sin(x1) and cos(x1) as follow:
103 %
104 % cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
105 % = 1/sqrt(2) * (sin(x) - cos(x))
106 % sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
107 % = -1/sqrt(2) * (sin(x) + cos(x))
108 %
109 % The format of the BesselOrderOne method is:
110 %
111 % double BesselOrderOne(double x)
112 %
113 % A description of each parameter follows:
114 %
115 % o value: Method BesselOrderOne returns the Bessel function of x of the
116 % first kind of orders 1.
117 %
118 % o x: double value.
119 %
120 %
121 */
122 
123 static double J1(double x)
124 {
125  double
126  p,
127  q;
128 
129  int
130  i;
131 
132  static const double
133  Pone[] =
134  {
135  0.581199354001606143928050809e+21,
136  -0.6672106568924916298020941484e+20,
137  0.2316433580634002297931815435e+19,
138  -0.3588817569910106050743641413e+17,
139  0.2908795263834775409737601689e+15,
140  -0.1322983480332126453125473247e+13,
141  0.3413234182301700539091292655e+10,
142  -0.4695753530642995859767162166e+7,
143  0.270112271089232341485679099e+4
144  },
145  Qone[] =
146  {
147  0.11623987080032122878585294e+22,
148  0.1185770712190320999837113348e+20,
149  0.6092061398917521746105196863e+17,
150  0.2081661221307607351240184229e+15,
151  0.5243710262167649715406728642e+12,
152  0.1013863514358673989967045588e+10,
153  0.1501793594998585505921097578e+7,
154  0.1606931573481487801970916749e+4,
155  0.1e+1
156  };
157 
158  p=Pone[8];
159  q=Qone[8];
160  for (i=7; i >= 0; i--)
161  {
162  p=p*x*x+Pone[i];
163  q=q*x*x+Qone[i];
164  }
165  return(p/q);
166 }
167 
168 static double P1(double x)
169 {
170  double
171  p,
172  q;
173 
174  int
175  i;
176 
177  static const double
178  Pone[] =
179  {
180  0.352246649133679798341724373e+5,
181  0.62758845247161281269005675e+5,
182  0.313539631109159574238669888e+5,
183  0.49854832060594338434500455e+4,
184  0.2111529182853962382105718e+3,
185  0.12571716929145341558495e+1
186  },
187  Qone[] =
188  {
189  0.352246649133679798068390431e+5,
190  0.626943469593560511888833731e+5,
191  0.312404063819041039923015703e+5,
192  0.4930396490181088979386097e+4,
193  0.2030775189134759322293574e+3,
194  0.1e+1
195  };
196 
197  p=Pone[5];
198  q=Qone[5];
199  for (i=4; i >= 0; i--)
200  {
201  p=p*(8.0/x)*(8.0/x)+Pone[i];
202  q=q*(8.0/x)*(8.0/x)+Qone[i];
203  }
204  return(p/q);
205 }
206 
207 static double Q1(double x)
208 {
209  double p, q;
210  int i;
211 
212  static const double
213  Pone[] =
214  {
215  0.3511751914303552822533318e+3,
216  0.7210391804904475039280863e+3,
217  0.4259873011654442389886993e+3,
218  0.831898957673850827325226e+2,
219  0.45681716295512267064405e+1,
220  0.3532840052740123642735e-1
221  },
222  Qone[] =
223  {
224  0.74917374171809127714519505e+4,
225  0.154141773392650970499848051e+5,
226  0.91522317015169922705904727e+4,
227  0.18111867005523513506724158e+4,
228  0.1038187585462133728776636e+3,
229  0.1e+1
230  };
231 
232  p=Pone[5];
233  q=Qone[5];
234  for (i=4; i >= 0; i--)
235  {
236  p=p*(8.0/x)*(8.0/x)+Pone[i];
237  q=q*(8.0/x)*(8.0/x)+Qone[i];
238  }
239  return(p/q);
240 }
241 
242 double ossimBesselOrderOneFilter::filter(double x, double /* support */)const
243 {
244  double
245  p,
246  q;
247 
248  if (x == 0.0)
249  return(0.0);
250  p=x;
251  if (x < 0.0)
252  x=(-x);
253  if (x < 8.0)
254  return(p*J1(x));
255  q=sqrt(2.0/(M_PI*x))*(P1(x)*(1.0/sqrt(2.0)*(sin(x)-cos(x)))-8.0/x*Q1(x)*
256  (-1.0/sqrt(2.0)*(sin(x)+cos(x))));
257  if (p < 0.0)
258  q=(-q);
259  return(q);
260 
261 }
262 
263 void ossimFilter::createMatrix(NEWMAT::Matrix& m,
264  long width,
265  double middle,
266  double scale)const
267 {
268  NEWMAT::ColumnVector colVec(width);
269  NEWMAT::RowVector rowVec(width);
270 
271  double t = 0.0;
272  double val = 0.0;
273  if(width == 1)
274  {
275  t = 0;
276  val = filter(t, getSupport());
277  colVec[0] = val;
278  rowVec[0] = val;
279  }
280  else
281  {
282  for(long index = 0; index < width; index++)
283  {
284  t = (double)index/(double)(width-1);
285  t = middle + (t - .5)*scale;
286  val = filter(t, getSupport());
287  colVec[index] = val;
288  rowVec[index] = val;
289  }
290  }
291 
292  // do the outer product to construct the
293  // filter matrix
294  m = colVec * rowVec;
295 }
296 
297 
298 NEWMAT::Matrix *ossimFilter::newMatrix(long width,
299  double middle,
300  double scale)const
301 {
302  NEWMAT::Matrix *result = new NEWMAT::Matrix(width, width);
303 
304  createMatrix(*result,
305  width,
306  middle,
307  scale);
308 
309  return result;
310 }
311 
312 NEWMAT::RowVector *ossimFilter::newVector(long width,
313  double middle,
314  double scale)const
315 {
316  NEWMAT::RowVector *result = new NEWMAT::RowVector(width);
317 
318 
319  double t = 0.0;
320  double val = 0.0;
321  for(long index = 0; index < width; index++)
322  {
323  t = (double)index/(double)(width-1);
324  t = middle + (t- .5)*scale;
325  val = filter(t, getSupport());
326  (*result)[index] = val;
327  }
328 
329  return result;
330 }
RTTI_DEF(ossimFilter, "ossimFilter")
ossim_uint32 x
virtual double filter(double value, double) const
virtual void createMatrix(NEWMAT::Matrix &m, long width=3, double middle=0.0, double scale=0.0) const
virtual double getSupport() const =0
virtual NEWMAT::RowVector * newVector(long width, double middle=0.0, double scale=1.0) const
#define M_PI
virtual NEWMAT::Matrix * newMatrix(long width=3, double middle=0.0, double scale=0.0) const
RTTI_DEF1(ossimBoxFilter, "ossimBoxFilter", ossimFilter)
virtual double filter(double x, double support) const =0