8#include "tpcclibConfig.h"
24static char *info[] = {
25 "Applying Gaussian 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 SDs of Gaussian filter for x,y- and z-dimensions, or only",
28 "to the x,y-planes by giving the SD only for x,y-dimensions.",
29 "SDs are assumed to be in pixels, if units are not given.",
32 "Usage: @P [Options] imgfile outputfile SDxy [SDz]",
36 " FWHM value(s) are given instead of SDs.",
37 " -method=<<FIR>|<AM>>",
38 " Specify the Gaussian filtering method; default is the finite impulse",
39 " response method (FIR); Alvarez-Mazorra approximate Gaussian image",
40 " filtering method (AM) is less accurate but may be faster.",
42 " Default tolerance can be changed with this option.",
44 " More steps provides better accuracy but longer execution time;",
45 " default is 4. Applies only to AM method.",
46 " -xysize=<pixel size>",
47 " Set image pixel x,y size (mm), if missing or wrong in image data.",
48 " -zsize=<pixel size>",
49 " Set image pixel z size (mm), if missing or wrong in image data.",
52 "Example #1: 3D filtering with Gaussian SDs given in mm",
53 " @P s5998dy1.v s5998dy1_filt.v 3.4mm 4.1mm",
55 "Example #2: 2D filtering with Gaussian SDs given in pixels",
56 " @P s5998dy1.v s5998dy1_filt.v 4pxl",
58 "Example #3: 3D filtering with FWHMs given in mm",
59 " @P -fwhm s5998dy1.v s5998dy1_filt.v 8mm 9.66mm",
61 "See also: imgdysmo, imgfsegm, imgthrs, imgbkgrm, fvar4img, imgprofi",
63 "Keywords: image, smoothing, gaussian, FWHM",
82int main(
int argc,
char **argv)
84 int ai, help=0, version=0, verbose=1;
85 char petfile[FILENAME_MAX], outfile[FILENAME_MAX];
86 int gaussian_method=1;
87 double xsize=nan(
""), ysize=nan(
""), zsize=nan(
"");
89 double SDx=nan(
""), SDy=nan(
""), SDz=nan(
"");
90 int SDxUnit, SDyUnit, SDzUnit;
91 double tolerance=1.0E-04;
98 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
99 petfile[0]=outfile[0]=(char)0;
100 SDxUnit=SDyUnit=SDzUnit=0;
102 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
104 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
105 if(strncasecmp(cptr,
"METHOD=", 7)==0 && strlen(cptr)>7) {
107 if(strcasecmp(cptr,
"FIR")==0) {gaussian_method=1;
continue;}
108 if(strcasecmp(cptr,
"AM")==0) {gaussian_method=2;
continue;}
109 if(strcasecmp(cptr,
"EBOX")==0) {gaussian_method=3;
continue;}
110 }
else if(strcasecmp(cptr,
"SD")==0) {
112 }
else if(strcasecmp(cptr,
"FWHM")==0) {
114 }
else if(strncasecmp(cptr,
"STEPS=", 6)==0) {
115 stepNr=atoi(cptr+6);
if(stepNr>0)
continue;
116 }
else if(strncasecmp(cptr,
"XYSIZE=", 7)==0) {
117 xsize=ysize=
atof_dpi(cptr+7);
if(xsize>0.0)
continue;
118 }
else if(strncasecmp(cptr,
"ZSIZE=", 6)==0) {
119 zsize=
atof_dpi(cptr+6);
if(zsize>0.0)
continue;
120 }
else if(strncasecmp(cptr,
"TOL=", 4)==0) {
121 tolerance=
atof_dpi(cptr+4);
if(tolerance>0.0)
continue;
122 }
else if(strncasecmp(cptr,
"TOLERANCE=", 10)==0) {
123 tolerance=
atof_dpi(cptr+10);
if(tolerance>0.0)
continue;
125 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
130 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
135 if(ai<argc) {
strlcpy(petfile, argv[ai++], FILENAME_MAX);}
137 strlcpy(outfile, argv[ai++], FILENAME_MAX);
140 fprintf(stderr,
"Error: invalid output file name '%s'\n", outfile);
147 if(ret==0 && v>=0.0) {
150 if(
strcasestr(argv[ai],
"pxl")!=NULL) SDxUnit=SDyUnit=0;
151 if(
strcasestr(argv[ai],
"mm")!=NULL) SDxUnit=SDyUnit=1;
152 if(
strcasestr(argv[ai],
"cm")!=NULL) SDxUnit=SDyUnit=2;
155 fprintf(stderr,
"Error: invalid filter S.D.\n");
162 if(ret==0 && v>=0.0) {
165 if(
strcasestr(argv[ai],
"pxl")!=NULL) SDzUnit=0;
166 if(
strcasestr(argv[ai],
"mm")!=NULL) SDzUnit=1;
167 if(
strcasestr(argv[ai],
"cm")!=NULL) SDzUnit=2;
170 fprintf(stderr,
"Error: invalid filter S.D.\n");
174 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
177 if(!outfile[0] || !(SDx>=0.0)) {
178 fprintf(stderr,
"Error: missing command-line argument; try %s --help\n", argv[0]);
181 if(strcasecmp(outfile, petfile)==0) {
182 fprintf(stderr,
"Error: check the output file name.\n");
185 if(!(SDx>0.0) && !(SDy>0.0) && !(SDz>0.0)) {
186 fprintf(stderr,
"Warning: with given SD no filtering is applied.\n");
192 if(!useSD) {SDx/=2.355; SDy/=2.355;
if(SDz>0.0) SDz/=2.355;}
196 printf(
"petfile := %s\n", petfile);
197 printf(
"outfile := %s\n", outfile);
198 if(!isnan(xsize)) printf(
"pixel_xysize := %g mm\n", xsize);
199 if(!isnan(zsize)) printf(
"pixel_zsize := %g mm\n", zsize);
200 printf(
"gaussian_method := %d\n", gaussian_method);
201 printf(
"stepNr := %d\n", stepNr);
210 if(verbose>0) printf(
"reading %s\n", petfile);
212 int ret=
imgRead(petfile, &img);
214 fprintf(stderr,
"Error: %s\n", img.
statmsg);
215 if(verbose>1) printf(
"ret=%d\n", ret);
220 fprintf(stderr,
"Error: %s is not an image.\n", petfile);
224 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
228 if(xsize>0.0) img.
sizex=xsize;
229 if(ysize>0.0) img.
sizey=ysize;
230 if(zsize>0.0) img.
sizez=zsize;
231 if(verbose>1) printf(
"image_xyz_sizes := %g %g %g\n", img.
sizex, img.
sizey, img.
sizez);
232 if(!isnan(xsize) || !isnan(ysize)) {
234 fprintf(stderr,
"Warning: different pixel x and y size.\n");
239 printf(
"image_xyzf_dimensions := %d %d %d %d\n", img.
dimx, img.
dimy, img.
dimz, img.
dimt);
242 if(SDz>0 && img.
dimz<4) {
243 fprintf(stderr,
"Error: invalid Z dimension for 3D filtering.\n");
246 if((SDx>0 && img.
dimx<4) || (SDy>0 && img.
dimy<4)) {
247 fprintf(stderr,
"Error: invalid x,y dimensions for filtering.\n");
255 if((SDxUnit!=0 && !(img.
sizex>0.0)) || (SDyUnit!=0 && !(img.
sizey>0.0)) ||
256 (SDzUnit!=0 && !(img.
sizez>0.0)))
258 fprintf(stderr,
"Error: unknown image pixel size.\n");
262 if(SDxUnit==2) {SDx*=10.0; SDxUnit=1;}
263 if(SDyUnit==2) {SDy*=10.0; SDyUnit=1;}
264 if(SDzUnit==2) {SDz*=10.0; SDzUnit=1;}
266 if(SDxUnit==1) {SDx/=img.
sizex; SDxUnit=0;}
267 if(SDyUnit==1) {SDy/=img.
sizey; SDyUnit=0;}
268 if(SDzUnit==1) {SDz/=img.
sizez; SDzUnit=0;}
270 printf(
"gaussian_sdx := %g pxl\n", SDx);
271 printf(
"gaussian_sdy := %g pxl\n", SDy);
272 printf(
"gaussian_sdz := %g pxl\n", SDz);
280 if(gaussian_method==1) {
281 if(verbose>0) fprintf(stdout,
"Gaussian FIR filtering\n");
283 }
else if(gaussian_method==2) {
284 if(verbose>0) fprintf(stdout,
"Gaussian AM filtering\n");
287 if(verbose>0) fprintf(stdout,
"Gaussian Ebox filtering\n");
291 fprintf(stderr,
"Error: cannot filter the image.\n");
292 if(verbose>1) fprintf(stderr,
"ret := %d\n", ret);
300 if(verbose>2) fprintf(stdout,
"writing %s\n", outfile);
302 fprintf(stderr,
"Error: %s\n", img.
statmsg);
306 if(verbose>0) printf(
"Written %s\n", outfile);
int atof_with_check(char *double_as_string, double *result_value)
double atof_dpi(char *str)
unsigned long long imgNaNs(IMG *img, int fix)
void imgEmpty(IMG *image)
int imgRead(const char *fname, IMG *img)
int imgWrite(const char *fname, IMG *img)
int imgGaussianEBoxFilter(IMG *img, float xsd, float ysd, float zsd, int passNr, int verbose)
int imgGaussianFIRFilter(IMG *img, float xsd, float ysd, float zsd, double tolerance, int verbose)
int imgGaussianAMFilter(IMG *img, float xsd, float ysd, float zsd, int passNr, double tolerance, int verbose)
Header file for libtpcimgio.
Header file for libtpcimgp.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
char * strcasestr(const char *haystack, const char *needle)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Header file for libtpcmodext.