22 FastGauss::FastGauss(
void)
38 FastGauss::~FastGauss(
void)
43 bool FastGauss::IsAllocated()
47 long FastGauss::GetLines()
52 long FastGauss::GetCols()
58 long FastGauss::GetStridePix()
63 double FastGauss::GetScale()
68 bool FastGauss::AllocateResources(
long lines,
long cols,
double scale)
78 throw "Scale values lower than 0.5 are not alowed";
82 throw "Danger: Bad Approximation for scale values higher than 100";
87 filt_poles =
new complex<double>[5];
89 filt_coeffs =
new float[6];
91 m_resid_step =
new float[3];
93 m_resid_ic =
new float[9];
97 m_i_stridepix = m_i_cols;
100 temp =
new float[m_i_lines*m_i_cols];
105 _compute_gauss3_resids(filt_poles, filt_coeffs, m_resid_ic, m_resid_step);
111 bool FastGauss::FreeResources()
113 m_bAllocated =
false;
114 if(m_resid_step != NULL)
117 delete[] m_resid_step;
121 if(m_resid_ic!= NULL)
128 if(filt_coeffs != NULL)
131 delete[] filt_coeffs;
134 if(filt_poles != NULL)
148 void FastGauss::_iir_gaussfilt3_horz(
float * in,
float * tempbuf,
float * out,
int width,
int height,
int stridepix,
float *coeffs,
float *resid_ic,
float *resid_step)
153 float bi_val, bf_val;
156 for(i = 0; i < height; i++)
164 compute_step_forward_ic(bi_val, coeffs, i0);
171 i0[0] = tempbuf[width-1];
172 i0[1] = tempbuf[width-2];
173 i0[2] = tempbuf[width-3];
175 compute_natural_backward_ic(resid_ic,i0);
176 add_step_backward_ic(resid_step,bf_val,i0);
178 iir_filt_backward(tempbuf,out+bi,width,coeffs,i0);
182 void FastGauss::_iir_gaussfilt3_vert(
float * inout,
float *tempbuf,
int width,
int height,
int stridepix,
float *coeffs,
float *resid_ic,
float *resid_step)
186 float b0 = coeffs[0];
187 float a1 = coeffs[1];
188 float a2 = coeffs[2];
189 float a3 = coeffs[3];
193 float bi_val, bf_val;
197 for(j = 0; j < width; j++)
205 compute_step_forward_ic(bi_val, coeffs, i0);
212 i0[0] = tempbuf[height-1];
213 i0[1] = tempbuf[height-2];
214 i0[2] = tempbuf[height-3];
216 compute_natural_backward_ic(resid_ic,i0);
217 add_step_backward_ic(resid_step,bf_val,i0);
219 iir_filt_backward(tempbuf,inout+bi,s,height,coeffs,i0);
223 void FastGauss::_iir_gaussfilt3(
float * in,
float * out,
float *tempbuf,
int width,
int height,
int stridepix,
float *coeffs,
float *resid_ic,
float *resid_step )
225 _iir_gaussfilt3_horz(in, tempbuf, out, width, height, stridepix, coeffs, resid_ic, resid_step);
226 _iir_gaussfilt3_vert(out, tempbuf, width, height, stridepix, coeffs, resid_ic, resid_step);
229 bool FastGauss::GaussFilt(
float * in,
float * out)
232 throw "Resources not allocated";
237 for( i = 0; i < m_i_lines; i++ )
238 memcpy(in + i*m_i_stridepix, in + m_i_cols*i, m_i_cols*
sizeof(
float) );
241 _iir_gaussfilt3(in, out, temp, m_i_cols, m_i_lines, m_i_stridepix, filt_coeffs, m_resid_ic, m_resid_step );
246 void FastGauss::compute_step_forward_ic(
float bord_val,
float *coeffs,
float *i0)
249 float b0 = coeffs[0];
250 float a1 = coeffs[1];
251 float a2 = coeffs[2];
252 float a3 = coeffs[3];
254 i0[0] = i0[1] = i0[2] = bord_val*b0/(1+a1+a2+a3);
257 void FastGauss::compute_natural_backward_ic(
float *resid_ic,
float *init_cond )
259 float i0 = init_cond[0];
260 float i1 = init_cond[1];
261 float i2 = init_cond[2];
263 init_cond[0]=i0*resid_ic[0]+i1*resid_ic[1]+i2*resid_ic[2];
264 init_cond[1]=i0*resid_ic[3]+i1*resid_ic[4]+i2*resid_ic[5];
265 init_cond[2]=i0*resid_ic[6]+i1*resid_ic[7]+i2*resid_ic[8];
268 void FastGauss::add_step_backward_ic(
float *resid_step,
float val,
float *init_cond )
270 init_cond[0] += val*resid_step[0];
271 init_cond[1] += val*resid_step[1];
272 init_cond[2] += val*resid_step[2];
275 void FastGauss::_compute_gauss3_resids( complex<double> filt_poles[],
float *filt_coeffs,
float *resid_ic,
float *resid_step )
278 complex <double> p1, p2, p3, _p1, _p2, _p3;
279 complex <double> p1_1, p1_2, p1_3, p2_1, p2_2, p2_3, p3_1, p3_2, p3_3;
280 double b0, a1, a2, a3;
304 complex <double> res1a, res2a, res3a, res1b, res2b, res3b, res1c, res2c, res3c;
306 res1a = b0/a3*p1_3/(1.0-p1_2)/(1.0-p1_1*(p2+p2_1)+p1_2)/(1.0-p1_1*(p3+p3_1)+p1_2);
307 res2a = b0/a3*p2_3/(1.0-p2_2)/(1.0-p2_1*(p1+p1_1)+p2_2)/(1.0-p2_1*(p3+p3_1)+p2_2);
308 res3a = b0/a3*p3_3/(1.0-p3_2)/(1.0-p3_1*(p2+p2_1)+p3_2)/(1.0-p3_1*(p1+p1_1)+p3_2);
317 complex<double> r0, r1, r2, r3, r4, r5, r6, r7, r8;
319 r0 = (-a1*res1a-a2*res1b-a3*res1c);
320 r1 = (-a2*res1a-a3*res1b);
322 r3 = (-a1*res2a-a2*res2b-a3*res2c);
323 r4 = (-a2*res2a-a3*res2b);
325 r6 = (-a1*res3a-a2*res3b-a3*res3c);
326 r7 = (-a2*res3a-a3*res3b);
329 resid_ic[0] = (float)real(r0+r3+r6);
330 resid_ic[1] = (float)real(r1+r4+r7);
331 resid_ic[2] = (float)real(r2+r5+r8);
332 resid_ic[3] = (float)real(r0*p1+r3*p2+r6*p3);
333 resid_ic[4] = (float)real(r1*p1+r4*p2+r7*p3);
334 resid_ic[5] = (float)real(r2*p1+r5*p2+r8*p3);
335 resid_ic[6] = (float)real(r0*p1*p1+r3*p2*p2+r6*p3*p3);
336 resid_ic[7] = (float)real(r1*p1*p1+r4*p2*p2+r7*p3*p3);
337 resid_ic[8] = (float)real(r2*p1*p1+r5*p2*p2+r8*p3*p3);
340 complex <double> res1, res2, res3, res4;
342 res1 = b0*res1a/(1.0-_p1);
343 res2 = b0*res2a/(1.0-_p2);
344 res3 = b0*res3a/(1.0-_p3);
345 res4 = b0*b0/(1+a1+a2+a3)/(1+a1+a2+a3);
346 resid_step[0] = (float)real(res1+res2+res3+res4);
347 resid_step[1] = (float)real(res1*p1+res2*p2+res3*p3+res4);
348 resid_step[2] = (float)real(res1*p1*p1+res2*p2*p2+res3*p3*p3+res4);
Implements 3 Tap IIR Gaussian Filtering with Boundary Conditions.
Functions for generic, 3 tap, iir filtering.
void iir_filt_forward(float *in, int stepin, float *out, int stepout, int length, float *coeffs, float *i0)
Functions iir_filt_forward and iir_filt_backward do a 3 tap recursive filtering operation on floating...
Coefficients and poles of IIR Gaussian Derivative Filters (order 0, 1 and 2).
void calc_poles(int taps, const double scale, const complex< double > oldpoles[], complex< double > newpoles[])
5 tap second derivative filter with Linf norm approximation
void calc_coeffs(int taps, const complex< double > poles[], const double s, float *coeffs)
Compute the coefficients of the filter for scale s, given the poles at scale 2.
const complex< double > d0_N3_Linf[]
5 tap gaussian filter with L2 norm approximation