1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 c-style: "K&R" -*- */
3 /*---------------------------------------------------------------------------
4 imgproc: processes image
6 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008
7 Gerber van der Graaf <gerber_graaf@users.sourceforge.net
9 imgproc is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR 'PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software Foundation,
21 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 ------------------------------------------------------------------------*/
32 #define PARFILE "gpivrc" /* Parameter file name */
35 Usage: imgproc | mktestimg | smooth | hilo | clip | fft | lowpass | highpass | getbit | subtr-img \n\
36 [-b int] [-h | --help] [-i | --image] [-o | --operation] \n\
37 [-p | --print] [-w int] [-f | --filter] [-t | --threshold int] \n\
38 [-v] [filename] < stdin > stdout \n\
42 -b bit: for getbit: bit number [0, .., 7] \n\
43 -f | --filter: for imgproc: image filter to be performed: \n\
44 make test image (0), subtract image (1), smoothing (2), \n\
45 high-low filtering (3), clipping (4), fft (5), \n\
46 inverse fft (6), lowpass filter (9), highpass filter (10), \n\
48 -h | --help: this on-line help \n\
49 -i | --image: for subtract image: image filename used for subtraction \n \
50 Default: background.png. \n\
51 -p | --print: print parameters to stdout \n\
52 -o | --operation: for smoothing: set pixel equal to the mean of the \n\
53 window value (0), subtract mean from pixel (1) \n\
54 add (2), multiply (3) or divide (4)\n\
55 -t | --threshold: only for clip: threshold value to be set to zero \n\
56 -w size: window size (default: 15) \n\
57 -v | --version: version number \n\
58 filename: full image filename. Overrides stdin and stdout. \n\
59 If stdin and stdout are used, input is expected to be .png \n\
64 Image processing program for PIV images."
70 gboolean use_stdin_stdout
= FALSE
;
71 /* gboolean print_par = FALSE; */
72 gboolean fname_subtr__set
= FALSE
;
73 gboolean verbose
= FALSE
;
78 command_args (int argc
,
80 char fname
[GPIV_MAX_CHARS
],
81 GpivImageProcPar
*image_proc_par
83 /* ----------------------------------------------------------------------------
84 * Command line argument handling */
88 while (--argc
> 0 && (*++argv
)[0] == '-') {
91 * argc_next is set to 1 if the next cmd line argument has to be searched for;
92 * in case that the command line argument concerns more than one char or cmd
93 * line argument needs a parameter
95 while (argc_next
== 0 && (c
= *++argv
[0])) {
99 * Use Git version control system
102 printf ("git hash: %s\n", GIT_REV
);
104 printf ("version: %s\n", GPIVTOOLS_VERSION
);
109 printf("\n%s", argv
[0]);
110 printf("\n%s", HELP
);
111 printf("\n%s", USAGE
);
115 * (average) image filename used to subtract from input image
118 strcpy(image_proc_par
->fname
, *++argv
);
119 image_proc_par
->fname__set
= TRUE
;
123 * bitnumber for getbit
126 image_proc_par
->bit
= atoi(*++argv
);
127 image_proc_par
->bit__set
= TRUE
;
135 image_proc_par
->filter
= atoi(*++argv
);
136 image_proc_par
->filter__set
= TRUE
;
143 * whar to do with the mean value of a window: operation
146 image_proc_par
->smooth_operator
= atoi(*++argv
);
147 image_proc_par
->smooth_operator__set
= TRUE
;
163 image_proc_par
->threshold
= atoi(*++argv
);
164 image_proc_par
->threshold__set
= TRUE
;
173 image_proc_par
->window
= atoi(*++argv
);
174 image_proc_par
->window__set
= TRUE
;
183 if (strcmp("-help", *argv
) == 0) {
184 printf("\n%s", argv
[0]);
185 printf("\n%s", HELP
);
186 printf("\n%s", USAGE
);
189 } else if (strcmp("-print", *argv
) == 0) {
192 } else if (strcmp("-filter", *argv
) == 0) {
193 image_proc_par
->filter
= atoi(*++argv
);
194 image_proc_par
->filter__set
= TRUE
;
197 } else if (strcmp("-version", *argv
) == 0) {
199 printf ("git hash: %s\n", GIT_REV
);
201 printf ("version: %s\n", GPIVTOOLS_VERSION
);
205 } else if (strcmp("-operation", *argv
) == 0) {
206 image_proc_par
->smooth_operator
= atoi(*++argv
);
207 image_proc_par
->smooth_operator__set
= TRUE
;
210 } else if (strcmp("-threshold", *argv
) == 0) {
211 image_proc_par
->threshold
= atoi(*++argv
);
212 image_proc_par
->threshold__set
= TRUE
;
217 gpiv_error("%s: unknown option: %s", argv
[0], *argv
);
223 gpiv_error("%s: unknown option: %s", argv
[0], *argv
);
231 strcpy(fname
, argv
[argc
- 1]);
232 use_stdin_stdout
= FALSE
;
233 } else if (argc
== 0) {
234 use_stdin_stdout
= TRUE
;
237 gpiv_error("%s: unknown argument: %s", argv
[0], *argv
);
245 make_fname (char *fname
,
246 char *fname_parameter
,
249 /*-----------------------------------------------------------------------------
250 * generates filenames for output
253 gchar
*err_msg
= NULL
;
254 gchar
*fname_base
= NULL
;
256 if (fname
== NULL
) {
257 err_msg
= "make_fname: \"fname_in == NULL\"";
261 fname_base
= g_strdup(fname
);
262 strtok(fname_base
, ".");
263 gpiv_io_make_fname(fname_base
, GPIV_EXT_PAR
, fname_parameter
);
264 if (verbose
) printf("# Parameter file: %s\n", fname_parameter
);
266 gpiv_io_make_fname(fname_base
, GPIV_EXT_PNG_IMAGE_PROC
, fname_out
);
267 if (verbose
) printf("# Output image file: %s\n", fname_out
);
276 * Image processing functions
280 /* imgproc_invfft(GpivImagePar image_par, */
281 /* GpivImageProcPar image_proc_par, */
282 /* guint16 **img_in, */
283 /* guint16 **img_out); */
292 /* ----------------------------------------------------------------------------
293 * main routine to process images for PIV
296 FILE *fp
= NULL
, *fp_par
= NULL
;
297 gchar
*err_msg
= NULL
;
298 gchar fname_in
[GPIV_MAX_CHARS
],
299 fname_out
[GPIV_MAX_CHARS
],
300 fname_parameter
[GPIV_MAX_CHARS
];
302 GpivImage
*image
= NULL
;
304 GpivImageProcPar
*image_proc_par
= g_new0 (GpivImageProcPar
, 1);
305 GpivImageProcPar
*image_proc_par_default
= g_new0 (GpivImageProcPar
, 1);
310 * Image process parameter initialization
312 gpiv_imgproc_parameters_set (image_proc_par
, FALSE
);
313 gpiv_imgproc_default_parameters (image_proc_par_default
, TRUE
);
316 * Image processing parameter initialization
317 * Define operation type from program name, which is a symbolic link to imgproc
319 if ((c
= strstr(argv
[0], "imgproc")) != NULL
) {
320 image_proc_par
->filter
= 0;
321 image_proc_par
->filter__set
= FALSE
;
322 } else if ((c
= strstr(argv
[0], "mktestimg")) != NULL
) {
323 image_proc_par
->filter
= GPIV_IMGFI_MKTESTIMG
;
324 image_proc_par
->filter__set
= TRUE
;
325 } else if ((c
= strstr(argv
[0], "smooth")) != NULL
) {
326 image_proc_par
->filter
= GPIV_IMGFI_SMOOTH
;
327 image_proc_par
->filter__set
= TRUE
;
328 } else if ((c
= strstr(argv
[0], "hilo")) != NULL
) {
329 image_proc_par
->filter
= GPIV_IMGFI_HILO
;
330 image_proc_par
->filter__set
= TRUE
;
331 } else if ((c
= strstr(argv
[0], "clip")) != NULL
) {
332 image_proc_par
->filter
= GPIV_IMGFI_CLIP
;
333 image_proc_par
->filter__set
= TRUE
;
334 } else if ((c
= strstr(argv
[0], "fft")) != NULL
) {
335 image_proc_par
->filter
= GPIV_IMGFI_FFT
;
336 image_proc_par
->filter__set
= TRUE
;
337 /* } else if ((c = strstr(argv[0], "invfft")) != NULL) { */
338 /* image_proc_par->filter = GPIV_IMGFI_INVFFT; */
339 /* image_proc_par->filter__set = TRUE; */
340 } else if ((c
= strstr(argv
[0], "lowpass")) != NULL
) {
341 image_proc_par
->filter
= GPIV_IMGFI_LOWPASS
;
342 image_proc_par
->filter__set
= TRUE
;
343 } else if ((c
= strstr(argv
[0], "highpass")) != NULL
) {
344 image_proc_par
->filter
= GPIV_IMGFI_HIGHPASS
;
345 image_proc_par
->filter__set
= TRUE
;
346 } else if ((c
= strstr(argv
[0], "getbit")) != NULL
) {
347 image_proc_par
->filter
= GPIV_IMGFI_GETBIT
;
348 image_proc_par
->filter__set
= TRUE
;
349 } else if ((c
= strstr(argv
[0], "subtr-img")) != NULL
) {
350 image_proc_par
->filter
= GPIV_IMGFI_SUBTRACT
;
351 image_proc_par
->filter__set
= TRUE
;
353 gpiv_error("imgproc: unvalid program name or symlink");
358 * Reads command line arguments.
359 * Reads image header and image processing parametes from resource files
360 * if not overridden by the commandline options
362 command_args (argc
, argv
, fname_in
, image_proc_par
);
363 gpiv_scan_parameter (GPIV_IMGPROCPAR_KEY
, PARFILE
, image_proc_par
, verbose
);
364 gpiv_scan_resourcefiles (GPIV_IMGPROCPAR_KEY
, image_proc_par
, verbose
);
366 if (use_stdin_stdout
== FALSE
) {
369 * Generating filenames
371 make_fname(fname_in
, fname_parameter
, fname_out
);
373 printf("\n# Parameters written to: %s", fname_parameter
);
379 * Check if all image process parameters have been read
381 g_message ("main:: 0a");
383 gpiv_imgproc_check_parameters_read (image_proc_par
, image_proc_par_default
))
384 != NULL
) gpiv_warning ("%s: %s", argv
[0], err_msg
);
386 g_message ("main:: 0b");
387 if (use_stdin_stdout
== FALSE
) {
388 if ((fp_par
= fopen (fname_parameter
, "a")) == NULL
) {
389 gpiv_error ("%s: failure opening %s for input",
390 argv
[0], fname_parameter
);
392 gpiv_imgproc_print_parameters (fp_par
, image_proc_par
);
396 if (verbose
) gpiv_imgproc_print_parameters (stdout
, image_proc_par
);
401 /* g_message ("main:: 2"); */
402 if (image_proc_par
->filter
!= GPIV_IMGFI_MKTESTIMG
) {
403 if (use_stdin_stdout
) {
404 if ((image
= gpiv_read_image (stdin
)) == NULL
) {
405 gpiv_error ("%s: gpiv_fread_image_ni", argv
[0]);
409 if ((image
= gpiv_fread_image (fname_in
)) == NULL
) {
410 gpiv_error ("%s: %s", argv
[0], err_msg
);
415 /* g_message ("main:: 3"); */
417 * Here the function calls for the image processing
419 if (image_proc_par
->filter
== GPIV_IMGFI_MKTESTIMG
) {
420 GpivImagePar
*image_par
= g_new0 (GpivImagePar
, 1);
421 GpivImagePar
*image_par_default
= g_new0 (GpivImagePar
, 1);
423 gpiv_img_parameters_set (image_par
, FALSE
);
424 gpiv_img_default_parameters (image_par_default
, TRUE
);
425 gpiv_scan_parameter (GPIV_IMGPAR_KEY
, PARFILE
, image_par
, verbose
);
426 gpiv_scan_resourcefiles (GPIV_IMGPAR_KEY
, image_par
, verbose
);
427 if (gpiv_img_check_header_required_read (image_par
) != NULL
) {
428 gpiv_img_ovwrt_parameters (image_par_default
, image_par
);
430 if (verbose
) gpiv_img_print_header (stdout
, image_par
);
432 if ((image
= gpiv_imgproc_mktestimg (image_par
, image_proc_par
)) == NULL
) {
433 gpiv_error ("%s: %s", argv
[0], err_msg
);
437 } else if (image_proc_par
->filter
== GPIV_IMGFI_HILO
) {
438 if ((err_msg
= gpiv_imgproc_highlow (image
, image_proc_par
)) != NULL
) {
439 gpiv_error ("%s: %s", argv
[0], err_msg
);
443 } else if (image_proc_par
->filter
== GPIV_IMGFI_SMOOTH
) {
444 if ((err_msg
= gpiv_imgproc_smooth (image
, image_proc_par
)) != NULL
) {
445 gpiv_error ("%s: %s", argv
[0], err_msg
);
449 } else if (image_proc_par
->filter
== GPIV_IMGFI_CLIP
) {
450 if ((err_msg
= gpiv_imgproc_clip (image
, image_proc_par
)) != NULL
) {
451 gpiv_error ("%s: %s", argv
[0], err_msg
);
455 } else if (image_proc_par
->filter
== GPIV_IMGFI_FFT
) {
456 if ((err_msg
= gpiv_imgproc_fft (image
, image_proc_par
)) != NULL
) {
457 gpiv_error ("%s: %s", argv
[0], err_msg
);
460 /* } else if (image_proc_par->filter == GPIV_FI_INVFFT) { */
461 /* gpiv_imgproc_invfft (image_par, image_proc_par, img1_in, img1_out)) */
462 /* if (image_par->x_corr) { */
463 /* gpiv_imgproc_invfft(image_par, image_proc_par, img2_in, img2_out)) */
466 /* BUGFIX: Libgpiv TODO */
467 /* #ifndef USE_FFTW3 */
469 } else if (image_proc_par->filter == GPIV_IMGFI_CORR) {
471 gpiv_imgproc_correlate (image_par, image_proc_par, img1_in, img2_in,
473 != NULL) gpiv_error ("%s: %s", argv[0], err_msg);
476 } else if (image_proc_par->filter == GPIV_IMGFI_CONV) {
478 gpiv_imgproc_convolve (image_par, image_proc_par, img1_in, img2_in,
480 != NULL) gpiv_error ("%s: %s", argv[0], err_msg);
483 } else if (image_proc_par->filter == GPIV_IMGFI_LOWPASS) {
485 gpiv_imgproc_lowpass (image_par, image_proc_par, img1_in))
486 != NULL) gpiv_error ("%s: %s", argv[0], err_msg);
488 if (image_par->x_corr) {
490 gpiv_imgproc_lowpass(image_par, image_proc_par, img2_in))
491 != NULL) gpiv_error ("%s: %s", argv[0], err_msg);
497 /* #endif USE_FFTW3 */
498 } else if (image_proc_par
->filter
== GPIV_IMGFI_HIGHPASS
) {
499 if ((err_msg
= gpiv_imgproc_highpass (image
, image_proc_par
)) != NULL
) {
500 gpiv_error ("%s: %s", argv
[0], err_msg
);
504 } else if (image_proc_par
->filter
== GPIV_IMGFI_GETBIT
) {
505 if ((err_msg
= gpiv_imgproc_getbit (image
, image_proc_par
)) != NULL
) {
506 gpiv_error ("%s: %s", argv
[0], err_msg
);
510 } else if (image_proc_par
->filter
== GPIV_IMGFI_SUBTRACT
) {
511 GpivImage
*image_subtract
= NULL
;
513 if (image_proc_par
->fname__set
== FALSE
) {
514 gpiv_error ("%s: no filename set for subtract image. Use -i filename", argv
[0]);
517 if ((image_subtract
= gpiv_fread_image (image_proc_par
->fname
)) == NULL
) {
518 gpiv_error ("%s: failing gpiv_fread_image", argv
[0]);
521 if ((err_msg
= gpiv_imgproc_subtractimg(image_subtract
, image
)) != NULL
) {
522 gpiv_error ("%s: %s", argv
[0], err_msg
);
527 gpiv_error("imgproc: non-existing filter %d", image_proc_par
->filter
);
532 * And writing to output
534 if (use_stdin_stdout
== TRUE
) {
536 if ((err_msg
= gpiv_write_png_image (fp
, image
, TRUE
)) != NULL
) {
537 gpiv_error ("%s: %s\n", argv
[0], err_msg
);
542 if ((fp
= fopen (fname_out
, "wb")) == NULL
) {
543 gpiv_error ("%s: unable to open %s", argv
[0], fname_out
);
546 if ((err_msg
= gpiv_write_png_image (fp
, image
, TRUE
)) != NULL
) {
547 gpiv_error ("%s: %s\n", argv
[0], err_msg
);