9#include "tpcclibConfig.h"
24static char *info[] = {
25 "Trial program to find the locations of arteries in dynamic PET image.",
27 "Usage: @P [Options] imgfile template",
31 " Pixel peak values are saved as image.",
33 " Pixel peak times (1/peaktime) are saved as image.",
35 " Pixel peak value/time ratios are saved as image.",
36 " -lthr=<percentage value>",
37 " Lower threshold value as percentage of maximum.",
38 " -uthr=<percentage value>",
39 " Upper threshold value as percentage of maximum.",
40 " -maxpeaktime=<time in sec>",
41 " Pixel TAC values after given time are ignored when finding peak.",
42 " -minpeaktime=<time in sec>",
43 " Pixel TAC values before given time are ignored when finding peak.",
46 "See also: eabaort, imgprofi, imgthrs, imgfsegm, imgdysmo, imgmax, img2tif",
48 "Keywords: image, input, blood, aorta",
67int main(
int argc,
char **argv)
69 int ai, help=0, version=0, verbose=1;
70 int ret, fi, fj, zi, yi, xi;
72 char *cptr, imgfile[FILENAME_MAX];
73 char peakfile[FILENAME_MAX], timefile[FILENAME_MAX],
74 ratiofile[FILENAME_MAX], templfile[FILENAME_MAX];
75 float lower_threshold=0.0, upper_threshold=1.0;
76 float max_peak_time=0.0;
77 float min_peak_time=0.0;
78 float local_mean, best_mean, f1, f2, best_two_mean,
79 peak_time, peak_value_per_time;
81 IMG img, template_img, peak_img, time_img, ratio_img;
87 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
89 peakfile[0]=timefile[0]=ratiofile[0]=templfile[0]=(char)0;
91 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
92 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
94 if(strncasecmp(cptr,
"PEAK=", 5)==0) {
95 strlcpy(peakfile, cptr+5, FILENAME_MAX);
continue;
96 }
else if(strncasecmp(cptr,
"TIME=", 5)==0) {
97 strlcpy(timefile, cptr+5, FILENAME_MAX);
continue;
98 }
else if(strncasecmp(cptr,
"RATIO=", 6)==0) {
99 strlcpy(ratiofile, cptr+6, FILENAME_MAX);
continue;
100 }
else if(strncasecmp(cptr,
"LTHR=", 5)==0) {
103 if(v>=0.0 && v<100.0) {lower_threshold=0.01*v;
continue;}
105 }
else if(strncasecmp(cptr,
"UTHR=", 5)==0) {
108 if(v>0.0 && v<=100.0) {upper_threshold=0.01*v;
continue;}
110 }
else if(strncasecmp(cptr,
"MAXPEAKTIME=", 12)==0) {
113 if(v>0.0) {max_peak_time=v;
continue;}
115 }
else if(strncasecmp(cptr,
"MINPEAKTIME=", 12)==0) {
118 if(v>0.0) {min_peak_time=v;
continue;}
121 fprintf(stderr,
"Error: invalid option '%s'\n", argv[ai]);
126 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
131 if(ai<argc) {
strlcpy(imgfile, argv[ai], FILENAME_MAX); ai++;}
132 if(ai<argc) {
strlcpy(templfile, argv[ai], FILENAME_MAX); ai++;}
133 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
137 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
140 if(lower_threshold>=upper_threshold) {
141 fprintf(stderr,
"Error: invalid thresholds.\n");
144 if(strcasecmp(imgfile, templfile)==0) {
145 fprintf(stderr,
"Error: check the output filename.\n");
151 printf(
"imgfile := %s\n", imgfile);
152 printf(
"peakfile := %s\n", peakfile);
153 printf(
"timefile := %s\n", timefile);
154 printf(
"ratiofile := %s\n", ratiofile);
155 printf(
"templfile := %s\n", templfile);
156 printf(
"lower_threshold := %g\n", lower_threshold);
157 printf(
"upper_threshold := %g\n", upper_threshold);
158 printf(
"max_peak_time := %g s\n", max_peak_time);
159 printf(
"min_peak_time := %g s\n", min_peak_time);
166 if(verbose>0) fprintf(stdout,
"reading dynamic image %s\n", imgfile);
170 fprintf(stderr,
"Error: %s\n", img.
statmsg);
171 if(verbose>1) printf(
"ret := %d\n", ret);
176 fprintf(stderr,
"Error: %s is not an image.\n", imgfile);
180 fprintf(stderr,
"Error: %s contains only %d time frame(s).\n", imgfile, img.
dimt);
183 if(verbose>0) fprintf(stdout,
" image contains %d frames and %d planes.\n", img.
dimt, img.
dimz);
185 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
191 if(verbose>1) fprintf(stdout,
"allocating memory for parametric images\n");
194 if(ret==0 && peakfile[0])
196 if(ret==0 && timefile[0])
201 fprintf(stderr,
"Error: out of memory.\n");
207 if(timefile[0]) time_img.
unit=IMGUNIT_UNITLESS;
208 ratio_img.
unit=IMGUNIT_UNITLESS;
210 ratio_img.
start[0]=0.0; ratio_img.
end[0]=1.0;
216 printf(
"%lld pixel(s) filtered out as outliers from dynamic image.\n", n);
223 if(verbose>1 || (verbose>0 && (lower_threshold>0.0 || upper_threshold<1.0)))
224 fprintf(stdout,
"thresholding with limits %g-%g%% of AUC max.\n",
225 100.*lower_threshold, 100.*upper_threshold);
228 &template_img, &n, &m);
230 fprintf(stderr,
"Warning: error %d in thresholding.\n", ret);
231 else if(verbose>0 && (n>0 || m>0)) {
232 fprintf(stdout,
" %lld pixels below threshold\n", n);
233 fprintf(stdout,
" %lld pixels above threshold\n", m);
243 if(verbose>0) fprintf(stdout,
"computing pixel-by-pixel\n");
244 for(zi=0; zi<img.
dimz; zi++) {
245 if(img.
dimz>1 && verbose==1) {fprintf(stdout,
"."); fflush(stdout);}
246 else if(verbose>1) printf(
"processing plane %d\n", 1+zi);
247 for(yi=0; yi<img.
dimy; yi++) {
248 for(xi=0; xi<img.
dimx; xi++) {
250 ratio_img.
m[zi][yi][xi][0]=0.0;
251 if(template_img.
m[zi][yi][xi][0]<=0.0)
continue;
254 best_mean=0.0; best_frame=0;
255 for(fj=3; fj<img.
dimt; fj++) {
256 if(img.
mid[fj-2]<min_peak_time)
continue;
258 for(fi=fj-3; fi<=fj; fi++) {
259 local_mean+=img.
m[zi][yi][xi][fi];
262 if(local_mean>best_mean) {
263 best_mean=local_mean;
273 f1=img.
m[zi][yi][xi][best_frame]+img.
m[zi][yi][xi][best_frame+1];
274 f2=img.
m[zi][yi][xi][best_frame+1]+img.
m[zi][yi][xi][best_frame+2];
275 if(f1>f2) best_two_mean=f1;
else best_two_mean=f2;
278 if(peakfile[0]) peak_img.
m[zi][yi][xi][0]=best_two_mean;
282 for(fi=best_frame; fi<=best_frame+3; fi++)
283 peak_time+=img.
m[zi][yi][xi][fi]*img.
mid[fi];
284 if(best_mean>0.0) peak_time/=(4.0*best_mean);
else peak_time=0.0;
288 if(peak_time>0) time_img.
m[zi][yi][xi][0]=1.0/peak_time;
289 else time_img.
m[zi][yi][xi][0]=0.0;
294 if(max_peak_time>0.0 && peak_time>max_peak_time) {
295 template_img.
m[zi][yi][xi][0]=0;
296 if(peakfile[0]) peak_img.
m[zi][yi][xi][0]=0.0;
297 if(timefile[0]) time_img.
m[zi][yi][xi][0]=0.0;
302 if(peak_time>0.0 && best_two_mean>0.0) {
303 peak_value_per_time=(best_two_mean)/(peak_time);
304 }
else peak_value_per_time=0.0;
306 ratio_img.
m[zi][yi][xi][0]=peak_value_per_time;
310 if(verbose==1) fprintf(stdout,
"\ndone.\n");
314 &template_img, &n, &m);
316 fprintf(stderr,
"Warning: error %d in thresholding.\n", ret);
317 else if(verbose>0 && (n>0 || m>0)) {
318 fprintf(stdout,
" %lld pixels below threshold\n", n);
319 fprintf(stdout,
" %lld pixels above threshold\n", m);
333 if(verbose>1) printf(
"writing result image(s)\n");
335 ret=
imgWrite(templfile, &template_img);
337 fprintf(stderr,
"Error: %s\n", template_img.
statmsg);
342 if(verbose>0) fprintf(stdout,
"Template image %s saved.\n", templfile);
347 fprintf(stderr,
"Error: %s\n", peak_img.
statmsg);
352 if(verbose>0) fprintf(stdout,
"Peak value image %s saved.\n", peakfile);
357 fprintf(stderr,
"Error: %s\n", time_img.
statmsg);
362 if(verbose>0) fprintf(stdout,
"Peak time image %s saved.\n", timefile);
365 ret=
imgWrite(ratiofile, &ratio_img);
367 fprintf(stderr,
"Error: %s\n", ratio_img.
statmsg);
372 if(verbose>0) fprintf(stdout,
"Peak value/time image %s saved.\n", ratiofile);
378 if(verbose>0) printf(
"done.\n");
int atof_with_check(char *double_as_string, double *result_value)
unsigned long long imgNaNs(IMG *img, int fix)
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
void imgEmpty(IMG *image)
int imgRead(const char *fname, IMG *img)
int imgWrite(const char *fname, IMG *img)
int imgOutlierFilter(IMG *img, float limit)
int imgThresholdingLowHigh(IMG *img, float lower_threshold_level, float upper_threshold_level, IMG *timg, long long *lower_thr_nr, long long *upper_thr_nr)
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)