TPCCLIB
Loading...
Searching...
No Matches
imgthreshold.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "libtpcimgp.h"
7/*****************************************************************************/
8
9/*****************************************************************************/
21 IMG *img,
23 float threshold_level,
25 long long *thr_nr
26) {
27 int zi, yi, xi, fi, ret;
28 long long nr=0;
29 IMG aucimg;
30 float maxauc, thr_limit;
31
32 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
33 if(img->dimt>1) { // dynamic image
34 /* Calculate AUC image */
35 imgInit(&aucimg);
36 ret=imgFrameIntegral(img, 0, img->dimt-1, &aucimg, 0);
37 if(ret) return(ret);
38 /* Search the max AUC */
39 ret=imgMax(&aucimg, &maxauc); if(ret) {imgEmpty(&aucimg); return(ret);}
40 /* Calculate the limit value */
41 thr_limit=threshold_level*maxauc;
42 /* Set to zero the pixels with AUC less than this limit */
43 for(zi=0; zi<img->dimz; zi++)
44 for(yi=0; yi<img->dimy; yi++)
45 for(xi=0; xi<img->dimx; xi++)
46 if(aucimg.m[zi][yi][xi][0]<thr_limit) {
47 for(fi=0; fi<img->dimt; fi++) img->m[zi][yi][xi][fi]=0.0;
48 nr++;
49 }
50 imgEmpty(&aucimg);
51 } else { // static image
52 /* Search the max value */
53 ret=imgMax(img, &maxauc); if(ret) return(ret);
54 /* Calculate the limit value */
55 thr_limit=threshold_level*maxauc;
56 /* Set to zero the pixels with AUC less than this limit */
57 for(zi=0; zi<img->dimz; zi++)
58 for(yi=0; yi<img->dimy; yi++)
59 for(xi=0; xi<img->dimx; xi++)
60 if(img->m[zi][yi][xi][0]<thr_limit) {
61 for(fi=0; fi<img->dimt; fi++) img->m[zi][yi][xi][fi]=0.0;
62 nr++;
63 }
64 }
65 if(thr_nr!=NULL) *thr_nr=nr;
66 return(0);
67}
68/*****************************************************************************/
69
70/*****************************************************************************/
81 IMG *img,
84 float lower_threshold_level,
87 float upper_threshold_level,
92 IMG *timg,
95 long long *lower_thr_nr,
98 long long *upper_thr_nr
99) {
100 int zi, yi, xi, fi, ret;
101 long long lnr=0, unr=0;
102 IMG aucimg;
103 float maxauc, lower_thr_limit, upper_thr_limit;
104
105 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
106
107 /* Check if mask image is given and if it exists */
108 if(timg!=NULL && timg->status!=IMG_STATUS_OCCUPIED) {
109 /* Allocate memory for the mask data */
110 ret=imgAllocate(timg, img->dimz, img->dimy, img->dimx, 1);
111 if(ret) return(ret);
112 /* set mask image header information */
113 imgCopyhdr(img, timg);
114 timg->start[0]=img->start[0]; timg->end[0]=img->end[img->dimt-1];
115 timg->mid[0]=(timg->start[0]+timg->end[0])/2.0;
116 /* Initiate mask to 1 */
117 for(zi=0; zi<img->dimz; zi++)
118 for(yi=0; yi<img->dimy; yi++)
119 for(xi=0; xi<img->dimx; xi++)
120 timg->m[zi][yi][xi][0]=1.0;
121 } else if(timg!=NULL) {
122 /* Check that mask dimensions are ok */
123 if(timg->dimz!=img->dimz || timg->dimy!=img->dimy || timg->dimx!=img->dimx) return 2;
124 if(timg->dimt<1) return 3;
125 }
126
127 /* Threshold */
128 if(img->dimt>1) { // dynamic image
129 /* Calculate AUC image */
130 imgInit(&aucimg);
131 ret=imgFrameIntegral(img, 0, img->dimt-1, &aucimg, 0);
132 if(ret) return(ret);
133 /* Search the max AUC */
134 ret=imgMax(&aucimg, &maxauc); if(ret) {imgEmpty(&aucimg); return(ret);}
135 /* Calculate the limit values */
136 lower_thr_limit=lower_threshold_level*maxauc;
137 upper_thr_limit=upper_threshold_level*maxauc;
138 /* Set to zero the pixels with AUC less/more than these limits */
139 for(zi=0; zi<img->dimz; zi++)
140 for(yi=0; yi<img->dimy; yi++)
141 for(xi=0; xi<img->dimx; xi++)
142 if(aucimg.m[zi][yi][xi][0]<lower_thr_limit) {
143 if(timg==NULL) for(fi=0; fi<img->dimt; fi++) img->m[zi][yi][xi][fi]=0.0;
144 else timg->m[zi][yi][xi][0]=0.0;
145 lnr++;
146 } else if(aucimg.m[zi][yi][xi][0]>upper_thr_limit) {
147 if(timg==NULL) for(fi=0; fi<img->dimt; fi++) img->m[zi][yi][xi][fi]=0.0;
148 else timg->m[zi][yi][xi][0]=0.0;
149 unr++;
150 }
151 imgEmpty(&aucimg);
152 } else { // static image
153 /* Search the max value */
154 ret=imgMax(img, &maxauc); if(ret) return(ret);
155 /* Calculate the limit values */
156 lower_thr_limit=lower_threshold_level*maxauc;
157 upper_thr_limit=upper_threshold_level*maxauc;
158 /* Set to zero the pixels with AUC less/more than these limits */
159 for(zi=0; zi<img->dimz; zi++)
160 for(yi=0; yi<img->dimy; yi++)
161 for(xi=0; xi<img->dimx; xi++)
162 if(img->m[zi][yi][xi][0]<lower_thr_limit) {
163 if(timg==NULL) for(fi=0; fi<img->dimt; fi++) img->m[zi][yi][xi][fi]=0.0;
164 else timg->m[zi][yi][xi][0]=0.0;
165 lnr++;
166 } else if(img->m[zi][yi][xi][0]>upper_thr_limit) {
167 if(timg==NULL) for(fi=0; fi<img->dimt; fi++) img->m[zi][yi][xi][fi]=0.0;
168 else timg->m[zi][yi][xi][0]=0.0;
169 unr++;
170 }
171 }
172
173 if(lower_thr_nr!=NULL) *lower_thr_nr=lnr;
174 if(upper_thr_nr!=NULL) *upper_thr_nr=unr;
175 return(0);
176}
177/*****************************************************************************/
178
179/*****************************************************************************/
193 IMG *img,
195 float minValue,
197 float maxValue,
201 IMG *timg,
204 long long *count
205) {
206 int fi=0, zi, xi, yi, ret;
207
208 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
209 if(count!=NULL) *count=0;
210 /* Check if mask image exists */
211 if(timg->status!=IMG_STATUS_OCCUPIED) {
212 /* Allocate memory for the template data */
213 ret=imgAllocate(timg, img->dimz, img->dimy, img->dimx, 1);
214 if(ret) return(ret);
215 /* set mask image header information */
216 imgCopyhdr(img, timg);
217 timg->start[0]=img->start[0]; timg->end[0]=img->end[img->dimt-1];
218 timg->mid[0]=(timg->start[0]+timg->end[0])/2.0;
219 /* Initiate template to 1 */
220 for(zi=0; zi<img->dimz; zi++)
221 for(yi=0; yi<img->dimy; yi++)
222 for(xi=0; xi<img->dimx; xi++)
223 timg->m[zi][yi][xi][0]=1.0;
224 } else {
225 /* Check that mask image dimensions are ok */
226 if(timg->dimz!=img->dimz || timg->dimy!=img->dimy || timg->dimx!=img->dimx)
227 return 2;
228 if(timg->dimt<1) return(3);
229 }
230 /* Set mask contents */
231 fi=0;
232 long long n=0;
233 for(zi=0; zi<img->dimz; zi++)
234 for(yi=0; yi<img->dimy; yi++)
235 for(xi=0; xi<img->dimx; xi++) {
236 /*printf("pxl=%g (%g - %g)\n", img->m[zi][yi][xi][fi], minValue, maxValue);*/
237 if(img->m[zi][yi][xi][fi]<minValue || img->m[zi][yi][xi][fi]>maxValue)
238 timg->m[zi][yi][xi][0]=0.0;
239 else n++;
240 }
241 if(count!=NULL) *count=n;
242 return(0);
243}
244/*****************************************************************************/
245
246/*****************************************************************************/
259 IMG *img,
261 float minValue,
263 float maxValue,
267 IMG *timg
268) {
269 return(imgThresholdMaskCount(img, minValue, maxValue, timg, NULL));
270}
271/*****************************************************************************/
272
273/*****************************************************************************/
284 IMG *img,
286 IMG *templt,
288 float thrValue
289) {
290 if(img->status!=IMG_STATUS_OCCUPIED) return(1);
291 if(templt->status!=IMG_STATUS_OCCUPIED) return(2);
292 for(int zi=0; zi<img->dimz; zi++)
293 for(int yi=0; yi<img->dimy; yi++) for(int xi=0; xi<img->dimx; xi++)
294 if(templt->m[zi][yi][xi][0]==0.0) {
295 for(int fi=0; fi<img->dimt; fi++) img->m[zi][yi][xi][fi]=thrValue;
296 }
297 return(0);
298}
299/*****************************************************************************/
300
301/*****************************************************************************/
308 IMG *image,
310 float cutoff,
313 int mode
314) {
315 int zi, yi, xi, ti;
316
317 if(mode==0) {
318 for(zi=0; zi<image->dimz; zi++)
319 for(yi=0; yi<image->dimy; yi++)
320 for(xi=0; xi<image->dimx; xi++)
321 for(ti=0; ti<image->dimt; ti++)
322 if(image->m[zi][yi][xi][ti]>cutoff) image->m[zi][yi][xi][ti]=cutoff;
323 } else {
324 for(zi=0; zi<image->dimz; zi++)
325 for(yi=0; yi<image->dimy; yi++)
326 for(xi=0; xi<image->dimx; xi++)
327 for(ti=0; ti<image->dimt; ti++)
328 if(image->m[zi][yi][xi][ti]<cutoff) image->m[zi][yi][xi][ti]=cutoff;
329 }
330 return;
331}
332/*****************************************************************************/
333
334/*****************************************************************************/
341 IMG *img,
343 float limit
344) {
345 int zi, yi, xi, fi;
346 long long nr=0;
347 float f;
348 IMG tmp;
349
350 if(img->status!=IMG_STATUS_OCCUPIED || img->dimt<1) return(-1);
351 imgInit(&tmp);
352 if(imgAllocate(&tmp, img->dimz, img->dimy, img->dimx, 1)!=0) return(-2);
353 /* Process one frame at a time */
354 for(fi=0; fi<img->dimt; fi++) {
355 /* Copy one frame to safety */
356 for(zi=0; zi<tmp.dimz; zi++)
357 for(yi=0; yi<tmp.dimy; yi++)
358 for(xi=0; xi<tmp.dimx; xi++)
359 tmp.m[zi][yi][xi][0]=img->m[zi][yi][xi][fi];
360 /* Go through it */
361 for(zi=0; zi<img->dimz; zi++) {
362 for(yi=1; yi<img->dimy-1; yi++) for(xi=1; xi<img->dimx-1; xi++) {
363 f=tmp.m[zi][yi][xi-1][0]+
364 tmp.m[zi][yi][xi+1][0]+
365 tmp.m[zi][yi-1][xi][0]+
366 tmp.m[zi][yi+1][xi][0]+
367 tmp.m[zi][yi+1][xi-1][0]+
368 tmp.m[zi][yi+1][xi+1][0]+
369 tmp.m[zi][yi-1][xi-1][0]+
370 tmp.m[zi][yi-1][xi+1][0];
371 f/=8.0;
372 if(img->m[zi][yi][xi][fi]>(limit*f)) {img->m[zi][yi][xi][fi]=f; nr++;}
373 }
374 } /* next plane */
375 } /* next frame */
376 imgEmpty(&tmp);
377
378 return(nr);
379}
380/*****************************************************************************/
381
382/*****************************************************************************/
396 IMG *img,
398 const int sz,
400 const int sy,
402 const int sx,
404 float lthr,
406 float uthr,
408 IMG *mask,
410 int verbose
411) {
412 if(verbose>0) {
413 printf("imgRegionGrowingByThreshold(img, %d, %d, %d, %g, %g, mask, %d)\n",
414 sz, sy, sx, lthr, uthr, verbose);
415 fflush(stdout);
416 }
417 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(2);
418 if(mask==NULL || mask->status!=IMG_STATUS_OCCUPIED) return(3);
419 if(img->dimz!=mask->dimz || img->dimy!=mask->dimy || img->dimx!=mask->dimx) return(4);
420 int dimz=img->dimz, dimy=img->dimy, dimx=img->dimx;
421
422 /* Check that seed pixel resides inside image volume */
423 if(sz<0 || sy<0 || sx<0 || sz>=dimz || sy>=dimy || sx>=dimx) {
424 if(verbose>1) printf("pixels does not reside inside image\n");
425 return(1);
426 }
427
428 /* Check that seed pixel is not already part of mask */
429 if(mask->m[sz][sy][sx][0]>0.5) {
430 if(verbose>1) printf("seed already belongs to mask\n");
431 return(1);
432 }
433
434 /* Threshold */
435 if(img->m[sz][sy][sx][0]<lthr || img->m[sz][sy][sx][0]>uthr) {
436 if(verbose>1) {
437 printf(" [%d][%d][%d] outside thresholds\n", sz, sy, sx);
438 fflush(stdout);
439 }
440 mask->m[sz][sy][sx][0]=0.0;
441 return(1);
442 }
443 if(verbose>1) {
444 printf(" [%d][%d][%d] added to mask\n", sz, sy, sx);
445 fflush(stdout);
446 }
447 mask->m[sz][sy][sx][0]=1.0;
448
449 /* Check the neighbouring pixels */
450 int nsz, nsy, nsx;
451 nsz=sz; nsy=sy; nsx=sx-1;
452 imgRegionGrowingByThreshold(img, nsz, nsy, nsx, lthr, uthr, mask, verbose);
453 nsz=sz; nsy=sy; nsx=sx+1;
454 imgRegionGrowingByThreshold(img, nsz, nsy, nsx, lthr, uthr, mask, verbose);
455 nsz=sz; nsy=sy-1; nsx=sx;
456 imgRegionGrowingByThreshold(img, nsz, nsy, nsx, lthr, uthr, mask, verbose);
457 nsz=sz; nsy=sy+1; nsx=sx;
458 imgRegionGrowingByThreshold(img, nsz, nsy, nsx, lthr, uthr, mask, verbose);
459 nsz=sz-1; nsy=sy; nsx=sx;
460 imgRegionGrowingByThreshold(img, nsz, nsy, nsx, lthr, uthr, mask, verbose);
461 nsz=sz+1; nsy=sy; nsx=sx;
462 imgRegionGrowingByThreshold(img, nsz, nsy, nsx, lthr, uthr, mask, verbose);
463
464 return(0);
465}
466/*****************************************************************************/
467
468/*****************************************************************************/
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 imgFrameIntegral(IMG *img, int first, int last, IMG *iimg, int verbose)
Definition imgarithm.c:346
int imgMax(IMG *img, float *maxvalue)
Definition imgminmax.c:15
int imgThresholdMask(IMG *img, float minValue, float maxValue, IMG *timg)
void imgCutoff(IMG *image, float cutoff, int mode)
int imgThresholding(IMG *img, float threshold_level, long long *thr_nr)
int imgRegionGrowingByThreshold(IMG *img, const int sz, const int sy, const int sx, float lthr, float uthr, IMG *mask, int verbose)
int imgThresholdMaskCount(IMG *img, float minValue, float maxValue, IMG *timg, long long *count)
int imgThresholdByMask(IMG *img, IMG *templt, float thrValue)
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)
#define IMG_STATUS_OCCUPIED
Header file for libtpcimgp.
unsigned short int dimx
float **** m
char status
unsigned short int dimt
float * start
unsigned short int dimz
unsigned short int dimy
float * end
float * mid