9#include "tpcclibConfig.h"
25static char *info[] = {
26 "Threshold PET image file in ECAT, NIfTI, or Analyze format.",
27 "Program calculates an integral (AUC) over time frames of a dynamic image,",
28 "finds the maximal integral value of all planes, and cuts off (sets to zero)",
29 "the pixels in dynamic image which have lower or higher integral than",
30 "the specified threshold-%.",
31 "Original image file is not modified.",
33 "Usage: @P [Options] imgfile lowerthreshold upperthreshold [outputfile]",
37 " Save cutoff mask file containing pixels values 1 (between threshold",
38 " limits) and 0 (under lower or over upper threshold).",
40 " Thresholds are given as absolute values instead of percentages",
41 " of maximum in the static image; not applicable to dynamic images.",
42 " -start=<time (min)>",
43 " AUC calculation starts from given time. By default from scan start.",
45 " AUC calculation ends to given time. By default until scan end.",
47 " Program does not mind if none of pixels are thresholded;",
48 " otherwise that is considered as an error.",
51 "Lower and upper limit can be given directly as values on the command line,",
52 "or as names of files containing only the value, or value with key 'lower' or",
53 "'upper', respectively.",
55 "Example: threshold the background and cerebrospinal fluid:",
56 " @P b123dy1.v 30 100 b123thres.v",
58 "See also: img2dft, imgmask, imgqntls, imginteg, imgposv, imgslim, imgcutof",
60 "Keywords: image, threshold, mask",
79int main(
int argc,
char **argv)
81 int ai, help=0, version=0, verbose=1;
82 char petfile[FILENAME_MAX], maskfile[FILENAME_MAX], outfile[FILENAME_MAX];
83 float lowerThreshold=-1.0, upperThreshold=-1.0;
95 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
96 petfile[0]=outfile[0]=maskfile[0]=(char)0;
99 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
101 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
102 if(strncasecmp(cptr,
"MASK=", 5)==0) {
103 strlcpy(maskfile, cptr+5, FILENAME_MAX);
continue;
104 }
else if(strncasecmp(cptr,
"ABSOLUTE", 3)==0) {
105 absThreshold=1;
continue;
106 }
else if(strncasecmp(cptr,
"START=", 6)==0) {
109 if(v>0.0) tstart=60.0*v;
else tstart=0.0;
112 }
else if(strncasecmp(cptr,
"END=", 4)==0) {
115 if(v>0.0) {tstop=60.0*v;
continue;}
117 }
else if(strncasecmp(cptr,
"STOP=", 5)==0) {
120 if(v>0.0) {tstop=60.0*v;
continue;}
122 }
else if(strcasecmp(cptr,
"F")==0 || strcasecmp(cptr,
"FORCE")==0) {
123 forceMode=1;
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); ai++;}
142 fprintf(stderr,
"Error: invalid lower limit '%s'.\n", argv[ai]);
146 if(absThreshold==0) lowerThreshold*=0.01;
149 fprintf(stderr,
"Error: missing command-line argument; try %s --help\n", argv[0]);
158 fprintf(stderr,
"Error: invalid lower limit '%s'.\n", argv[ai]);
162 if(absThreshold==0) {
163 if(upperThreshold<=0.0) {
164 fprintf(stderr,
"Error: invalid upper threshold '%s'.\n", argv[ai]);
167 upperThreshold*=0.01;
171 fprintf(stderr,
"Error: missing command-line argument; try %s --help\n",
175 if(ai<argc) {
strlcpy(outfile, argv[ai], FILENAME_MAX); ai++;}
176 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
181 fprintf(stderr,
"Error: missing command-line argument; try %s --help\n", argv[0]);
184 if(lowerThreshold>upperThreshold) {
185 fprintf(stderr,
"Error: invalid threshold range.\n");
188 printf(
"Threshold range: %g - %g\n", 100.*lowerThreshold, 100.*upperThreshold);
190 printf(
"Threshold range: %g - %g\n", lowerThreshold, upperThreshold);
194 if(lowerThreshold==upperThreshold) {
197 if(absThreshold==0) {
198 f=0.001*lowerThreshold; lowerThreshold-=f; upperThreshold+=f;
199 if(verbose>1) printf(
"Threshold range: %g - %g\n", 100.*lowerThreshold, 100.*upperThreshold);
201 f=0.001*lowerThreshold;
if(f>0.1) f=0.1;
202 lowerThreshold-=f; upperThreshold+=f;
203 if(verbose>1) printf(
"Threshold range: %g - %g\n", lowerThreshold, upperThreshold);
204 if(verbose>10) printf(
"Threshold range: %.2f - %.2f\n", lowerThreshold, upperThreshold);
212 printf(
"petfile := %s\n", petfile);
213 if(outfile[0]) printf(
"outfile := %s\n", outfile);
214 if(maskfile[0]) printf(
"maskfile := %s\n", maskfile);
215 if(absThreshold==0) {
216 printf(
"upper_threshold_percentage := %g\n", 100.*upperThreshold);
217 printf(
"lower_threshold_percentage := %g\n", 100.*lowerThreshold);
219 printf(
"upper_threshold := %g\n", upperThreshold);
220 printf(
"lower_threshold := %g\n", lowerThreshold);
222 if(tstart>=0) printf(
"start_time := %g\n", tstart/60.0);
223 if(tstop>=0) printf(
"end_time := %g\n", tstop/60.0);
231 if(verbose>0) printf(
"reading %s\n", petfile);
234 fprintf(stderr,
"Error: %s\n", img.
statmsg);
235 if(verbose>1) printf(
"ret=%d\n", ret);
239 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
241 if(absThreshold!=0 && img.
dimt>1) {
242 fprintf(stderr,
"Error: do not use absolute thresholds for dynamic image.\n");
247 if(tstart>0.0 || tstop>0.0) {
248 fprintf(stderr,
"Error: image does not contain frame times.\n");
252 fprintf(stderr,
"Warning: image does not contain frame times.\n");
257 fprintf(stderr,
"Error: cannot correct sinogram counts.\n");
258 if(verbose>1) printf(
"ret=%d\n", ret);
267 if(verbose>0) fprintf(stdout,
"calculating integral image\n");
269 if(tstart<=0.0 && tstop<=0.0) {
275 if(tstop<0.01 || tstop>img.
end[img.
dimt-1]) tstop=img.
end[img.
dimt-1];
277 printf(
"tstart := %g\n", tstart);
278 printf(
"tstop := %g\n", tstop);
283 fprintf(stderr,
"Error: cannot integrate.\n");
284 if(verbose>1) printf(
"ret=%d\n", ret);
292 if(verbose>2) fprintf(stdout,
"static image\n");
294 if(
imgDup(&img, &sum)!=0) {
295 fprintf(stderr,
"Error: cannot duplicate static image.\n");
303 if(verbose>0) fprintf(stdout,
"thresholding\n");
305 if(absThreshold==0) {
307 if(verbose>1) printf(
"searching maximum pixel value...\n");
311 fprintf(stderr,
"Error: cannot find maximum.\n");
312 if(verbose>1) printf(
"ret=%d\n", ret);
316 if(verbose>1) printf(
"max := %g\n", max);
317 lowerThreshold*=max; upperThreshold*=max;
319 printf(
"lowerThresholdValue := %g\nupperThresholdValue:=%g\n",
320 lowerThreshold, upperThreshold);
327 fprintf(stderr,
"Error: cannot threshold.\n");
328 if(verbose>1) printf(
"ret=%d\n", ret);
338 long long nr, total_nr=0, thrs_nr;
339 if(verbose>1 && mask.
dimz>1) printf(
"Nr of retained pixels:\n");
340 for(zi=0; zi<mask.
dimz; zi++) {
342 for(yi=0; yi<mask.
dimy; yi++)
343 for(xi=0; xi<mask.
dimx; xi++)
344 if(fabs(mask.
m[zi][yi][xi][0])>0.01) nr++;
345 if(verbose>1 && mask.
dimz>1) printf(
" plane %d: %lld\n", zi+1, nr);
348 if(verbose>0 || !outfile[0]) printf(
"retained_pixels := %lld\n", total_nr);
350 if(verbose>0 || !outfile[0]) printf(
"thresholded_pixels := %lld\n", thrs_nr);
354 fprintf(stderr,
"Warning: no pixels thresholded.\n");
356 fprintf(stderr,
"Error: no pixels thresholded.\n");
365 if(verbose>1) fprintf(stdout,
"writing %s\n", maskfile);
368 fprintf(stderr,
"Error: %s\n", img.
statmsg);
369 if(verbose>1) printf(
"ret=%d\n", ret);
373 if(verbose>0) printf(
"Written %s\n", maskfile);
378 if(verbose>0) printf(
"done.\n");
386 fprintf(stderr,
"Error: cannot threshold by the mask.\n");
387 if(verbose>1) printf(
"ret=%d\n", ret);
400 fprintf(stderr,
"Error: cannot correct sinogram counts.\n");
403 if(verbose>1) fprintf(stdout,
"writing %s\n", outfile);
405 fprintf(stderr,
"Error: %s\n", img.
statmsg);
406 if(verbose>1) printf(
"ret=%d\n", ret);
410 if(verbose>0) printf(
"Written %s\n", outfile);
int atof_with_check(char *double_as_string, double *result_value)
char * iftReadValue(char *filename, char *keystr, int verbose)
int imgExistentTimes(IMG *img)
unsigned long long imgNaNs(IMG *img, int fix)
int imgDup(IMG *img1, IMG *img2)
void imgEmpty(IMG *image)
int imgFrameIntegral(IMG *img, int first, int last, IMG *iimg, int verbose)
int imgRawCountsPerTime(IMG *img, int operation)
int imgRead(const char *fname, IMG *img)
int imgWrite(const char *fname, IMG *img)
int imgMax(IMG *img, float *maxvalue)
int imgThresholdMask(IMG *img, float minValue, float maxValue, IMG *timg)
int imgThresholdByMask(IMG *img, IMG *templt, float thrValue)
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)
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.
int imgTimeIntegral(IMG *img, float t1, float t2, IMG *iimg, int calc_mode, char *status, int verbose)