TPCCLIB
Loading...
Searching...
No Matches
mask.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "libtpcimgp.h"
7/*****************************************************************************/
8
9/*****************************************************************************/
15long long imgMaskCount(
17 IMG *img
18) {
19 long long n=0;
20 int zi, yi, xi;
21 for(zi=0; zi<img->dimz; zi++)
22 for(yi=0; yi<img->dimy; yi++)
23 for(xi=0; xi<img->dimx; xi++)
24 if(img->m[zi][yi][xi][0]>0.0) n++;
25 return(n);
26}
27/*****************************************************************************/
28
29/*****************************************************************************/
36 IMG *img,
39 IMG *se
40) {
41 if(img==NULL || se==NULL) return(-1);
42 if(img->dimx<1 || img->dimy<1 || img->dimz<1) return(-2);
43 if(se->dimx<1 || se->dimy<1 || se->dimz<1) return(-3);
44 if(se->dimx%2==0 || se->dimy%2==0 || se->dimz%2==0) return(-4);
45
46
47 /* make a copy of original data */
48 IMG orig; imgInit(&orig);
49 if(imgDup(img, &orig)!=0) return(-5);
50 long long n=0;
51 int zi, yi, xi, zj, yj, xj;
52 for(zi=0; zi<orig.dimz; zi++)
53 for(yi=0; yi<orig.dimy; yi++)
54 for(xi=0; xi<orig.dimx; xi++)
55 if(orig.m[zi][yi][xi][0]>0.0) {
56 int zs, ys, xs;
57 float miv=+1.0E+20;
58 for(zs=0; zs<se->dimz; zs++)
59 for(ys=0; ys<se->dimy; ys++)
60 for(xs=0; xs<se->dimx; xs++)
61 if(se->m[zs][ys][xs][0]>0.0) {
62 zj=zi+(zs-se->dimz/2); if(zj<0 || zj>=orig.dimz) continue;
63 yj=yi+(ys-se->dimy/2); if(yj<0 || yj>=orig.dimy) continue;
64 xj=xi+(xs-se->dimx/2); if(xj<0 || xj>=orig.dimx) continue;
65 if(orig.m[zj][yj][xj][0]<miv) miv=orig.m[zj][yj][xj][0];
66 }
67 if(!(miv>1.0E-20)) {img->m[zi][yi][xi][0]=0.0; n++;}
68 }
69 imgEmpty(&orig);
70
71 return(n);
72}
73/*****************************************************************************/
74
75/*****************************************************************************/
82 IMG *img,
85 IMG *se
86) {
87 if(img==NULL || se==NULL) return(-1);
88 if(img->dimx<1 || img->dimy<1 || img->dimz<1) return(-2);
89 if(se->dimx<1 || se->dimy<1 || se->dimz<1) return(-3);
90 if(se->dimx%2==0 || se->dimy%2==0 || se->dimz%2==0) return(-4);
91
92
93 /* make a copy of original data */
94 IMG orig; imgInit(&orig);
95 if(imgDup(img, &orig)!=0) return(-5);
96 long long n=0;
97 int zi, yi, xi, zj, yj, xj;
98 for(zi=0; zi<orig.dimz; zi++)
99 for(yi=0; yi<orig.dimy; yi++)
100 for(xi=0; xi<orig.dimx; xi++)
101 if(orig.m[zi][yi][xi][0]==0.0) {
102 int zs, ys, xs;
103 float mav=-1.0E+20;
104 for(zs=0; zs<se->dimz; zs++)
105 for(ys=0; ys<se->dimy; ys++)
106 for(xs=0; xs<se->dimx; xs++)
107 if(se->m[zs][ys][xs][0]>0.0) {
108 zj=zi+(zs-se->dimz/2); if(zj<0 || zj>=orig.dimz) continue;
109 yj=yi+(ys-se->dimy/2); if(yj<0 || yj>=orig.dimy) continue;
110 xj=xi+(xs-se->dimx/2); if(xj<0 || xj>=orig.dimx) continue;
111 if(orig.m[zj][yj][xj][0]>mav) mav=orig.m[zj][yj][xj][0];
112 }
113 if(mav>0.0) {img->m[zi][yi][xi][0]=mav; n++;}
114 }
115 imgEmpty(&orig);
116
117 return(n);
118}
119/*****************************************************************************/
120
121/*****************************************************************************/
128 IMG *img,
134 const int structuring_element,
136 int verbose
137) {
138 if(img==NULL) return(1);
139 imgEmpty(img);
140
141 int ret=0;
142 if(structuring_element==1) {
143 if(verbose>0) printf("making cube as the structuring element\n");
144 ret=imgAllocate(img, 3, 3, 3, 1);
145 } else if(structuring_element==2) {
146 if(verbose>0) printf("making rounded cube as the structuring element\n");
147 ret=imgAllocate(img, 3, 3, 3, 1);
148 } else if(structuring_element==3) {
149 if(verbose>0) printf("making star as the structuring element\n");
150 ret=imgAllocate(img, 3, 3, 3, 1);
151 } else {
152 fprintf(stderr, "Error: unsupported structuring element.\n");
153 return(2);
154 }
155 if(verbose>0) {fflush(stdout);}
156 if(ret) {
157 fprintf(stderr, "Error: cannot allocate memory.\n");
158 imgEmpty(img);
159 return(3);
160 }
161
162 int z, y, x, n;
163
164 if(structuring_element==1) { // 3x3x3 cube
165 for(z=0; z<3; z++)
166 for(y=0; y<3; y++)
167 for(x=0; x<3; x++)
168 img->m[z][y][x][0]=1.0;
169 } else if(structuring_element==2) { // rounded 3x3x3 cube
170 for(z=0; z<3; z++)
171 for(y=0; y<3; y++)
172 for(x=0; x<3; x++)
173 if(z==1 || y==1 || x==1)
174 img->m[z][y][x][0]=1.0;
175 else
176 img->m[z][y][x][0]=0.0;
177 } else if(structuring_element==3) { // 7-voxel star
178 for(z=0; z<3; z++)
179 for(y=0; y<3; y++)
180 for(x=0; x<3; x++) {
181 n=0;
182 if(z==1) n++;
183 if(y==1) n++;
184 if(x==1) n++;
185 if(n>1)
186 img->m[z][y][x][0]=1.0;
187 else
188 img->m[z][y][x][0]=0.0;
189 }
190 }
191
192 if(verbose>3) {
193 int z, y, x;
194 printf("\nplanes 1-3\n");
195 for(x=0; x<3; x++) {
196 for(z=0; z<3; z++) {
197 for(y=0; y<3; y++)
198 printf(" %g", img->m[z][y][x][0]);
199 printf(" ");
200 }
201 printf("\n");
202 }
203 printf("\n");
204 }
205 return(0);
206}
207/*****************************************************************************/
208
209/*****************************************************************************/
218 IMG *img
219) {
220 if(img==NULL) return;
221 int zi, yi, xi;
222 for(zi=0; zi<img->dimz; zi++)
223 for(yi=0; yi<img->dimy; yi++)
224 for(xi=0; xi<img->dimx; xi++)
225 if(fabs(img->m[zi][yi][xi][0])>1.0E-12)
226 img->m[zi][yi][xi][0]=0.0;
227 else
228 img->m[zi][yi][xi][0]=1.0;
229 return;
230}
231/*****************************************************************************/
232
233/*****************************************************************************/
241 IMG *mask1,
243 IMG *mask2
244) {
245 if(mask1==NULL || mask2==NULL) return(1);
246 if(mask1->dimx<1 || mask1->dimy<1 || mask1->dimz<1) return(2);
247 if(mask1->dimx!=mask2->dimx) return(3);
248 if(mask1->dimy!=mask2->dimy) return(4);
249 if(mask1->dimz!=mask2->dimz) return(5);
250
251 int zi, yi, xi;
252 for(zi=0; zi<mask1->dimz; zi++)
253 for(yi=0; yi<mask1->dimy; yi++)
254 for(xi=0; xi<mask1->dimx; xi++) {
255 if(fabs(mask1->m[zi][yi][xi][0])<1.0E-12 ||
256 fabs(mask2->m[zi][yi][xi][0])<1.0E-12)
257 {
258 mask1->m[zi][yi][xi][0]=0.0;
259 } else {
260 mask1->m[zi][yi][xi][0]=1.0;
261 }
262 }
263
264 return(0);
265}
266/*****************************************************************************/
267
268/*****************************************************************************/
283 IMG *mask1,
286 IMG *mask2,
288 int *n,
290 int verbose
291) {
292 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
293 if(mask1==NULL || mask2==NULL || mask1==mask2) return(1);
294 if(mask1->status!=IMG_STATUS_OCCUPIED) return(2);
295 if(mask1->dimx<1 || mask1->dimy<1 || mask1->dimz<1) return(3);
296 if(verbose>1) printf("mask dimensions := %d x %d x %d\n", mask1->dimx, mask1->dimy, mask1->dimz);
297 if(n!=NULL) *n=0;
298
299 /* Make a copy of the mask */
300 imgEmpty(mask2);
301 long long nr;
302 if(imgThresholdMaskCount(mask1, 0.1, 1.0E+22, mask2, &nr)!=0) {
303 if(verbose>0) fprintf(stderr, "Error: cannot make initial copy of mask.\n");
304 return(11);
305 }
306 if(nr==0) {
307 if(verbose>0) fprintf(stderr, "Warning: empty mask.\n");
308 return(0);
309 }
310 if(verbose>1) printf("mask contains %lld foreground pixels.\n", nr);
311 if(verbose>80) {
312 for(int zi=0; zi<mask2->dimz; zi++)
313 for(int yi=0; yi<mask2->dimy; yi++)
314 for(int xi=0; xi<mask2->dimx; xi++)
315 if(mask2->m[zi][yi][xi][0]!=0.0)
316 printf(" %d,%d,%d\n", zi, yi, xi);
317 }
318
319 /* Label regions */
320 int ret=0, nextLabel=2;
321 for(int zi=0; zi<mask2->dimz; zi++)
322 for(int yi=0; yi<mask2->dimy; yi++)
323 for(int xi=0; xi<mask2->dimx; xi++)
324 if(mask2->m[zi][yi][xi][0]==1.0) {
325 ret=imgMaskFloodFill(mask2, zi, yi, xi, nextLabel, &nr, verbose);
326 if(ret!=0) break;
327 if(verbose>2) printf("%lld pixels labelled as %d\n", nr, nextLabel);
328 nextLabel++;
329 }
330 if(ret!=0) {
331 if(verbose>0) fprintf(stderr, "Error: Flood fill failed.\n");
332 imgEmpty(mask2); return(21);
333 }
334 if(verbose>0) printf("%d regions labelled.\n", nextLabel-2);
335 if(n!=NULL) *n=nextLabel-2;
336
337 return(0);
338}
339/*****************************************************************************/
340
341/*****************************************************************************/
357 IMG *m,
359 int sz,
361 int sy,
363 int sx,
365 int label,
367 long long *n,
369 int verbose
370) {
371 if(verbose>0) {
372 printf("%s(mask, %d, %d, %d, %d)\n", __func__, sz, sy, sx, label);
373 fflush(stdout);
374 }
375 if(m==NULL || m->status!=IMG_STATUS_OCCUPIED) return(1);
376 if(m->dimx<1 || m->dimy<1 || m->dimz<1) return(2);
377 if(sx<0 || sy<0 || sz<0 || sx>=m->dimx || sy>=m->dimy || sz>=m->dimz) return(3);
378 if(label<2) return(4);
379 if(n!=NULL) *n=0;
380
381 /* Create empty stack of pixel coordinates */
382 IMG_PIXELS pxls; pxlInit(&pxls);
383
384 /* Put the start coordinate into the stack */
385 IMG_PIXEL pxl; pxl.x=sx; pxl.y=sy; pxl.z=sz;
386 if(pxlAdd(&pxls, &pxl)!=0) {
387 if(verbose>0) fprintf(stderr, "Error: cannot add seed pixel to stack.\n");
388 pxlFree(&pxls); return(11);
389 }
390
391 /* Process the stack until empty */
392 unsigned long long int pxlNr=0;
393 while(pxls.pxlNr>0) {
394 /* Take the last pixel from the list */
395 if(pxlGet(&pxls, pxls.pxlNr-1, &pxl)!=0) break;
396 pxls.pxlNr--;
397 /* Should this pixel be labelled? */
398 if(verbose>100) printf(" m[%d][%d][%d] := %g\n", pxl.z, pxl.y, pxl.x, m->m[pxl.z][pxl.y][pxl.x][0]);
399 if(pxl.z<0 || pxl.z>=m->dimz || pxl.y<0 || pxl.y>=m->dimy || pxl.x<0 || pxl.x>=m->dimx)
400 continue; // certainly not since outside of the image
401 if(m->m[pxl.z][pxl.y][pxl.x][0]!=1.0) continue; // no since labelled or part of background
402 m->m[pxl.z][pxl.y][pxl.x][0]=(float)label; // yes
403 if(verbose>100) printf(" -> m[%d][%d][%d] := %g\n", pxl.z, pxl.y, pxl.x, m->m[pxl.z][pxl.y][pxl.x][0]);
404 pxlNr++;
405 /* Add the 26 neighbours to the beginning of the stack */
406 if(pxlMakeRoom(&pxls, 0, 26)!=0) break;
407 if(pxls.pxlNr==0) pxls.pxlNr=26;
408 if(verbose>100) printf(" pxls.pxlNr := %lld\n", pxls.pxlNr);
409 unsigned long long int i=0;
410 for(int dz=-1; dz<2; dz++) for(int dy=-1; dy<2; dy++) for(int dx=-1; dx<2; dx++) {
411 if(dz==0 && dy==0 && dx==0) continue;
412 pxls.p[i].z=pxl.z+dz; pxls.p[i].y=pxl.y+dy; pxls.p[i].x=pxl.x+dx;
413 i++;
414 }
415 }
416 pxlFree(&pxls);
417 if(verbose>1) printf(" %lld pixels labelled.\n", pxlNr);
418 if(n!=NULL) *n=pxlNr;
419 if(pxlNr==0) return(21);
420 return(0);
421}
422/*****************************************************************************/
423
424/*****************************************************************************/
431 IMG *img,
433 int dim,
435 float id
436) {
437 if(img==NULL) return(1);
438 int dimx=img->dimx, dimy=img->dimy, dimz=img->dimz;
439 if(dimx<1 || dimy<1 || dimz<1) return(2);
440
441 for(int z=0; z<dimz; z++) {
442 for(int y=0; y<dimy; y++) {
443 for(int x=0; x<dimx; x++) if(!(img->m[z][y][x][0]<0.5) && img->m[z][y][x][0]!=id) {
444 int x1=x, x2=x, y1=y, y2=y, z1=z, z2=z;
445 if(x>0) x1=x-1;
446 if(x<dimx-1) x2=x+1;
447 if(y>0) y1=y-1;
448 if(y<dimy-1) y2=y+1;
449 if(dim==3) {
450 if(z>0) z1=z-1;
451 if(z<dimz-1) z2=z+1;
452 }
453 for(int nz=z1; nz<=z2; nz++)
454 for(int ny=y1; ny<=y2; ny++)
455 for(int nx=x1; nx<=x2; nx++)
456 if(z!=nz || y!=ny || x!=nx)
457 if(img->m[nz][ny][nx][0]<0.5)
458 img->m[nz][ny][nx][0]=id;
459 }
460 }
461 }
462
463 return(0);
464}
465/*****************************************************************************/
466
467/*****************************************************************************/
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition img.c:194
int imgDup(IMG *img1, IMG *img2)
Definition img.c:304
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgThresholdMaskCount(IMG *img, float minValue, float maxValue, IMG *timg, long long *count)
int pxlMakeRoom(IMG_PIXELS *list, long long int i, long long int n)
Definition pixel.c:110
void pxlFree(IMG_PIXELS *pxl)
Definition pixel.c:28
#define IMG_STATUS_OCCUPIED
int pxlGet(IMG_PIXELS *list, long long int i, IMG_PIXEL *pxl)
Definition pixel.c:163
int pxlAdd(IMG_PIXELS *list, IMG_PIXEL *pxl)
Definition pixel.c:139
void pxlInit(IMG_PIXELS *pxl)
Definition pixel.c:14
Header file for libtpcimgp.
long long imgMaskCount(IMG *img)
Definition mask.c:15
int imgMaskRegionLabeling(IMG *mask1, IMG *mask2, int *n, int verbose)
Definition mask.c:279
int imgMaskCloak(IMG *img, int dim, float id)
Definition mask.c:429
int imgMaskFloodFill(IMG *m, int sz, int sy, int sx, int label, long long *n, int verbose)
Definition mask.c:352
void imgMaskInvert(IMG *img)
Definition mask.c:216
int imgStructuringElement(IMG *img, const int structuring_element, int verbose)
Definition mask.c:126
int imgMaskDilate(IMG *img, IMG *se)
Definition mask.c:80
int imgMaskErode(IMG *img, IMG *se)
Definition mask.c:34
int imgMaskConjunction(IMG *mask1, IMG *mask2)
Definition mask.c:238
IMG_PIXEL * p
long long int pxlNr
unsigned short int dimx
float **** m
char status
unsigned short int dimz
unsigned short int dimy