aimstil  5.0.5
RF4Gaussian.h
Go to the documentation of this file.
1 #ifndef TIL_RF4_GAUSSIAN_H
2 #define TIL_RF4_GAUSSIAN_H
3 
4 
5 
6 // Local includes
7 
8 #include "til/til_common.h"
9 
10 #include "til/rf4.h"
11 #include "til/recursiveFilters.h"
12 #include "til/RecursiveFilterSum.h"
13 
14 // Namespace
15 
16 namespace til {
17 
18 
19 template < typename T >
21 (T &a0, T &a1,
22  T &c0, T &c1,
23  T &w0, T &w1,
24  T &b0, T &b1) {
25 
26  // Deriche's Gaussian approximation:
27  // ( 1.68 * cos(0.6318 * x / sigma)
28  // + 3.735 * sin(0.6318 * x / sigma) ) * exp (-1.783 * x / sigma) -
29  // (0.6803 * cos(1.997 * x / sigma)
30  //+ 0.2598 * sin(1.997 * x / sigma) ) * exp (-1.723 * x / sigma)
31 
32  a0 = (T) 1.68;
33  a1 = (T) 3.735;
34  c0 = (T) -0.6803;
35  c1 = (T) -0.2598;
36  w0 = (T) 0.6318;
37  w1 = (T) 1.997;
38  b0 = (T) 1.783;
39  b1 = (T) 1.723;
40 }
41 
42 template < typename T >
44 (T &a0, T &a1,
45  T &c0, T &c1,
46  T &w0, T &w1,
47  T &b0, T &b1) {
48 
49  // Deriche's First Gaussian Derivative approximation:
50  // (-0.6472 * cos(0.6719 * x / sigma)
51  // - 4.531 * sin(0.6719 * x / sigma) ) * exp (-1.527 * x / sigma) +
52  // (0.6494 * cos(2.072 * x / sigma)
53  // + 0.9557 * sin(2.072 * x / sigma) ) * exp (-1.516 * x / sigma)
54 
55  a0 = (T) -0.6472;
56  a1 = (T) -4.531;
57  c0 = (T) 0.6494;
58  c1 = (T) 0.9557;
59  w0 = (T) 0.6719;
60  w1 = (T) 2.072;
61  b0 = (T) 1.527;
62  b1 = (T) 1.516;
63 }
64 
65 
66 template < typename T >
68 (T &a0, T &a1,
69  T &c0, T &c1,
70  T &w0, T &w1,
71  T &b0, T &b1) {
72 
73  a0 = (T) -1.331;
74  a1 = (T) 3.661;
75  c0 = (T) 0.3225;
76  c1 = (T) -1.738;
77  w0 = (T) 0.748;
78  w1 = (T) 2.166;
79  b0 = (T) 1.24;
80  b1 = (T) 1.314;
81 }
82 
83 
84 
85 template < typename T >
87 (T a0, T a1,
88  T c0, T c1,
89  T cw0, T sw0,
90  T cw1, T sw1,
91  T eb0, T eb1)
92 {
93  return
94  eb0 * (a0 * (cw0 - eb0) - a1*sw0)
95  / (T(2) * cw0 * eb0 - eb0*eb0 - T(1)) +
96  eb1 * (c0 * (cw1 - eb1) - c1*sw1)
97  / (T(2) * cw1 * eb1 - eb1*eb1 - T(1));
98 }
99 
100 template < typename T >
102 (T a0, T a1,
103  T c0, T c1,
104  T cw0, T sw0,
105  T cw1, T sw1,
106  T eb0, T eb1)
107 {
108  return
109  eb0 *
110  ( cw0*a0 + eb0*eb0*a0*cw0 + eb0*eb0*a1*sw0 - 2.0*a0*eb0 -a1*sw0 ) /
111  (4*square(cw0*eb0)-4*cw0*eb0-4*cw0*eb0*eb0*eb0+2.0*eb0*eb0+square(eb0*eb0)+1.0) +
112  eb1 *
113  ( cw1*c0 + eb1*eb1*c0*cw1 + eb1*eb1*c1*sw1 - 2.0*c0*eb1 -c1*sw1 ) /
114  (4*square(cw1*eb1)-4*cw1*eb1-4*cw1*eb1*eb1*eb1+2.0*eb1*eb1+square(eb1*eb1)+1.0);
115 }
116 
117 template < typename T >
119 (T a0, T a1,
120  T c0, T c1,
121  T cw0, T sw0,
122  T cw1, T sw1,
123  T eb0, T eb1)
124 {
125  return
126  (-2*cube(cw0)*cube(eb0)*a1
127  -2*cube(cw0)*eb0*a1
128  -square(cw0)*square(square(eb0))*a1
129  +2*square(cw0)*cube(eb0)*a0*sw0
130  +6*square(eb0)*square(cw0)*a1
131  -2*square(cw0)*eb0*a0*sw0
132  -square(cw0)*a1
133  +cw0*square(square(eb0))*a0*sw0
134  +2*cube(eb0)*a1*cw0
135  +2*cw0*a1*eb0
136  -cw0*sw0*a0
137  +a1*square(square(eb0))
138  -4*cube(eb0)*a0*sw0
139  -6*a1*square(eb0)
140  +4*a0*eb0*sw0+a1)*eb0/(
141  (4*square(cw0)*square(eb0)
142  -4*cw0*cube(eb0)
143  -4*eb0*cw0
144  +square(square(eb0))
145  +2*square(eb0)+1)*sw0*
146  (-2*eb0*cw0+square(eb0)+1))
147  +
148  (
149  -2*cube(cw1)*cube(eb1)*c1
150  -2*cube(cw1)*eb1*c1
151  -square(square(eb1))*square(cw1)*c1
152  +square(square(eb1))*c1
153  +square(square(eb1))*sw1*c0*cw1
154  -4*cube(eb1)*sw1*c0
155  +2*square(cw1)*cube(eb1)*sw1*c0
156  +2*cube(eb1)*cw1*c1
157  -6*c1*square(eb1)
158  +6*square(cw1)*square(eb1)*c1
159  -2*square(cw1)*eb1*c0*sw1
160  +4*c0*eb1*sw1
161  +2*cw1*c1*eb1
162  +c1
163  -cw1*c0*sw1
164  -square(cw1)*c1)*eb1/
165  ((-4*cube(eb1)*cw1
166  +square(square(eb1))
167  +2*square(eb1)
168  +4*square(cw1)*square(eb1)
169  -4*eb1*cw1+1)*sw1*
170  (-2*eb1*cw1+square(eb1)+1));
171 }
172 
173 
174 
175 template < typename T >
177  RecursiveFilter<T, -1, 4> > RF4Gaussian(T sigma)
178 {
179  typedef RecursiveFilterSum< RecursiveFilter<T, +1, 4>, RecursiveFilter<T, -1, 4> > RecGaussian;
180 
181  const T EPSILON = 128 * std::numeric_limits<T>::epsilon();
182 
183  RecursiveFilter<T,+1,4> resForward;
184  RecursiveFilter<T,-1,4> resBackward;
185 
186 
187  // If sigma is too small (division following), set recursive
188  // filter to identity
189  if (sigma <= EPSILON)
190  {
191  resForward.setFilter(1,0,0,0,0,0,0,0);
192  resBackward.setFilter(1,0,0,0,0,0,0,0);
193  return RecGaussian(resForward, resBackward);
194  }
195 
196  T a0, a1, c0, c1, b0, b1, w0, w1;
197  setRecursiveFilterCoefficientsToGaussian(a0,a1,c0,c1,w0,w1,b0,b1);
198 
199  resForward.setFilterFromFormula(a0, a1, c0, c1, w0, w1, b0, b1, sigma);
200  resBackward.setFilterFromFormula(a0, a1, c0, c1, w0, w1, b0, b1, sigma);
201 
202  T cw0 = cos(w0/sigma);
203  T cw1 = cos(w1/sigma);
204  T sw0 = sin(w0/sigma);
205  T sw1 = sin(w1/sigma);
206  T norm = recursiveGaussianNorm(a0,a1,c0,c1,cw0,sw0,cw1,sw1,(T)exp(b0/sigma),(T)exp(b1/sigma));
207 
208  resForward.normalize(norm);
209  resBackward.normalize(norm);
210 
211  return RecGaussian(resForward, resBackward);
212 }
213 
214 
215 template < typename T >
217  RecursiveFilter<T, -1, 4> > RF4GaussianDerivative(T sigma, T stepSize = 1)
218 {
219  typedef RecursiveFilterSum< RecursiveFilter<T, +1, 4>, RecursiveFilter<T, -1, 4> > RecGaussian;
220 
221  const T EPSILON = 128 * std::numeric_limits<T>::epsilon();
222 
223  if (sigma <= EPSILON)
224  {
225  // WHY: division by sigma later on
226  throw std::domain_error("Sigma is too small");
227  }
228 
229  T a0, a1, c0, c1, b0, b1, w0, w1;
230 
232 
233  RecursiveFilter<T, +1, 4> resForward;
234  RecursiveFilter<T, -1, 4> resBackward;
235  resForward.setFilterFromFormula(-a0, -a1, -c0, -c1, w0, w1, b0, b1, sigma);
236  resBackward.setFilterFromFormula(a0, a1, c0, c1, w0, w1, b0, b1, sigma);
237 
238  T cw0 = cos(w0/sigma);
239  T cw1 = cos(w1/sigma);
240  T sw0 = sin(w0/sigma);
241  T sw1 = sin(w1/sigma);
242 
243  T norm = recursiveGaussianDerivativeNorm(a0,a1,c0,c1,cw0,sw0,cw1,sw1,(T)exp(b0/sigma),(T)exp(b1/sigma));
244 
245  norm *= stepSize;
246 
247  resForward.normalize(norm);
248  resBackward.normalize(norm);
249 
250  return RecGaussian(resForward, resBackward);
251 }
252 
253 
254 template < typename T >
257 {
258  typedef RecursiveFilterSum< RecursiveFilter<T, +1, 4>, RecursiveFilter<T, -1, 4> > RecGaussian;
259 
260 
261  if (sigma < 0.7)
262  {
263  throw std::invalid_argument("Second order derivative computation using recursive filtering are unreliable for sigma < 0.7");
264  }
265 
266 
267  T a0, a1, c0, c1, b0, b1, w0, w1;
269 
270  RecursiveFilter<T, +1, 4> resForward;
271  RecursiveFilter<T, -1, 4> resBackward;
272  resForward.setFilterFromFormula(a0, a1, c0, c1, w0, w1, b0, b1, sigma);
273  resBackward.setFilterFromFormula(a0, a1, c0, c1, w0, w1, b0, b1, sigma);
274 
275  T cw0 = cos(w0/sigma);
276  T cw1 = cos(w1/sigma);
277  T sw0 = sin(w0/sigma);
278  T sw1 = sin(w1/sigma);
279 
280  T norm = recursiveGaussianSecondDerivativeNorm(a0,a1,c0,c1,cw0,sw0,cw1,sw1,(T)exp(b0/sigma),(T)exp(b1/sigma));
281 
282  resForward.normalize(norm);
283  resBackward.normalize(norm);
284 
285  return RecGaussian(resForward, resBackward);
286 }
287 
288 } // namespace
289 
290 #endif
291 
void setRecursiveFilterCoefficientsToSecondDerivativeGaussian(T &a0, T &a1, T &c0, T &c1, T &w0, T &w1, T &b0, T &b1)
Definition: RF4Gaussian.h:68
T recursiveGaussianNorm(T a0, T a1, T c0, T c1, T cw0, T sw0, T cw1, T sw1, T eb0, T eb1)
Definition: RF4Gaussian.h:87
Sum of two recursive filters, a forward and a backward one.
INLINE double norm(const T &a, const T &b)
< Euclidean norm of 2D vector (a, b)
Belongs to package Box Do not include directly, include til/Box.h instead.
Definition: Accumulator.h:10
RecursiveFilterSum< RecursiveFilter< T,+1, 4 >, RecursiveFilter< T, -1, 4 > > RF4Gaussian(T sigma)
Definition: RF4Gaussian.h:177
General macros, definitions and functions.
INLINE const T cube(const T &a)
Max of two numbers.
void setRecursiveFilterCoefficientsToDerivativeGaussian(T &a0, T &a1, T &c0, T &c1, T &w0, T &w1, T &b0, T &b1)
Definition: RF4Gaussian.h:44
T recursiveGaussianDerivativeNorm(T a0, T a1, T c0, T c1, T cw0, T sw0, T cw1, T sw1, T eb0, T eb1)
Definition: RF4Gaussian.h:102
void setRecursiveFilterCoefficientsToGaussian(T &a0, T &a1, T &c0, T &c1, T &w0, T &w1, T &b0, T &b1)
Definition: RF4Gaussian.h:21
RecursiveFilterSum< RecursiveFilter< T,+1, 4 >, RecursiveFilter< T, -1, 4 > > RF4GaussianDerivative(T sigma, T stepSize=1)
Definition: RF4Gaussian.h:217
void square(const TImage &in, TImage &out)
Definition: imageArith.h:310
RecursiveFilterSum< RecursiveFilter< T,+1, 4 >, RecursiveFilter< T, -1, 4 > > RF4GaussianSecondDerivative(T sigma)
Definition: RF4Gaussian.h:256
T recursiveGaussianSecondDerivativeNorm(T a0, T a1, T c0, T c1, T cw0, T sw0, T cw1, T sw1, T eb0, T eb1)
Definition: RF4Gaussian.h:119