8#include "tpcclibConfig.h"
24static char *info[] = {
25 "Slice off empty parts (rows, columns, planes) in dynamic PET image file in",
26 "ECAT, NIfTI, or Analyze format.",
28 "Usage: @P [Options] imgfile [outputfile]",
32 " Slices, where average pixel value is less than the limit value,",
33 " are cut off; by default 0.1.",
34 " -keepframes | -slimframes",
35 " Selects whether time frames can be sliced off",
36 " (by default, frames are always kept).",
40 " @P b123dy1.v b123dy1_slim.v",
42 "See also: imgdim, imgshrink, imgbkgrm, imgthrs, imgbox",
44 "Keywords: image, compression, cropping, threshold",
63int main(
int argc,
char **argv)
65 int ai, help=0, version=0, verbose=1;
66 char petfile[FILENAME_MAX], outfile[FILENAME_MAX];
67 double limit_mean=nan(
"");
74 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
75 petfile[0]=outfile[0]=(char)0;
77 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
79 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
80 if(strncasecmp(cptr,
"KEEPFRAMES", 5)==0) {
81 keep_frames=1;
continue;
82 }
else if(strncasecmp(cptr,
"SLIMFRAMES", 5)==0) {
83 keep_frames=0;
continue;
84 }
else if(strncasecmp(cptr,
"LIMIT=", 6)==0) {
87 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
92 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
97 if(ai<argc) {
strlcpy(petfile, argv[ai], FILENAME_MAX); ai++;}
98 if(ai<argc) {
strlcpy(outfile, argv[ai], FILENAME_MAX); ai++;}
99 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
104 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
107 if(!outfile[0]) strcpy(outfile, petfile);
112 printf(
"petfile := %s\n", petfile);
113 printf(
"outfile := %s\n", outfile);
114 if(!isnan(limit_mean)) printf(
"limit_mean := %g\n", limit_mean);
115 printf(
"keep_frames := %d\n", keep_frames);
118 if(isnan(limit_mean)) limit_mean=0.1;
125 if(verbose>0) printf(
"reading %s\n", petfile);
126 int ret=
imgRead(petfile, &img);
128 fprintf(stderr,
"Error: %s\n", img.
statmsg);
129 if(verbose>1) printf(
"ret=%d\n", ret);
134 fprintf(stderr,
"Error: %s is not an image.\n", petfile);
139 fprintf(stderr,
"Error: method works only for dynamic data.\n");
143 if(verbose>0) fprintf(stderr,
"Warning: missing pixel values.\n");
148 fprintf(stdout,
"image_dimensions := %d %d %d\n", img.
dimx, img.
dimy, img.
dimz);
149 fprintf(stdout,
"frame_nr := %d\n", img.
dimt);
162 SLIM_LIST xlist[img.
dimx];
163 SLIM_LIST ylist[img.
dimy];
164 SLIM_LIST zlist[img.
dimz];
165 SLIM_LIST tlist[img.
dimt];
167 for(
int xi=0; xi<img.
dimx; xi++) {
169 xlist[xi].weight=0.0;
172 for(
int yi=0; yi<img.
dimy; yi++) {
174 ylist[yi].weight=0.0;
177 for(
int zi=0; zi<img.
dimz; zi++) {
179 zlist[zi].weight=0.0;
182 for(
int ti=0; ti<img.
dimt; ti++) {
184 tlist[ti].weight=0.0;
189 for(
int zi=0; zi<img.
dimz; zi++) {
190 for(
int yi=0; yi<img.
dimy; yi++) {
191 for(
int xi=0; xi<img.
dimx; xi++) {
192 for(
int fi=0; fi<img.
dimt; fi++) {
193 xlist[xi].sum+=img.
m[zi][yi][xi][fi]; xlist[xi].weight+=1.0;
194 ylist[yi].sum+=img.
m[zi][yi][xi][fi]; ylist[yi].weight+=1.0;
195 zlist[zi].sum+=img.
m[zi][yi][xi][fi]; zlist[zi].weight+=1.0;
196 tlist[fi].sum+=img.
m[zi][yi][xi][fi]; tlist[fi].weight+=1.0;
206 for(
int xi=0; xi<img.
dimx; xi++) {
207 xlist[xi].keep=(xlist[xi].sum/xlist[xi].weight<limit_mean) ? 0 : 1 ;
209 for(
int yi=0; yi<img.
dimy; yi++) {
210 ylist[yi].keep=(ylist[yi].sum/ylist[yi].weight<limit_mean) ? 0 : 1 ;
212 for(
int zi=0; zi<img.
dimz; zi++) {
213 zlist[zi].keep=(zlist[zi].sum/zlist[zi].weight<limit_mean) ? 0 : 1 ;
215 for(
int ti=0; ti<img.
dimt; ti++) {
216 tlist[ti].keep=(tlist[ti].sum/tlist[ti].weight<limit_mean) ? 0 : 1 ;
219 printf(
"\nxlist:\n");
220 for(
int xi=0; xi<img.
dimx; xi++) {
221 printf(
" %04d %20.5f %20.5f %d\n",
222 xi+1, xlist[xi].sum, xlist[xi].weight, xlist[xi].keep);
225 for(
int yi=0; yi<img.
dimy; yi++) {
226 printf(
" %04d %20.5f %20.5f %d\n",
227 yi+1, ylist[yi].sum, ylist[yi].weight, ylist[yi].keep);
230 for(
int zi=0; zi<img.
dimz; zi++) {
231 printf(
" %04d %20.5f %20.5f %d\n",
232 zi+1, zlist[zi].sum, zlist[zi].weight, zlist[zi].keep);
235 for(
int ti=0; ti<img.
dimt; ti++) {
236 printf(
" %04d %20.5f %20.5f %d\n",
237 ti+1, tlist[ti].sum, tlist[ti].weight, tlist[ti].keep);
242 int newdimx, newdimy, newdimz, newdimt;
246 i=0;
while(i<img.
dimx && xlist[i].keep==0) i++;
248 i=img.
dimx-1;
while(i>=0 && xlist[i].keep==0) i--;
250 if(first>last) {first=0; last=img.
dimx-1;}
251 for(i=first; i<=last; i++) xlist[i].keep=1;
252 newdimx=1+last-first;
253 if(verbose>1) printf(
"x_first := %d\nx_last := %d", first, last);
258 i=0;
while(i<img.
dimy && ylist[i].keep==0) i++;
260 i=img.
dimy-1;
while(i>=0 && ylist[i].keep==0) i--;
262 if(first>last) {first=0; last=img.
dimy-1;}
263 for(i=first; i<=last; i++) ylist[i].keep=1;
264 newdimy=1+last-first;
265 if(verbose>1) printf(
"y_first := %d\ny_last := %d", first, last);
270 i=0;
while(i<img.
dimz && zlist[i].keep==0) i++;
272 i=img.
dimz-1;
while(i>=0 && zlist[i].keep==0) i--;
274 if(first>last) {first=0; last=img.
dimz-1;}
275 for(i=first; i<=last; i++) zlist[i].keep=1;
276 newdimz=1+last-first;
277 if(verbose>1) printf(
"z_first := %d\nz_last := %d", first, last);
282 i=0;
while(i<img.
dimt && tlist[i].keep==0) i++;
284 i=img.
dimt-1;
while(i>=0 && tlist[i].keep==0) i--;
286 if(first>last) {first=0; last=img.
dimt-1;}
287 for(i=first; i<=last; i++) tlist[i].keep=1;
288 newdimt=1+last-first;
289 if(verbose>1) printf(
"t_first := %d\nt_last := %d", first, last);
293 if(keep_frames && newdimt<img.
dimt) {
294 if(verbose>1) printf(
"keeping all time frames\n");
295 for(
int ti=0; ti<img.
dimt; ti++) tlist[ti].keep=1;
300 printf(
"\nxlist:\n");
301 for(
int xi=0; xi<img.
dimx; xi++) {
302 printf(
" %04d %20.5f %20.5f %d\n",
303 xi+1, xlist[xi].sum, xlist[xi].weight, xlist[xi].keep);
306 for(
int yi=0; yi<img.
dimy; yi++) {
307 printf(
" %04d %20.5f %20.5f %d\n",
308 yi+1, ylist[yi].sum, ylist[yi].weight, ylist[yi].keep);
311 for(
int zi=0; zi<img.
dimz; zi++) {
312 printf(
" %04d %20.5f %20.5f %d\n",
313 zi+1, zlist[zi].sum, zlist[zi].weight, zlist[zi].keep);
316 for(
int ti=0; ti<img.
dimt; ti++) {
317 printf(
" %04d %20.5f %20.5f %d\n",
318 ti+1, tlist[ti].sum, tlist[ti].weight, tlist[ti].keep);
322 printf(
" new_dimx := %d\n", newdimx);
323 printf(
" new_dimy := %d\n", newdimy);
324 printf(
" new_dimz := %d\n", newdimz);
325 printf(
" new_dimt := %d\n", newdimt);
328 if(newdimx==img.
dimx && newdimy==img.
dimy && newdimz==img.
dimz && newdimt==img.
dimt) {
329 fprintf(stderr,
"Error: cannot slim-off anything from %s\n", petfile);
333 if(newdimx==0 || newdimy==0 || newdimz==0 || newdimt==0) {
334 fprintf(stderr,
"Error: this would result in empty image.\n");
344 fprintf(stderr,
"Error: cannot make output image.\n");
348 for(
int ti=0, nti=0; ti<img.
dimt; ti++)
if(tlist[ti].keep==1) {
349 for(
int zi=0, nzi=0; zi<img.
dimz; zi++)
if(zlist[zi].keep==1) {
350 for(
int yi=0, nyi=0; yi<img.
dimy; yi++)
if(ylist[yi].keep==1) {
351 for(
int xi=0, nxi=0; xi<img.
dimx; xi++)
if(xlist[xi].keep==1) {
352 out.
m[nzi][nyi][nxi][nti]=img.
m[zi][yi][xi][ti];
370 if(verbose>1) fprintf(stdout,
"writing image...\n");
373 fprintf(stderr,
"Error: %s\n", out.
statmsg);
376 if(verbose==1) printf(
"Written image %s\n", outfile);
379 if(verbose>0) printf(
"done.\n");
int atof_with_check(char *double_as_string, double *result_value)
unsigned long long imgNaNs(IMG *img, int fix)
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
void imgEmpty(IMG *image)
int imgRead(const char *fname, IMG *img)
int imgWrite(const char *fname, IMG *img)
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)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Header file for libtpcmodel.