TPCCLIB
Loading...
Searching...
No Matches
imgmaxp.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//#include <float.h>
17/*****************************************************************************/
18#include "libtpcmisc.h"
19#include "libtpcimgio.h"
20#include "libtpcimgp.h"
21/*****************************************************************************/
22
23/*****************************************************************************/
24/* Local functions */
25int imgRangeWeightedMax(IMG *img, IMG_RANGE *r, IMG_PIXEL *maxp);
26/*****************************************************************************/
27
28/*****************************************************************************/
29static char *info[] = {
30 "Find the position of maximum pixel value in PET image in ECAT 6.3 or 7.x,",
31 "NIfTI-1, or Analyze 7.5 format.",
32 "Position of the found pixel is written in specified file or stdout as its",
33 "coordinates (x,y,z,f; 1..dimension).",
34 " ",
35 "Usage: @P [Options] imgfile [pxlfile]",
36 " ",
37 "Options:",
38 " -min",
39 " Find minimum instead of maximum.",
40 " -vrdfile=<filename>",
41 " Volume range definition (vrd) file is an ASCII text file, which",
42 " contains pixel coordinates (x y z f; 1..dimension) of the two opposite",
43 " corners of the image space to be searched for; for example:",
44 " corner1 := 63 57 26 1",
45 " corner2 := 84 71 44 17",
46 " -wmax",
47 " Find pixel value weighted position inside the image.",
48 " -stdoptions", // List standard options like --help, -v, etc
49 " ",
50 "See also: imgmax, imgpeak, imginteg, pxl2tac, pxl2mask, imgprofi, imgmask",
51 " ",
52 "Keywords: image, pixel, max, min",
53 0};
54/*****************************************************************************/
55
56/*****************************************************************************/
57/* Turn on the globbing of the command line, since it is disabled by default in
58 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
59 In Unix&Linux wildcard command line processing is enabled by default. */
60/*
61#undef _CRT_glob
62#define _CRT_glob -1
63*/
64int _dowildcard = -1;
65/*****************************************************************************/
66
67/*****************************************************************************/
71int main(int argc, char **argv)
72{
73 int ai, help=0, version=0, verbose=1;
74 int ret;
75 int find_what=0; // 0=max, 1=min, 2=wmax
76 char imgfile[FILENAME_MAX], pxlfile[FILENAME_MAX], vrdfile[FILENAME_MAX];
77 char *cptr=NULL;
78
79
80 /*
81 * Get arguments
82 */
83 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
84 imgfile[0]=pxlfile[0]=vrdfile[0]=(char)0;
85
86 /* Options */
87 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
88 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
89 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
90 if(strncasecmp(cptr, "VRDFILE=", 8)==0) {
91 strlcpy(vrdfile, cptr+8, FILENAME_MAX); if(vrdfile[0]) continue;
92 } else if(strncasecmp(cptr, "MINIMUM", 3)==0) {
93 find_what=1; continue;
94 } else if(strncasecmp(cptr, "MAXIMUM", 3)==0) {
95 find_what=0; continue;
96 } else if(strncasecmp(cptr, "WMAX", 1)==0) {
97 find_what=2; continue;
98 }
99 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
100 return(1);
101 } else break;
102
103 /* Print help or version? */
104 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
105 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
106 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
107
108 /* Process other arguments, starting from the first non-option */
109 if(ai<argc) {strlcpy(imgfile, argv[ai], FILENAME_MAX); ai++;}
110 if(ai<argc) {strlcpy(pxlfile, argv[ai], FILENAME_MAX); ai++;}
111 if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
112
113 /* Did we get all the information that we need? */
114 if(!imgfile[0]) {
115 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
116 return(1);
117 }
118
119
120 /* In verbose mode print options */
121 if(verbose>1) {
122 printf("imgfile := %s\n", imgfile);
123 if(vrdfile[0]) printf("vrdfile := %s\n", vrdfile);
124 if(pxlfile[0]) printf("pxlfile := %s\n", pxlfile);
125 printf("find_what := %d\n", find_what);
126 fflush(stdout);
127 }
128
129 if(verbose>2) IMG_TEST=ECAT63_TEST=ECAT7_TEST=verbose-2;
131
132
133 /*
134 * Read the contents of the PET file to img data structure
135 */
136 IMG img; imgInit(&img);
137 if(verbose>0) printf("reading %s\n", imgfile);
138 ret=imgRead(imgfile, &img);
139 if(ret) {
140 fprintf(stderr, "Error: %s\n", img.statmsg);
141 if(verbose>1) printf("ret=%d\n", ret);
142 imgEmpty(&img); return(2);
143 }
144 if(verbose>1) {
145 printf("img_dimx := %d\n", img.dimx);
146 printf("img_dimy := %d\n", img.dimy);
147 printf("img_dimz := %d\n", img.dimz);
148 printf("img_dimt := %d\n", img.dimt);
149 }
150 if(imgNaNs(&img, 1)>0)
151 if(verbose>0) fprintf(stderr, "Warning: missing pixel values.\n");
152 /* Correct sinogram data for decay */
153 if(img.type==IMG_TYPE_RAW) {
154 if(verbose>0) fprintf(stdout, "correcting sinogram data for decay\n");
155 ret=imgDecayCorrection(&img, 1);
156 if(ret) {
157 fprintf(stderr, "Error %d: cannot decay correct dynamic sinogram.\n", ret);
158 if(ret==1) fprintf(stderr, " Sinogram contains no isotope.\n");
159 if(ret==2) fprintf(stderr, " Sinogram is already decay corrected.\n");
160 imgEmpty(&img);
161 return(2);
162 }
163 }
164 /* Correct sinogram data for frame lengths */
165 if(img.type==IMG_TYPE_RAW) {
166 if(verbose>0) fprintf(stdout, "correcting sinogram data for frame lengths\n");
167 ret=imgRawCountsPerTime(&img, 1);
168 if(ret) {
169 fprintf(stderr, "Error: cannot correct sinogram counts.\n");
170 if(verbose>1) printf("ret=%d\n", ret);
171 imgEmpty(&img); return(2);
172 }
173 }
174
175
176
177 /*
178 * Read image volume range definition, if requested
179 */
180 IMG_RANGE img_range={0,0,0,0,0,0,0,0};
181 if(vrdfile[0]) {
182 if(verbose==1) printf("reading image volume range definition file\n");
183 if(verbose>1) printf("reading %s\n", vrdfile);
184 char tmp[128];
185 ret=irdRead(vrdfile, &img_range, tmp);
186 if(ret) {
187 fprintf(stderr, "Error: could not read image range.\n");
188 if(verbose>2) printf("ret := %d\n", ret);
189 imgEmpty(&img); return(3);
190 }
191 if(verbose>1) {
192 printf("img_range.x := %d - %d\n", img_range.x1, img_range.x2);
193 printf("img_range.y := %d - %d\n", img_range.y1, img_range.y2);
194 printf("img_range.z := %d - %d\n", img_range.z1, img_range.z2);
195 printf("img_range.f := %d - %d\n", img_range.f1, img_range.f2);
196 }
197
198 /* Check that image range is inside image dimensions;
199 fix zero time frame range if necessary. */
200 ret=irdCheck(&img_range, &img);
201 if(ret) {
202 fprintf(stderr, "Error: invalid image range.\n");
203 if(verbose>2) printf("ret := %d\n", ret);
204 imgEmpty(&img); return(3);
205 }
206 }
207
208
209 /*
210 * Find image min and max
211 */
212 IMG_PIXEL maxp, minp;
213 float maxv, minv;
214 if(find_what==0) {
215 if(verbose>0) printf("searching for max in %s\n", imgfile);
216 if(vrdfile[0]) ret=imgRangeMinMax(&img, &img_range, &maxp, &maxv, &minp, &minv);
217 else ret=imgRangeMinMax(&img, NULL, &maxp, &maxv, &minp, &minv);
218 } else if(find_what==1) {
219 if(verbose>0) printf("searching for min in %s\n", imgfile);
220 if(vrdfile[0]) ret=imgRangeMinMax(&img, &img_range, &maxp, &maxv, &minp, &minv);
221 else ret=imgRangeMinMax(&img, NULL, &maxp, &maxv, &minp, &minv);
222 } else {
223 if(verbose>0) printf("searching for weighted max in %s\n", imgfile);
224 if(vrdfile[0]) ret=imgRangeWeightedMax(&img, &img_range, &maxp);
225 else ret=imgRangeWeightedMax(&img, NULL, &maxp);
226 }
227 if(ret) {
228 fprintf(stderr, "Error: cannot find min/max in %s\n", imgfile);
229 if(verbose>1) printf("ret=%d\n", ret);
230 imgEmpty(&img); return(5);
231 }
232 if(find_what!=2 && verbose>1) {
233 printf("image_min := %g\n", minv);
234 printf("image_max := %g\n", maxv);
235 }
236 imgEmpty(&img);
237
238
239 /*
240 * Save or print the pixel coordinates
241 */
242 IMG_PIXEL *ip;
243 if(find_what==0 || find_what==2) ip=&maxp; else ip=&minp;
244 if(!pxlfile[0]) {
245 fprintf(stdout, "%d,%d,%d,%d\n", ip->x, ip->y, ip->z, ip->f);
246 return(0);
247 }
248 FILE *fp; fp=fopen(pxlfile, "w");
249 if(fp==NULL) {
250 fprintf(stderr, "Error: cannot open file for writing (%s).\n", pxlfile);
251 return(11);
252 }
253 fprintf(fp, "%d,%d,%d,%d\n", ip->x, ip->y, ip->z, ip->f);
254 fclose(fp);
255 if(ret) {
256 fprintf(stderr, "Error: cannot write in file %s.\n", pxlfile);
257 return(12);
258 }
259 if(verbose>0) printf("Pixel coordinates written in %s\n", pxlfile);
260
261 return(0);
262}
263/*****************************************************************************/
265/*****************************************************************************/
273 IMG *img,
275 IMG_RANGE *r,
277 IMG_PIXEL *maxp
278) {
279 int zi, yi, xi, fi;
280 double wsum, wz, wy, wx, wf;
281
282 if(img->status<IMG_STATUS_OCCUPIED) return(1);
283 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(1);
284 if(maxp==NULL) return(1);
285 wsum=wz=wy=wx=wf=0.0;
286
287 if(r!=NULL) {
288 if(r->z1<1 || r->y1<1 || r->x1<1 || r->f1<1) return(2);
289 if(r->z2<r->z1 || r->y2<r->y1 || r->x2<r->x1 || r->f2<r->f1) return(3);
290 if(r->z2>img->dimz || r->y2>img->dimy || r->x2>img->dimx || r->f2>img->dimt) return(4);
291
292 maxp->z=r->z1; maxp->y=r->y1; maxp->x=r->x1; maxp->f=r->f1;
293 for(zi=r->z1-1; zi<r->z2; zi++) {
294 for(yi=r->y1-1; yi<r->y2; yi++) {
295 for(xi=r->x1-1; xi<r->x2; xi++) {
296 for(fi=r->f1-1; fi<r->f2; fi++) {
297 wsum+=img->m[zi][yi][xi][fi];
298 wx+=(double)xi*img->m[zi][yi][xi][fi];
299 wy+=(double)yi*img->m[zi][yi][xi][fi];
300 wz+=(double)zi*img->m[zi][yi][xi][fi];
301 wf+=(double)fi*img->m[zi][yi][xi][fi];
302 }
303 }
304 }
305 }
306 } else {
307 maxp->x=maxp->y=maxp->z=maxp->f=1;
308 for(zi=0; zi<img->dimz; zi++) {
309 for(yi=0; yi<img->dimy; yi++) {
310 for(xi=0; xi<img->dimx; xi++) {
311 for(fi=0; fi<img->dimt; fi++) {
312 wsum+=img->m[zi][yi][xi][fi];
313 wx+=(double)xi*img->m[zi][yi][xi][fi];
314 wy+=(double)yi*img->m[zi][yi][xi][fi];
315 wz+=(double)zi*img->m[zi][yi][xi][fi];
316 wf+=(double)fi*img->m[zi][yi][xi][fi];
317 }
318 }
319 }
320 }
321 }
322 if(wsum<1.0E-08) return(5);
323 wx/=wsum; wy/=wsum; wz/=wsum; wf/=wsum;
324 maxp->x=1+(int)roundf(wx); maxp->y=1+(int)roundf(wy);
325 maxp->z=1+(int)roundf(wz); maxp->f=1+(int)roundf(wf);
326 return(0);
327}
int ECAT63_TEST
Definition ecat63h.c:6
int ECAT7_TEST
Definition ecat7h.c:6
int IMG_TEST
Definition img.c:6
unsigned long long imgNaNs(IMG *img, int fix)
Definition img.c:658
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgRawCountsPerTime(IMG *img, int operation)
Definition imgarithm.c:442
int imgDecayCorrection(IMG *image, int mode)
Definition imgdecayc.c:16
int imgRead(const char *fname, IMG *img)
Definition imgfile.c:26
int imgRangeWeightedMax(IMG *img, IMG_RANGE *r, IMG_PIXEL *maxp)
Definition imgmaxp.c:271
int imgRangeMinMax(IMG *img, IMG_RANGE *r, IMG_PIXEL *maxp, float *maxv, IMG_PIXEL *minp, float *minv)
Definition imgminmax.c:71
int irdRead(char *irdfile, IMG_RANGE *img_range, char *status)
Definition ird.c:75
int irdCheck(IMG_RANGE *r, IMG *img)
Definition ird.c:152
Header file for libtpcimgio.
#define IMG_TYPE_RAW
#define IMG_STATUS_OCCUPIED
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
unsigned short int dimx
char type
float **** m
char status
unsigned short int dimt
unsigned short int dimz
unsigned short int dimy
const char * statmsg