A Survey of Gaussian Convolution Algorithms
Main Page
Modules
Files
File List
Globals
strategy_gaussian_conv.c
Go to the documentation of this file.
1
20
#include "
strategy_gaussian_conv.h
"
21
#include <stdlib.h>
22
#include <string.h>
23
#include "
gaussian_conv_fir.h
"
24
#include "
gaussian_conv_dct.h
"
25
#include "
gaussian_conv_box.h
"
26
#include "
gaussian_conv_ebox.h
"
27
#include "
gaussian_conv_sii.h
"
28
#include "
gaussian_conv_am.h
"
29
#include "
gaussian_conv_deriche.h
"
30
#include "
gaussian_conv_vyv.h
"
31
32
struct
gconv_
33
{
34
num
*
dest
;
35
const
num
*
src
;
36
num
*
buffer
;
37
long
N
;
38
long
stride
;
39
const
char
*
algo
;
40
double
sigma
;
41
int
K
;
42
num
tol
;
43
void
*
coeffs
;
44
void (*
execute
)(
gconv
*);
45
void (*
free
)(
gconv
*);
46
};
47
48
#ifndef DOXYGEN_SHOULD_SKIP_THIS
49
static
int
gconv_fir_plan(
gconv
*g);
50
static
int
gconv_dct_plan(
gconv
*g);
51
static
int
gconv_box_plan(
gconv
*g);
52
static
int
gconv_ebox_plan(
gconv
*g);
53
static
int
gconv_sii_plan(
gconv
*g);
54
static
int
gconv_am_orig_plan(
gconv
*g);
55
static
int
gconv_am_plan(
gconv
*g);
56
static
int
gconv_deriche_plan(
gconv
*g);
57
static
int
gconv_vyv_plan(
gconv
*g);
58
#endif
59
72
gconv
*
gconv_plan
(
num
*dest,
const
num
*src,
long
N,
long
stride,
73
const
char
*algo,
double
sigma,
int
K,
num
tol)
74
{
75
struct
gconv_algo_entry
76
{
77
const
char
*name;
78
int (*plan)(
gconv
*);
79
} algos[] = {
80
{
"fir"
, gconv_fir_plan},
81
{
"dct"
, gconv_dct_plan},
82
{
"box"
, gconv_box_plan},
83
{
"ebox"
, gconv_ebox_plan},
84
{
"sii"
, gconv_sii_plan},
85
{
"am_orig"
, gconv_am_orig_plan},
86
{
"am"
, gconv_am_plan},
87
{
"deriche"
, gconv_deriche_plan},
88
{
"vyv"
, gconv_vyv_plan}
89
};
90
gconv
*g;
91
size_t
i;
92
93
if
(!dest || !src || N <= 0 || sigma <= 0 || tol < 0 || tol > 1
94
|| !(g = (
gconv
*)malloc(
sizeof
(
gconv
))))
95
return
NULL;
96
97
g->
dest
= dest;
98
g->
src
= src;
99
g->
buffer
= NULL;
100
g->
N
= N;
101
g->
stride
= stride;
102
g->
algo
= algo;
103
g->
K
= K;
104
g->
sigma
= sigma;
105
g->
tol
= tol;
106
g->
coeffs
= NULL;
107
108
for
(i = 0; i <
sizeof
(algos)/
sizeof
(*algos); ++i)
109
if
(!strcmp(algo, algos[i].name))
110
{
111
if
(algos[i].plan(g))
112
return
g;
113
else
114
break
;
115
}
116
117
gconv_free
(g);
118
return
NULL;
119
}
120
125
void
gconv_execute
(
gconv
*g)
126
{
127
g->
execute
(g);
128
}
129
134
void
gconv_free
(
gconv
*g)
135
{
136
if
(g)
137
{
138
if
(g->
free
)
139
g->
free
(g);
140
141
free(g);
142
}
143
}
144
145
#ifndef DOXYGEN_SHOULD_SKIP_THIS
146
/* FIR filtering. */
147
static
void
gconv_fir_execute(
gconv
*g);
148
static
void
gconv_fir_free(
gconv
*g);
149
150
static
int
gconv_fir_plan(
gconv
*g)
151
{
152
g->
execute
= gconv_fir_execute;
153
g->
free
= gconv_fir_free;
154
return
(g->
coeffs
= malloc(
sizeof
(
fir_coeffs
)))
155
&&
fir_precomp
((
fir_coeffs
*)g->
coeffs
, g->
sigma
, g->
tol
);
156
}
157
158
static
void
gconv_fir_execute(
gconv
*g)
159
{
160
fir_gaussian_conv
(*((
fir_coeffs
*)g->
coeffs
),
161
g->
dest
, g->
src
, g->
N
, g->
stride
);
162
}
163
164
static
void
gconv_fir_free(
gconv
*g)
165
{
166
if
(g->
coeffs
)
167
{
168
fir_free
((
fir_coeffs
*)g->
coeffs
);
169
free(g->
coeffs
);
170
}
171
}
172
173
/* DCT (discrete cosine transform) based convolution. */
174
static
void
gconv_dct_execute(
gconv
*g);
175
static
void
gconv_dct_free(
gconv
*g);
176
177
static
int
gconv_dct_plan(
gconv
*g)
178
{
179
g->
execute
= gconv_dct_execute;
180
g->
free
= gconv_dct_free;
181
return
(g->
coeffs
= malloc(
sizeof
(
dct_coeffs
)))
182
&&
dct_precomp
((
dct_coeffs
*)g->
coeffs
, g->
dest
, g->
src
,
183
g->
N
, g->
stride
, g->
sigma
);
184
}
185
186
static
void
gconv_dct_execute(
gconv
*g)
187
{
188
dct_gaussian_conv
(*((
dct_coeffs
*)g->
coeffs
));
189
}
190
191
static
void
gconv_dct_free(
gconv
*g)
192
{
193
if
(g->
coeffs
)
194
{
195
dct_free
((
dct_coeffs
*)g->
coeffs
);
196
free(g->
coeffs
);
197
}
198
}
199
200
/* Box filtering. */
201
static
void
gconv_box_execute(
gconv
*g);
202
static
void
gconv_box_free(
gconv
*g);
203
204
static
int
gconv_box_plan(
gconv
*g)
205
{
206
g->
execute
= gconv_box_execute;
207
g->
free
= gconv_box_free;
208
return
((g->
K
> 0) && (g->
buffer
= malloc(
sizeof
(
num
)*g->
N
))) ? 1 : 0;
209
}
210
211
static
void
gconv_box_execute(
gconv
*g)
212
{
213
box_gaussian_conv
(g->
dest
, g->
buffer
, g->
src
, g->
N
, g->
stride
,
214
g->
sigma
, g->
K
);
215
}
216
217
static
void
gconv_box_free(
gconv
*g)
218
{
219
if
(g->
buffer
)
220
free(g->
buffer
);
221
}
222
223
/* Extended box filter. */
224
static
void
gconv_ebox_execute(
gconv
*g);
225
static
void
gconv_ebox_free(
gconv
*g);
226
227
static
int
gconv_ebox_plan(
gconv
*g)
228
{
229
g->
execute
= gconv_ebox_execute;
230
g->
free
= gconv_ebox_free;
231
232
if
((g->
K
<= 0) || !(g->
buffer
= malloc(
sizeof
(
num
) * g->
N
))
233
|| !(g->
coeffs
= malloc(
sizeof
(
ebox_coeffs
))))
234
return
0;
235
236
ebox_precomp
((
ebox_coeffs
*)g->
coeffs
, g->
sigma
, g->
K
);
237
return
1;
238
}
239
240
static
void
gconv_ebox_execute(
gconv
*g)
241
{
242
ebox_gaussian_conv
(*((
ebox_coeffs
*)g->
coeffs
),
243
g->
dest
, g->
buffer
, g->
src
, g->
N
, g->
stride
);
244
}
245
246
static
void
gconv_ebox_free(
gconv
*g)
247
{
248
if
(g->
buffer
)
249
free(g->
buffer
);
250
if
(g->
coeffs
)
251
free(g->
coeffs
);
252
}
253
254
/* SII Stacked integral images. */
255
static
void
gconv_sii_execute(
gconv
*g);
256
static
void
gconv_sii_free(
gconv
*g);
257
258
static
int
gconv_sii_plan(
gconv
*g)
259
{
260
g->
execute
= gconv_sii_execute;
261
g->
free
= gconv_sii_free;
262
263
if
(!
SII_VALID_K
(g->
K
) || !(g->
coeffs
= malloc(
sizeof
(
sii_coeffs
))))
264
return
0;
265
266
sii_precomp
((
sii_coeffs
*)g->
coeffs
, g->
sigma
, g->
K
);
267
268
return
(g->
buffer
= malloc(
sizeof
(
num
) *
sii_buffer_size
(
269
*((
sii_coeffs
*)g->
coeffs
), g->
N
))) ? 1 : 0;
270
}
271
272
static
void
gconv_sii_execute(
gconv
*g)
273
{
274
sii_gaussian_conv
(*((
sii_coeffs
*)g->
coeffs
),
275
g->
dest
, g->
buffer
, g->
src
, g->
N
, g->
stride
);
276
}
277
278
static
void
gconv_sii_free(
gconv
*g)
279
{
280
if
(g->
buffer
)
281
free(g->
buffer
);
282
if
(g->
coeffs
)
283
free(g->
coeffs
);
284
}
285
286
/* Alvarez-Mazorra, original algorithm. */
287
static
void
gconv_am_orig_execute(
gconv
*g);
288
289
static
int
gconv_am_orig_plan(
gconv
*g)
290
{
291
g->
execute
= gconv_am_orig_execute;
292
g->
free
= NULL;
293
return
1;
294
}
295
296
static
void
gconv_am_orig_execute(
gconv
*g)
297
{
298
am_gaussian_conv
(g->
dest
, g->
src
, g->
N
, 1,
299
g->
sigma
, g->
K
, g->
tol
, 0);
300
}
301
302
/* Alvarez-Mazorra with proposed regression on parameter q. */
303
static
void
gconv_am_execute(
gconv
*g);
304
305
static
int
gconv_am_plan(
gconv
*g)
306
{
307
g->
execute
= gconv_am_execute;
308
g->
free
= NULL;
309
return
(g->
K
> 0);
310
}
311
312
static
void
gconv_am_execute(
gconv
*g)
313
{
314
am_gaussian_conv
(g->
dest
, g->
src
, g->
N
, 1,
315
g->
sigma
, g->
K
, g->
tol
, 1);
316
}
317
318
/* Deriche recursive filtering. */
319
static
void
gconv_deriche_execute(
gconv
*g);
320
static
void
gconv_deriche_free(
gconv
*g);
321
322
static
int
gconv_deriche_plan(
gconv
*g)
323
{
324
g->
execute
= gconv_deriche_execute;
325
g->
free
= gconv_deriche_free;
326
327
if
(!
DERICHE_VALID_K
(g->
K
)
328
|| !(g->
buffer
= malloc(
sizeof
(
num
) * 2 * g->
N
))
329
|| !(g->
coeffs
= malloc(
sizeof
(
deriche_coeffs
))))
330
return
0;
331
332
deriche_precomp
((
deriche_coeffs
*)g->
coeffs
, g->
sigma
, g->
K
, g->
tol
);
333
return
1;
334
}
335
336
static
void
gconv_deriche_execute(
gconv
*g)
337
{
338
deriche_gaussian_conv
(*((
deriche_coeffs
*)g->
coeffs
),
339
g->
dest
, g->
buffer
, g->
src
, g->
N
, g->
stride
);
340
}
341
342
static
void
gconv_deriche_free(
gconv
*g)
343
{
344
if
(g->
buffer
)
345
free(g->
buffer
);
346
if
(g->
coeffs
)
347
free(g->
coeffs
);
348
}
349
350
/* Vliet-Young-Verbeek recursive filtering. */
351
static
void
gconv_vyv_execute(
gconv
*g);
352
static
void
gconv_vyv_free(
gconv
*g);
353
354
static
int
gconv_vyv_plan(
gconv
*g)
355
{
356
g->
execute
= gconv_vyv_execute;
357
g->
free
= gconv_vyv_free;
358
359
if
(!
VYV_VALID_K
(g->
K
) || !(g->
coeffs
= malloc(
sizeof
(
vyv_coeffs
))))
360
return
0;
361
362
vyv_precomp
((
vyv_coeffs
*)g->
coeffs
, g->
sigma
, g->
K
, g->
tol
);
363
return
1;
364
}
365
366
static
void
gconv_vyv_execute(
gconv
*g)
367
{
368
vyv_gaussian_conv
(*((
vyv_coeffs
*)g->
coeffs
),
369
g->
dest
, g->
src
, g->
N
, g->
stride
);
370
}
371
372
static
void
gconv_vyv_free(
gconv
*g)
373
{
374
if
(g->
coeffs
)
375
free(g->
coeffs
);
376
}
377
#endif
Generated on Sat Dec 14 2013 21:33:17 for A Survey of Gaussian Convolution Algorithms by
1.8.3.1