TPCCLIB
Loading...
Searching...
No Matches
imgminmax.c
Go to the documentation of this file.
1
5/******************************************************************************/
6#include "libtpcimgio.h"
7/******************************************************************************/
8
9/******************************************************************************/
17 IMG *img,
19 float *maxvalue
20) {
21 if(img->status<IMG_STATUS_OCCUPIED) return(1);
22 if(maxvalue==NULL) return(2); else *maxvalue=0.0;
23 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(3);
24 float f=nanf("");
25 for(int pi=0; pi<img->dimz; pi++)
26 for(int yi=0; yi<img->dimy; yi++)
27 for(int xi=0; xi<img->dimx; xi++)
28 for(int fi=0; fi<img->dimt; fi++) {
29 if(!isfinite(f) || img->m[pi][yi][xi][fi]>f) f=img->m[pi][yi][xi][fi];
30 }
31 *maxvalue=f;
32 return(0);
33}
34/******************************************************************************/
35
36/******************************************************************************/
46 IMG *img,
48 float *maxvalue
49) {
50 if(img->status<IMG_STATUS_OCCUPIED) return(1);
51 if(maxvalue==NULL) return(2); else *maxvalue=0.0;
52 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(3);
53 float f=nanf("");
54 for(int pi=0; pi<img->dimz; pi++)
55 for(int yi=0; yi<img->dimy; yi++)
56 for(int xi=0; xi<img->dimx; xi++)
57 for(int fi=0; fi<img->dimt; fi++) {
58 if(!isfinite(f) || fabs(img->m[pi][yi][xi][fi])>fabs(f)) f=img->m[pi][yi][xi][fi];
59 }
60 *maxvalue=f;
61 return(0);
62}
63/******************************************************************************/
64
65/******************************************************************************/
73 IMG *img,
75 IMG_RANGE *r,
77 IMG_PIXEL *maxp,
79 float *maxv,
81 IMG_PIXEL *minp,
83 float *minv
84) {
85 int zi, yi, xi, fi;
86 float lmax, lmin;
87
88 if(img->status<IMG_STATUS_OCCUPIED) return(1);
89 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(1);
90
91 if(r!=NULL) {
92 if(r->z1<1 || r->y1<1 || r->x1<1 || r->f1<1) return(2);
93 if(r->z2<r->z1 || r->y2<r->y1 || r->x2<r->x1 || r->f2<r->f1) return(3);
94 if(r->z2>img->dimz || r->y2>img->dimy || r->x2>img->dimx || r->f2>img->dimt) return(4);
95
96 zi=r->z1-1; yi=r->y1-1; xi=r->x1-1; fi=r->f1-1;
97 lmax=lmin=nanf("");
98 if(maxp!=NULL) {maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1; maxp->f=fi+1;}
99 if(minp!=NULL) {minp->z=zi+1; minp->y=yi+1; minp->x=xi+1; minp->f=fi+1;}
100 for(zi=r->z1-1; zi<r->z2; zi++) {
101 for(yi=r->y1-1; yi<r->y2; yi++) {
102 for(xi=r->x1-1; xi<r->x2; xi++) {
103 for(fi=r->f1-1; fi<r->f2; fi++) {
104 if(!isfinite(lmax) || img->m[zi][yi][xi][fi]>lmax) {
105 lmax=img->m[zi][yi][xi][fi];
106 if(maxp!=NULL && isfinite(img->m[zi][yi][xi][fi])) {
107 maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1; maxp->f=fi+1;}
108 }
109 if(!isfinite(lmin) || img->m[zi][yi][xi][fi]<lmin) {
110 lmin=img->m[zi][yi][xi][fi];
111 if(minp!=NULL && isfinite(img->m[zi][yi][xi][fi])) {
112 minp->z=zi+1; minp->y=yi+1; minp->x=xi+1; minp->f=fi+1;}
113 }
114 }
115 }
116 }
117 }
118 } else {
119 zi=yi=xi=fi=0; lmax=lmin=nanf("");
120 if(maxp!=NULL) {maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1; maxp->f=fi+1;}
121 if(minp!=NULL) {minp->z=zi+1; minp->y=yi+1; minp->x=xi+1; minp->f=fi+1;}
122 for(zi=0; zi<img->dimz; zi++) {
123 for(yi=0; yi<img->dimy; yi++) {
124 for(xi=0; xi<img->dimx; xi++) {
125 for(fi=0; fi<img->dimt; fi++) {
126 if(!isfinite(lmax) || img->m[zi][yi][xi][fi]>lmax) {
127 lmax=img->m[zi][yi][xi][fi];
128 if(maxp!=NULL && isfinite(img->m[zi][yi][xi][fi])) {
129 maxp->z=zi+1; maxp->y=yi+1; maxp->x=xi+1; maxp->f=fi+1;}
130 }
131 if(!isfinite(lmin) || img->m[zi][yi][xi][fi]<lmin) {
132 lmin=img->m[zi][yi][xi][fi];
133 if(minp!=NULL && isfinite(img->m[zi][yi][xi][fi])) {
134 minp->z=zi+1; minp->y=yi+1; minp->x=xi+1; minp->f=fi+1;}
135 }
136 }
137 }
138 }
139 }
140 }
141 if(maxv!=NULL) *maxv=lmax;
142 if(minv!=NULL) *minv=lmin;
143 if(!isfinite(lmax) && (maxp!=NULL || maxv!=NULL)) return(5);
144 if(!isfinite(lmin) && (minp!=NULL || minv!=NULL)) return(5);
145 return(0);
146}
147/******************************************************************************/
148
149/******************************************************************************/
156 IMG *img,
158 float *minvalue,
160 float *maxvalue
161) {
162 return (imgRangeMinMax(img, NULL, NULL, maxvalue, NULL, minvalue));
163}
164/******************************************************************************/
165
166/******************************************************************************/
173 IMG *img,
175 int frame,
177 float *minvalue,
179 float *maxvalue
180) {
181 if(img->status<IMG_STATUS_OCCUPIED) return(1);
182 if(minvalue==NULL || maxvalue==NULL) return(2);
183 *minvalue=*maxvalue=0.0;
184 int fi=frame-1;
185 if(img->dimt<frame || img->dimz<1 || img->dimy<1 || img->dimx<1) return(3);
186 if(frame<1) return(4);
187
188 float mi, ma;
189 mi=ma=nanf("");
190 for(int pi=0; pi<img->dimz; pi++)
191 for(int yi=0; yi<img->dimy; yi++)
192 for(int xi=0; xi<img->dimx; xi++) {
193 if(!isfinite(ma) || img->m[pi][yi][xi][fi]>ma) ma=img->m[pi][yi][xi][fi];
194 if(!isfinite(mi) || img->m[pi][yi][xi][fi]<mi) mi=img->m[pi][yi][xi][fi];
195 }
196 *minvalue=mi; *maxvalue=ma;
197 if(!isfinite(mi) || !isfinite(ma)) return(5);
198 return(0);
199}
200/******************************************************************************/
201
202/******************************************************************************/
213 const char *fname,
215 float *fmin,
217 float *fmax
218) {
219 int fi=0, ret;
220 IMG img;
221 float frmin, frmax;
222
223 if(IMG_TEST) printf("imgReadMinMax(%s, *fmin, *fmax)\n", fname);
224 imgInit(&img);
225 while((ret=imgReadFrame(fname, fi+1, &img, 0)) == 0) {
226 if(imgMinMax(&img, &frmin, &frmax)!=0) {imgEmpty(&img); return STATUS_FAULT;}
227 if(fi==0) {
228 if(fmin!=NULL) *fmin=frmin;
229 if(fmin!=NULL) *fmax=frmax;
230 } else {
231 if(fmin!=NULL && !(*fmin<=frmin)) *fmin=frmin;
232 if(fmax!=NULL && !(*fmax>=frmax)) *fmax=frmax;
233 }
234 fi++;
235 } /* next frame */
236 imgEmpty(&img);
237 if(ret==STATUS_NOMATRIX && fi>0) return STATUS_OK;
238 else return ret;
239}
240/******************************************************************************/
241
242/******************************************************************************/
250 IMG *img,
253 float *maxvalue,
256 IMG_PIXEL *p
257) {
258 int pi, yi, xi, fi;
259 float f, v;
260
261 if(img->status<IMG_STATUS_OCCUPIED) return(1);
262 if(maxvalue==NULL && p==NULL) return(2);
263 if(img->dimt<1 || img->dimz<1 || img->dimy<3 || img->dimx<3) return(3);
264 if(maxvalue!=NULL) *maxvalue=0.0;
265 if(p!=NULL) p->x=p->y=p->z=p->f=1;
266 f=-1.0E20;
267 for(pi=0; pi<img->dimz; pi++)
268 for(yi=1; yi<img->dimy-1; yi++)
269 for(xi=1; xi<img->dimx-1; xi++)
270 for(fi=0; fi<img->dimt; fi++) {
271 v=img->m[pi][yi-1][xi-1][fi]+
272 img->m[pi][yi-1][xi ][fi]+
273 img->m[pi][yi-1][xi+1][fi]+
274 img->m[pi][yi ][xi-1][fi]+
275 img->m[pi][yi ][xi ][fi]*2.0+
276 img->m[pi][yi ][xi+1][fi]+
277 img->m[pi][yi+1][xi-1][fi]+
278 img->m[pi][yi+1][xi ][fi]+
279 img->m[pi][yi+1][xi+1][fi];
280 v*=0.1;
281 if(v>f) {
282 f=v; if(p!=NULL) {p->x=xi+1; p->y=yi+1; p->z=pi+1; p->f=fi+1;}}
283 }
284 if(maxvalue!=NULL) *maxvalue=f;
285 return(0);
286}
287/******************************************************************************/
288
289/******************************************************************************/
296 IMG *img,
298 float beforeTime,
300 IMG_PIXEL *p,
302 int verbose
303) {
304 int zi, yi, xi, fi, mf;
305 float f;
306
307 if(verbose>0) printf("imgGetPeak(img, %g, p, %d)\n", beforeTime, verbose);
308 if(img->status<IMG_STATUS_OCCUPIED) return(1);
309 if(p==NULL) return(2);
310 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(3);
311 if(beforeTime<img->mid[0]) {
312 if(verbose>0) fprintf(stderr, "Error: invalid max search time setting.\n");
313 return(4);
314 }
315 f=nanf(""); mf=img->dimt; p->x=p->y=p->z=p->f=1;
316 for(zi=0; zi<img->dimz; zi++) {
317 for(yi=0; yi<img->dimy; yi++) {
318 for(xi=0; xi<img->dimx; xi++) {
319 for(fi=0; fi<img->dimt; fi++) if(img->mid[fi]<=beforeTime) {
320 if(!isfinite(img->m[zi][yi][xi][fi])) continue;
321 if(isfinite(f) && img->m[zi][yi][xi][fi]<f) // lower
322 continue;
323 if(isfinite(f) && img->m[zi][yi][xi][fi]==f) { // equal
324 // only use this if earlier than in prev max
325 if(fi>=mf) continue;
326 }
327 f=img->m[zi][yi][xi][fi];
328 p->x=xi+1; p->y=yi+1; p->z=zi+1; p->f=fi+1;
329 mf=fi;
330 }
331 }
332 }
333 }
334 if(!isfinite(f)) return(5);
335 if(verbose>2) printf("maxval := %g\n", f);
336 return(0);
337}
338/******************************************************************************/
339
340/******************************************************************************/
347 IMG *img,
350 IMG *mimg,
355 const int w,
357 int verbose
358) {
359 if(verbose>0) printf("imgGetMaxTime(*img, *mimg, %d)\n", w);
360
361 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
362 if(mimg==NULL) return(2);
363 if(mimg->status==IMG_STATUS_OCCUPIED) imgEmpty(mimg);
364
365 /* Allocate memory for one frame */
366 int ret;
367 if(verbose>1) printf("allocating memory for %dx%dx%d pixels\n", img->dimz, img->dimy, img->dimx);
368 ret=imgAllocate(mimg, img->dimz, img->dimy, img->dimx, 1);
369 if(ret) return(ret);
370 /* set image header information */
371 imgCopyhdr(img, mimg);
372 mimg->start[0]=img->start[0]; mimg->end[0]=img->end[img->dimt-1];
373 mimg->mid[0]=(mimg->start[0]+mimg->end[0])/2.0;
374 mimg->unit=CUNIT_UNKNOWN;
375
376 if(w==0) {
377 for(int zi=0; zi<img->dimz; zi++) {
378 for(int yi=0; yi<img->dimy; yi++) {
379 for(int xi=0; xi<img->dimx; xi++) {
380 /* Find the frame with max value */
381 int ti=0, mi=0;
382 double mv=img->m[zi][yi][xi][ti];
383 for(ti=1; ti<img->dimt; ti++) {
384 if(img->m[zi][yi][xi][ti]<mv) continue;
385 mi=ti; mv=img->m[zi][yi][xi][ti];
386 }
387 if(mv>0.0) mimg->m[zi][yi][xi][0]=img->mid[mi];
388 else mimg->m[zi][yi][xi][0]=0.0;
389 }
390 }
391 }
392 return(0);
393 }
394
395 if(w==1) { // Same as the equation for mean residence time (MRT) for PTACs in pharmacokinetics
396 for(int zi=0; zi<img->dimz; zi++) {
397 for(int yi=0; yi<img->dimy; yi++) {
398 for(int xi=0; xi<img->dimx; xi++) {
399 /* Compute the value weighted time */
400 double sumw=0.0, sumt=0.0;
401 for(int ti=0; ti<img->dimt; ti++) {
402 if(isnan(img->m[zi][yi][xi][ti])) continue;
403 float fdur=img->end[ti]-img->start[ti]; if(fdur<=0.0) fdur=1.0;
404 sumt+=img->m[zi][yi][xi][ti]*img->mid[ti]*fdur;
405 sumw+=img->m[zi][yi][xi][ti]*fdur;
406 }
407 sumt/=sumw;
408 if(sumt>0.0 && sumw>0.0) mimg->m[zi][yi][xi][0]=sumt;
409 else mimg->m[zi][yi][xi][0]=0.0;
410 }
411 }
412 }
413 return(0);
414 }
415
416 if(w>1) {
417 for(int zi=0; zi<img->dimz; zi++) {
418 for(int yi=0; yi<img->dimy; yi++) {
419 for(int xi=0; xi<img->dimx; xi++) {
420 /* Find the frame with max value */
421 int ti=0, mi=0;
422 double mv=img->m[zi][yi][xi][ti];
423 for(ti=1; ti<img->dimt; ti++) {
424 if(img->m[zi][yi][xi][ti]<mv) continue;
425 mi=ti; mv=img->m[zi][yi][xi][ti];
426 }
427 /* calculate weighted mean from subsequent frames, if possible */
428 if(mi<1 || mi>img->dimt-2) continue;
429 int i1, i2; i1=mi-1; i2=mi+1; if(i1>0 && i2<img->dimt-1) {i1--; i2++;}
430 double sumw=0.0, sumt=0.0;
431 for(int i=i1; i<=i2; i++) {
432 if(!(img->m[zi][yi][xi][i]>0.0)) continue;
433 sumt+=img->m[zi][yi][xi][i]*img->mid[i];
434 sumw+=img->m[zi][yi][xi][i];
435 }
436 sumt/=sumw;
437 if(sumt>0.0) mimg->m[zi][yi][xi][0]=sumt;
438 else mimg->m[zi][yi][xi][0]=0.0;
439 }
440 }
441 }
442 return(0);
443 }
444
445 return(0);
446}
447/******************************************************************************/
448
449/******************************************************************************/
456 IMG *img,
460 IMG *mimg,
462 int verbose
463) {
464 if(verbose>0) printf("imgGetMaxFrame()\n");
465
466 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
467 if(mimg==NULL) return(2);
468 if(mimg->status==IMG_STATUS_OCCUPIED) imgEmpty(mimg);
469
470 /* Allocate memory for one frame */
471 int ret;
472 if(verbose>1) printf("allocating memory for %dx%dx%d pixels\n", img->dimz, img->dimy, img->dimx);
473 ret=imgAllocate(mimg, img->dimz, img->dimy, img->dimx, 1); if(ret) return(ret);
474 /* set image header information */
475 imgCopyhdr(img, mimg);
476 mimg->start[0]=img->start[0]; mimg->end[0]=img->end[img->dimt-1];
477 mimg->mid[0]=(mimg->start[0]+mimg->end[0])/2.0;
478
479 /* Go through every pixel */
480 int ti, zi, xi, yi;
481 double mv; int mi;
482 for(zi=0; zi<img->dimz; zi++) {
483 for(yi=0; yi<img->dimy; yi++) for(xi=0; xi<img->dimx; xi++) {
484 ti=mi=0; mv=img->m[zi][yi][xi][ti];
485 for(ti=1; ti<img->dimt; ti++) {
486 if(img->m[zi][yi][xi][ti]<mv) continue;
487 mi=ti; mv=img->m[zi][yi][xi][ti];
488 }
489 if(mv>1.0E-008) mimg->m[zi][yi][xi][0]=1.0+mi;
490 else mimg->m[zi][yi][xi][0]=0.0;
491 }
492 }
493
494 return(0);
495}
496/******************************************************************************/
497
498/******************************************************************************/
505 IMG *img,
507 IMG_RANGE *r,
509 float *avg
510) {
511 int zi, yi, xi, fi;
512 long long n=0;
513
514 if(img->status<IMG_STATUS_OCCUPIED) return(1);
515 if(r!=NULL) {
516 if(r->z1<1 || r->y1<1 || r->x1<1 || r->f1<1) return(2);
517 if(r->z2<r->z1 || r->y2<r->y1 || r->x2<r->x1 || r->f2<r->f1) return(3);
518 if(r->z2>img->dimz || r->y2>img->dimy || r->x2>img->dimx || r->f2>img->dimt) return(4);
519 }
520 if(avg==NULL) return(5);
521
522 *avg=0.0;
523 if(r!=NULL) {
524 for(zi=r->z1-1; zi<r->z2; zi++) {
525 for(yi=r->y1-1; yi<r->y2; yi++) {
526 for(xi=r->x1-1; xi<r->x2; xi++) {
527 for(fi=r->f1-1; fi<r->f2; fi++) if(!isnan(img->m[zi][yi][xi][fi])) {
528 *avg+=img->m[zi][yi][xi][fi]; n++;
529 }
530 }
531 }
532 }
533 } else {
534 for(zi=0; zi<img->dimz; zi++) {
535 for(yi=0; yi<img->dimy; yi++) {
536 for(xi=0; xi<img->dimx; xi++) {
537 for(fi=0; fi<img->dimt; fi++) if(!isnan(img->m[zi][yi][xi][fi])) {
538 *avg+=img->m[zi][yi][xi][fi]; n++;
539 }
540 }
541 }
542 }
543 }
544 if(n>0) *avg/=(float)n;
545 return(0);
546}
547/******************************************************************************/
548
549/******************************************************************************/
560 float *data,
562 long long int n,
564 long long int k
565) {
566 long long int i, j, l, m;
567 float x, s;
568
569 l=0; m=n-1;
570 while(l<m) {
571 x=data[k]; i=l; j=m;
572 do {
573 while(data[i]<x) i++;
574 while(x<data[j]) j--;
575 if(i<=j) {s=data[i]; data[i]=data[j]; data[j]=s; i++; j--;}
576 } while(i<=j);
577 if(j<k) l=i;
578 if(k<i) m=j;
579 }
580 return(data[k]);
581}
582/******************************************************************************/
583
584/******************************************************************************/
595 float *data,
597 long long int n
598) {
599 long long int k;
600 float d1, d2;
601
602 if(n<1) return(0.0);
603 if(n%2) {
604 k=(n-1)/2; return(f_kth_smallest(data, n, k));
605 } else {
606 k=n/2; d1=f_kth_smallest(data, n, k-1); d2=f_kth_smallest(data, n, k);
607 return(0.5*(d1+d2));
608 }
609}
610/******************************************************************************/
611
612/******************************************************************************/
618float fmean(
620 float *data,
622 long long int n,
624 float *sd
625) {
626 long long int i;
627 float sumsqr=0.0, sqrsum=0.0, avg;
628
629 if(n<1 || data==NULL) {if(sd!=NULL) *sd=0.0; return(0.0);}
630
631 for(i=0; i<n; i++) {sumsqr+=data[i]*data[i]; sqrsum+=data[i];}
632 avg=sqrsum/(float)n; if(sd==NULL) return(avg);
633 if(n==1) {
634 *sd=0.0;
635 } else {
636 sqrsum*=sqrsum;
637 *sd=sqrt( (sumsqr - sqrsum/(float)n) / (float)(n-1) );
638 }
639 return(avg);
640}
641/******************************************************************************/
642
643/******************************************************************************/
651 float *data,
653 long long int n,
655 float *fmin,
657 float *fmax
658) {
659 if(fmin!=NULL) *fmin=nanf("");
660 if(fmax!=NULL) *fmax=nanf("");
661
662 long long int i;
663 for(i=0; i<n; i++) if(isfinite(data[i])) break;
664 if(i==n) return; // no finite values found
665 float mi, ma;
666 mi=ma=data[i++];
667 for(; i<n; i++) if(isfinite(data[i])) {
668 if(data[i]>ma) ma=data[i];
669 else if(data[i]<mi) mi=data[i];
670 }
671 if(fmin!=NULL) *fmin=mi;
672 if(fmax!=NULL) *fmax=ma;
673 return;
674}
675/******************************************************************************/
676
677/******************************************************************************/
int IMG_TEST
Definition img.c:6
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition img.c:194
int imgCopyhdr(IMG *image1, IMG *image2)
Definition img.c:471
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgReadFrame(const char *fname, int frame_to_read, IMG *img, int frame_index)
Definition imgfile.c:269
int imgGetMaxTime(IMG *img, IMG *mimg, const int w, int verbose)
Definition imgminmax.c:345
int imgAvg(IMG *img, IMG_RANGE *r, float *avg)
Definition imgminmax.c:503
float fmean(float *data, long long int n, float *sd)
Definition imgminmax.c:618
void fMinMaxFin(float *data, long long int n, float *fmin, float *fmax)
Definition imgminmax.c:649
int imgReadMinMax(const char *fname, float *fmin, float *fmax)
Definition imgminmax.c:211
int imgFrameMinMax(IMG *img, int frame, float *minvalue, float *maxvalue)
Definition imgminmax.c:171
int imgRangeMinMax(IMG *img, IMG_RANGE *r, IMG_PIXEL *maxp, float *maxv, IMG_PIXEL *minp, float *minv)
Definition imgminmax.c:71
int imgAbsMax(IMG *img, float *maxvalue)
Definition imgminmax.c:44
int imgMinMax(IMG *img, float *minvalue, float *maxvalue)
Definition imgminmax.c:154
int imgGetMaxFrame(IMG *img, IMG *mimg, int verbose)
Definition imgminmax.c:454
int imgGetPeak(IMG *img, float beforeTime, IMG_PIXEL *p, int verbose)
Definition imgminmax.c:294
float f_kth_smallest(float *data, long long int n, long long int k)
Definition imgminmax.c:558
int imgMax(IMG *img, float *maxvalue)
Definition imgminmax.c:15
int imgSmoothMax(IMG *img, float *maxvalue, IMG_PIXEL *p)
Definition imgminmax.c:248
float fmedian(float *data, long long int n)
Definition imgminmax.c:593
Header file for libtpcimgio.
#define IMG_STATUS_OCCUPIED
unsigned short int dimx
float **** m
char unit
char status
unsigned short int dimt
float * start
unsigned short int dimz
unsigned short int dimy
float * end
float * mid