38 puts(
"Gaussian convolution demo, P. Getreuer 2013");
40 puts(
"Single-precision computation");
42 puts(
"Double-precision computation");
44 puts(
"\nSyntax: gaussian_conv_demo [options] <input> <output>\n");
47 puts(
" -a <algo> algorithm to use, choices are");
48 puts(
" fir FIR approximation, tol = kernel accuracy");
49 puts(
" dct DCT-based convolution");
50 puts(
" box box filtering, K = # passes");
51 puts(
" sii stacked integral images, K = # boxes");
52 puts(
" am Alvarez-Mazorra using regression on q,");
53 puts(
" K = # passes, tol = boundary accuracy");
54 puts(
" deriche Deriche recursive filtering,");
55 puts(
" K = order, tol = boundary accuracy");
56 puts(
" vyv Vliet-Young-Verbeek recursive filtering,");
57 puts(
" K = order, tol = boundary accuracy");
58 puts(
" -s <number> sigma, standard deviation of the Gaussian");
59 puts(
" -K <number> specifies number of steps (box, sii, am)");
60 puts(
" -t <number> accuracy tolerance (fir, am, deriche, yv)\n");
84 void normalize(
num *output_image,
long num_pixels) {
85 num min_value = output_image[0];
86 num max_value = output_image[0];
89 for (i = 1; i < num_pixels; ++i) {
90 if (output_image[i] < min_value) {
91 min_value = output_image[i];
92 }
else if (output_image[i] > max_value) {
93 max_value = output_image[i];
96 scale = 1.0 / (max_value - min_value);
97 for (i = 0; i < num_pixels; ++i) {
98 output_image[i] = (output_image[i] - min_value) * scale;
102 int main(
int argc,
char **argv)
105 num *input_image = NULL;
106 num *output_image = NULL;
107 unsigned long time_start;
109 int width, height, num_channels, success = 0;
119 num_pixels = ((long)width) * ((long)height);
120 num_channels =
is_grayscale(input_image, num_pixels) ? 1 : 3;
123 if (!(output_image = (
num *)malloc(
sizeof(
num)
124 * num_channels * num_pixels)))
127 printf(
"Convolving %dx%d %s image with Gaussian, sigma=%g\n",
128 width, height, (num_channels == 3 ?
"RGB" :
"gray"), param.
sigma);
131 if (!strcmp(param.
algo,
"fir"))
136 printf(
"FIR convolution, tol=%g\n", param.
tol);
138 if (!(buffer = (
num *)malloc(
sizeof(
num) * width)))
147 width, height, num_channels);
151 else if (!strcmp(param.
algo,
"dct"))
155 printf(
"DCT-based convolution\n");
158 width, height, num_channels, param.
sigma)))
164 else if (!strcmp(param.
algo,
"box"))
168 printf(
"Box filtering, K=%d passes\n",
171 if (!(buffer = (
num *)malloc(
sizeof(
num) *
172 ((width >= height) ? width : height))))
174 fprintf(stderr,
"Error: Out of memory\n");
179 width, height, num_channels, param.
sigma, param.
K);
182 else if (!strcmp(param.
algo,
"ebox"))
187 printf(
"Extended box filtering, K=%d passes\n",
190 if (!(buffer = (
num *)malloc(
sizeof(
num) *
191 ((width >= height) ? width : height))))
193 fprintf(stderr,
"Error: Out of memory\n");
199 width, height, num_channels);
202 else if (!strcmp(param.
algo,
"sii"))
209 fprintf(stderr,
"Error: K=%d is invalid for SII\n", param.
K);
213 printf(
"Stacked integral images, K=%d boxes\n", param.
K);
217 ((width >= height) ? width : height)))))
221 width, height, num_channels);
224 else if (!strcmp(param.
algo,
"am"))
226 printf(
"Alvarez-Mazorra recursive filtering, K=%d passes,"
227 " tol=%g left boundary accuracy\n", param.
K, param.
tol);
229 width, height, num_channels,
232 else if (!strcmp(param.
algo,
"deriche"))
239 fprintf(stderr,
"Error: K=%d is invalid for Deriche\n", param.
K);
243 printf(
"Deriche recursive filtering,"
244 " K=%d, tol=%g boundary accuracy\n", param.
K, param.
tol);
247 || !(buffer = (
num *)malloc(
sizeof(
num) * 2 *
248 ((width >= height) ? width : height))))
250 fprintf(stderr,
"Error: Out of memory\n");
256 width, height, num_channels);
259 else if (!strcmp(param.
algo,
"vyv"))
265 fprintf(stderr,
"Error: K=%d is invalid for VYV\n", param.
K);
269 printf(
"Vliet-Young-Verbeek recursive filtering,"
270 " K=%d, tol=%g left boundary accuracy\n", param.
K, param.
tol);
273 width, height, num_channels);
277 fprintf(stderr,
"Unknown method \"%s\".\n", param.
algo);
283 normalize(output_image, width * height);
288 | ((num_channels == 1) ? IMAGEIO_GRAYSCALE : IMAGEIO_RGB), 95))
308 const num *red = rgb_image;
309 const num *green = rgb_image + num_pixels;
310 const num *blue = rgb_image + 2 * num_pixels;
313 for (i = 0; i < num_pixels; ++i)
314 if (red[i] != green[i] || red[i] != blue[i])
323 static const char *default_output_file = (
const char *)
"out.bmp";
324 static const char *default_algo = (
const char *)
"exact";
339 param->
algo = default_algo;
343 for (i = 1; i < argc;)
345 if (argv[i] && argv[i][0] ==
'-')
347 if ((option_char = argv[i][1]) == 0)
349 fprintf(stderr,
"Invalid parameter format.\n");
354 option_string = &argv[i][2];
356 option_string = argv[i];
359 fprintf(stderr,
"Invalid parameter format.\n");
366 param->
algo = option_string;
369 param->
sigma = atof(option_string);
371 if (param->
sigma < 0)
373 fprintf(stderr,
"sigma must be positive.\n");
378 param->
K = atoi(option_string);
382 fprintf(stderr,
"K must be positive.\n");
387 param->
tol = atof(option_string);
391 fprintf(stderr,
"Tolerance must be positive.\n");
399 if (isprint(option_char))
400 fprintf(stderr,
"Unknown option \"-%c\".\n", option_char);
402 fprintf(stderr,
"Unknown option.\n");