TPCCLIB
Loading...
Searching...
No Matches
imgfiltl.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "tpcclibConfig.h"
9/*****************************************************************************/
10#include <stdio.h>
11#include <stdlib.h>
12#include <math.h>
13#include <string.h>
14#include <unistd.h>
15#include <time.h>
16/*****************************************************************************/
17#include "libtpcmisc.h"
18#include "libtpcimgio.h"
19#include "libtpcimgp.h"
20#include "libtpcmodext.h"
21/*****************************************************************************/
22
23/*****************************************************************************/
24static char *info[] = {
25 "Applying mean filter for a static or dynamic PET image in ECAT, NIfTI,",
26 "or Analyze format. Filtering can be applied to x,y,z-volume (3D) by",
27 "specifying the number of adjacent pixels for x,y- and z-dimensions, or only",
28 "to the x,y-planes by giving the number only for x,y-dimensions.",
29 "Only zero and odd numbers 3, 5, ... are accepted",
30 " ",
31 "Usage: @P [Options] imgfile outputfile Nxy [Nz]",
32 " ",
33 "Options:",
34 " -nonegatives",
35 " Negative voxel values are set to 0.",
36 " -difference",
37 " Filtered image is subtracted from original image.",
38 " -stdoptions", // List standard options like --help, -v, etc
39 " ",
40 "See also: imgfiltg, imgdysmo, imgfsegm, imgthrs, imgbkgrm, fvar4img",
41 " ",
42 "Keywords: image, smoothing",
43 0};
44/*****************************************************************************/
45
46/*****************************************************************************/
47/* Turn on the globbing of the command line, since it is disabled by default in
48 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
49 In Unix&Linux wildcard command line processing is enabled by default. */
50/*
51#undef _CRT_glob
52#define _CRT_glob -1
53*/
54int _dowildcard = -1;
55/*****************************************************************************/
56
57/*****************************************************************************/
61int main(int argc, char **argv)
62{
63 int ai, help=0, version=0, verbose=1;
64 char petfile[FILENAME_MAX], outfile[FILENAME_MAX];
65 int Nx=0, Ny=0, Nz=0;
66 int leaveNegat=1;
67 int subtract=0;
68
69
70 /*
71 * Get arguments
72 */
73 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
74 petfile[0]=outfile[0]=(char)0;
75 /* Get options */
76 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
77 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
78 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
79 if(strncasecmp(cptr, "NONEGATIVES", 1)==0) {
80 leaveNegat=0; continue;
81 } else if(strncasecmp(cptr, "DIFFERENCE", 3)==0) {
82 subtract=1; continue;
83 }
84 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
85 return(1);
86 } else break;
87
88 /* Print help or version? */
89 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
90 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
91 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
92
93 /* Process other arguments, starting from the first non-option */
94 if(ai<argc) {strlcpy(petfile, argv[ai++], FILENAME_MAX);}
95 if(ai<argc) {
96 strlcpy(outfile, argv[ai++], FILENAME_MAX);
97 double v; // check that user did not forget file name
98 if(atof_with_check(outfile, &v)==0) {
99 fprintf(stderr, "Error: invalid output file name '%s'\n", outfile);
100 return(1);
101 }
102 }
103 if(ai<argc) {
104 Nx=Ny=atoi(argv[ai]);
105 if(Nx>0 || strcmp(argv[ai], "0")==0) {
106 ai++;
107 } else {
108 fprintf(stderr, "Error: invalid Nxy\n");
109 return(1);
110 }
111 }
112 if(ai<argc) {
113 Nz=atoi(argv[ai]);
114 if(Nz>0 || strcmp(argv[ai], "0")==0) {
115 ai++;
116 } else {
117 fprintf(stderr, "Error: invalid Nz\n");
118 return(1);
119 }
120 }
121 if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
122
123 /* Did we get all the information that we need? */
124 if(!outfile[0]) {
125 fprintf(stderr, "Error: missing command-line argument; try %s --help\n", argv[0]);
126 return(1);
127 }
128 if(strcasecmp(outfile, petfile)==0) {
129 fprintf(stderr, "Error: check the output file name.\n");
130 return(1);
131 }
132 if(!(Nx>0) && !(Ny>0) && !(Nz>0)) {
133 fprintf(stderr, "Error: with given parameters no filtering is applied.\n");
134 return(1);
135 }
136 if((Nx>0 && Nx<3) || (Ny>0 && Ny<3) || (Nz>0 && Nz<3)) {
137 fprintf(stderr, "Error: invalid pixel number.\n");
138 return(1);
139 }
140 if((Nx>0 && Nx%2==0) || (Ny>0 && Ny%2==0) || (Nz>0 && Nz%2==0)) {
141 fprintf(stderr, "Error: pixel numbers must be odd.\n");
142 return(1);
143 }
144
145
146 /* In verbose mode print arguments and options */
147 if(verbose>1) {
148 printf("petfile := %s\n", petfile);
149 printf("outfile := %s\n", outfile);
150 printf("Nx := %d\n", Nx);
151 printf("Ny := %d\n", Ny);
152 printf("Nz := %d\n", Nz);
153 printf("leaveNegat := %d\n", leaveNegat);
154 fflush(stdout);
155 }
156
157
158 /*
159 * Read the contents of the PET file to img data structure
160 */
161 IMG img; imgInit(&img);
162 if(verbose>0) printf("reading %s\n", petfile);
163 {
164 int ret=imgRead(petfile, &img);
165 if(ret) {
166 fprintf(stderr, "Error: %s\n", img.statmsg);
167 if(verbose>1) printf("ret=%d\n", ret);
168 imgEmpty(&img); return(2);
169 }
170 /* Check if PET data is raw or image */
171 if(img.type!=IMG_TYPE_IMAGE) {
172 fprintf(stderr, "Error: %s is not an image.\n", petfile);
173 imgEmpty(&img); return(2);
174 }
175 if(imgNaNs(&img, 1)>0)
176 if(verbose>0) fprintf(stderr, "Warning: missing pixel values.\n");
177 }
178 if(verbose>1)
179 printf("image_xyzf_dimensions := %d %d %d %d\n", img.dimx, img.dimy, img.dimz, img.dimt);
180
181 /* Check that image size in smoothing dimension is at least 4 */
182 if(Nz>0 && img.dimz<=Nz) {
183 fprintf(stderr, "Error: invalid Z dimension for 3D filtering.\n");
184 imgEmpty(&img); return(3);
185 }
186 if((Nx>0 && img.dimx<=Nx) || (Ny>0 && img.dimy<=Ny)) {
187 fprintf(stderr, "Error: invalid x,y dimensions for filtering.\n");
188 imgEmpty(&img); return(3);
189 }
190
191 /*
192 * Make backup image, in case subtraction was requested
193 */
194 IMG orig; imgInit(&orig);
195 if(subtract!=0) {
196 int ret=imgDup(&img, &orig);
197 if(ret) {
198 fprintf(stderr, "Error: cannot setup IMG data.\n");
199 if(verbose>1) fprintf(stderr, "ret := %d\n", ret);
200 imgEmpty(&img); return(6);
201 }
202 }
203
204
205 /*
206 * Smoothing
207 */
208 int ret=imgMeanFilter(&img, Nx, Ny, Nz, 0, verbose-2);
209 if(ret!=0) {
210 fprintf(stderr, "Error: cannot filter the image.\n");
211 if(verbose>1) fprintf(stderr, "ret := %d\n", ret);
212 imgEmpty(&img); imgEmpty(&orig); return(7);
213 }
214
215
216 /*
217 * Subtract filtered image from original image, if requested
218 */
219 if(subtract!=0) {
220 for(int z=0; z<img.dimz; z++)
221 for(int y=0; y<img.dimy; y++)
222 for(int x=0; x<img.dimx; x++)
223 for(int t=0; t<img.dimt; t++)
224 img.m[z][y][x][t]=orig.m[z][y][x][t]-img.m[z][y][x][t];
225 imgEmpty(&orig);
226 }
227
228 /* Set negative pixel values to zero, if required */
229 if(leaveNegat==0) {
230 if(verbose>1) printf("setting negative pixel values to zero\n");
231 imgCutoff(&img, 0.0, 1);
232 }
233
234
235 /*
236 * Save filtered image
237 */
238 if(verbose>2) fprintf(stdout, "writing %s\n", outfile);
239 if(imgWrite(outfile, &img)) {
240 fprintf(stderr, "Error: %s\n", img.statmsg);
241 imgEmpty(&img);
242 return(11);
243 }
244 if(verbose>0) printf("Written %s\n", outfile);
245 imgEmpty(&img);
246
247 return(0);
248}
249/*****************************************************************************/
250
251/*****************************************************************************/
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
unsigned long long imgNaNs(IMG *img, int fix)
Definition img.c:658
int imgDup(IMG *img1, IMG *img2)
Definition img.c:304
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgRead(const char *fname, IMG *img)
Definition imgfile.c:26
int imgWrite(const char *fname, IMG *img)
Definition imgfile.c:136
int imgMeanFilter(IMG *img, int xn, int yn, int zn, int tn, int verbose)
Definition imgfilter.c:624
void imgCutoff(IMG *image, float cutoff, int mode)
Header file for libtpcimgio.
#define IMG_TYPE_IMAGE
Header file for libtpcimgp.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:213
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:383
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:158
Header file for libtpcmodext.
unsigned short int dimx
char type
float **** m
unsigned short int dimt
unsigned short int dimz
unsigned short int dimy
const char * statmsg