TPCCLIB
Loading...
Searching...
No Matches
masksize.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/*****************************************************************************/
17#include "libtpcmisc.h"
18#include "libtpcimgio.h"
19#include "libtpcimgp.h"
20/*****************************************************************************/
21
22/*****************************************************************************/
23static char *info[] = {
24 "Report the number of pixels belonging to labelled regions in mask image",
25 "in ECAT 6.3 or 7.x, NIfTI-1, or Analyze 7.5 format.",
26 " ",
27 "Usage: @P [Options] maskfile",
28 " ",
29 "Options:",
30 " -sort",
31 " Region labels are modified so that label 1 will represent the largest,",
32 " label 2 the second largets, and so on.",
33 " Notice that this option will overwrite the mask file.",
34 " -stdoptions", // List standard options like --help, -v, etc
35 " ",
36 "See also: masklbl, imgthrs, maskconj, imgmask, mask2pxl",
37 " ",
38 "Keywords: image, mask, ROI",
39 0};
40/*****************************************************************************/
41
42/*****************************************************************************/
43/* Turn on the globbing of the command line, since it is disabled by default in
44 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
45 In Unix&Linux wildcard command line processing is enabled by default. */
46/*
47#undef _CRT_glob
48#define _CRT_glob -1
49*/
50int _dowildcard = -1;
51/*****************************************************************************/
52
53/*****************************************************************************/
57int main(int argc, char **argv)
58{
59 int ai, help=0, version=0, verbose=1;
60 int ret, n;
61 char maskfile[FILENAME_MAX];
62 int sortLabels=0; // 0=no sorting, 1=sort
63 char *cptr=NULL;
64
65
66 /*
67 * Get arguments
68 */
69 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
70 maskfile[0]=(char)0;
71 /* Options */
72 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
73 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
74 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
75 if(strcasecmp(cptr, "SORT")==0) {
76 sortLabels=1; continue;
77 }
78 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
79 return(1);
80 } else break;
81
82 /* Print help or version? */
83 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
84 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
85 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
86
87 /* Process other arguments, starting from the first non-option */
88 if(ai<argc) {strlcpy(maskfile, argv[ai], FILENAME_MAX); ai++;}
89 if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
90
91 /* Did we get all the information that we need? */
92 if(!maskfile[0]) {
93 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
94 return(1);
95 }
96
97
98 /* In verbose mode print options */
99 if(verbose>1) {
100 printf("maskfile := %s\n", maskfile);
101 printf("sortLabels := %d\n", sortLabels);
102 fflush(stdout);
103 }
104
105
106 /*
107 * Read mask
108 */
109 IMG mask; imgInit(&mask);
110
111 if(verbose>0) {printf("reading %s\n", maskfile); fflush(stdout);}
112 ret=imgRead(maskfile, &mask);
113 if(ret) {
114 fprintf(stderr, "Error: %s\n", mask.statmsg);
115 if(verbose>1) printf("ret := %d\n", ret);
116 return(2);
117 }
118 if(mask.dimt>1) {
119 fprintf(stderr, "Error: mask cannot be dynamic image.\n");
120 imgEmpty(&mask); return(2);
121 }
122 if(verbose>0 || sortLabels==0) {
123 printf("xdim := %d\n", mask.dimx);
124 printf("ydim := %d\n", mask.dimy);
125 printf("zdim := %d\n", mask.dimz);
126 printf("pxlNr := %d\n", mask.dimx*mask.dimy*mask.dimz);
127 }
128
129 /*
130 * Get the region labels and count the number of pixels belonging to each of them
131 */
132 int zi, yi, xi;
133 /* Search the maximum pixel value */
134 float mv=0.0;
135 for(zi=0; zi<mask.dimz; zi++)
136 for(yi=0; yi<mask.dimy; yi++)
137 for(xi=0; xi<mask.dimx; xi++)
138 if(mask.m[zi][yi][xi][0]>mv)
139 mv=mask.m[zi][yi][xi][0];
140 if(verbose>1) printf("maxval := %g\n", mv);
141 /* Based on that, set the max number of labels */
142 int maxLabel=(int)roundf(mv);
143 if(verbose>1) printf("maxlabel := %d\n", maxLabel);
144 if(maxLabel==0) {
145 fprintf(stderr, "Error: mask file does not contain any labelled pixels.\n");
146 imgEmpty(&mask); return(3);
147 }
148 if(maxLabel>10000) {
149 fprintf(stderr, "Error: mask file contains too many labels.\n");
150 imgEmpty(&mask); return(3);
151 }
152 /* Allocate a list for pixel number having a certain label */
153 int pxlNr[maxLabel+1];
154 for(int i=0; i<=maxLabel; i++) pxlNr[i]=0;
155 /* Count the pixels with each label */
156 for(zi=0; zi<mask.dimz; zi++)
157 for(yi=0; yi<mask.dimy; yi++)
158 for(xi=0; xi<mask.dimx; xi++) {
159 n=(int)roundf(mask.m[zi][yi][xi][0]);
160 if(n<0) n=0;
161 pxlNr[n]++;
162 }
163 /* List the pixel numbers, if >0 */
164 printf("Number of pixels per label:\n");
165 int bl=0, ms=0;
166 n=0;
167 for(int i=0; i<=maxLabel; i++) {
168 if(pxlNr[i]>0) printf("label_%d := %d\n", i, pxlNr[i]);
169 if(i==0) continue;
170 n+=pxlNr[i];
171 if(pxlNr[i]>ms) {ms=pxlNr[i]; bl=i;}
172 }
173 printf("totalNr := %d\n", n);
174 printf("largestRegion := %d\n", bl);
175 printf("largestSize := %d\n", ms);
176
177 /*
178 * If user did not want sorting, then we are ready
179 */
180 if(sortLabels==0) {imgEmpty(&mask); return(0);}
181
182
183 /*
184 * Determine new labels, based on region size
185 */
186 int newLabel[maxLabel+1];
187 for(int i=0; i<=maxLabel; i++) newLabel[i]=0;
188 /* Largest region will get label 1 */
189 int currLabel=1;
190 newLabel[bl]=currLabel; pxlNr[bl]=0;
191 while(1) {
192 /* Find the next highest */
193 bl=ms=0; currLabel++;
194 for(int i=1; i<=maxLabel; i++) {
195 if(pxlNr[i]>ms) {ms=pxlNr[i]; bl=i;}
196 }
197 if(verbose>10) printf("currLabel=%d ms=%d bl=%d\n", currLabel, ms, bl);
198 if(ms==0) break;
199 newLabel[bl]=currLabel; pxlNr[bl]=0;
200 }
201 if(verbose>2) {
202 printf("relabelling:\n");
203 for(int i=1; i<=maxLabel; i++) printf(" %d -> %d\n", i, newLabel[i]);
204 }
205
206 /*
207 * Relabel each mask pixel
208 */
209 for(zi=0; zi<mask.dimz; zi++)
210 for(yi=0; yi<mask.dimy; yi++)
211 for(xi=0; xi<mask.dimx; xi++) {
212 n=(int)roundf(mask.m[zi][yi][xi][0]);
213 if(n<0) n=0;
214 mask.m[zi][yi][xi][0]=(float)newLabel[n];
215 pxlNr[n]++;
216 }
217
218
219 /*
220 * Save the modified mask
221 */
222 if(verbose>2) printf("writing sorted mask...\n");
223 ret=imgWrite(maskfile, &mask);
224 if(ret) {
225 fprintf(stderr, "Error: %s\n", mask.statmsg);
226 imgEmpty(&mask); return(11);
227 }
228 imgEmpty(&mask);
229 if(verbose>0) printf("sorted mask written.\n\n");
230
231 return(0);
232}
233/*****************************************************************************/
234
235/*****************************************************************************/
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgRead(const char *fname, IMG *img)
Definition imgfile.c:26
int imgWrite(const char *fname, IMG *img)
Definition imgfile.c:136
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)
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
float **** m
unsigned short int dimt
unsigned short int dimz
unsigned short int dimy
const char * statmsg