TPCCLIB
Loading...
Searching...
No Matches
imgmove.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 "Move specified image frames in x,y-directions. Only for simulation use:",
25 "this is not convenient nor valid method for movement correction, because",
26 "attenuation correction is not moved accordingly.",
27 " ",
28 "Usage: @P [Options] imgfile x y [frames [outputfile]]",
29 " ",
30 "Image file can be in ECAT 6.3 or 7.x, NIfTI-1, or Analyze 7.5 format.",
31 "Movements in x and y directions are given in pixels, with positive number",
32 "meaning right/up and negative number meaning left/down.",
33 "If name for output file is not given, then the original image is overwritten.",
34 "If also frame(s) are not given, then all frames are moved.",
35 " ",
36 "Options:",
37 " -fill",
38 " New image area is filled with neighbouring pixel values",
39 " (by default with zeroes).",
40 " -stdoptions", // List standard options like --help, -v, etc
41 " ",
42 "Example: Move pixels in frames 14-16 upwards by two pixels",
43 " @P ua2918dy1.v 0 2 14-16 ua2918dy1mov.v",
44 " ",
45 "See also: imgadd, simcirc, simboxes, flat2img",
46 " ",
47 "Keywords: image, simulation, software testing, mask",
48 0};
49/*****************************************************************************/
50
51/*****************************************************************************/
52/* Turn on the globbing of the command line, since it is disabled by default in
53 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
54 In Unix&Linux wildcard command line processing is enabled by default. */
55/*
56#undef _CRT_glob
57#define _CRT_glob -1
58*/
59int _dowildcard = -1;
60/*****************************************************************************/
61
62/*****************************************************************************/
66int main(int argc, char **argv)
67{
68 int ai, help=0, version=0, verbose=1;
69 int ret;
70 int fill_area=0; // 0=fill with zeroes, 1=fill with neighbour values
71 char imgfile[FILENAME_MAX], outfile[FILENAME_MAX];
72 int xmov=0, ymov=0;
73
74
75 /*
76 * Get arguments
77 */
78 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
79 imgfile[0]=outfile[0]=(char)0;
80 INTEGER_LIST framelist; integerListInit(&framelist);
81 /* Options */
82 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
83 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
84 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
85 if(strncasecmp(cptr, "FILL", 3)==0) {
86 fill_area=1; continue;
87 }
88 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
89 return(1);
90 } else break;
91
92 /* Print help or version? */
93 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
94 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
95 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
96
97 /* Process other arguments, starting from the first non-option */
98 if(ai<argc) {strlcpy(imgfile, argv[ai], FILENAME_MAX); ai++;}
99 if(ai<argc) {
100 if(atoi_with_check(argv[ai++], &xmov)) {fprintf(stderr, "Error: invalid x."); return(1);}
101 }
102 if(ai<argc) {
103 if(atoi_with_check(argv[ai++], &ymov)) {fprintf(stderr, "Error: invalid y."); return(1);}
104 } else {
105 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
106 return(1);
107 }
108 if(ai<argc) {
109 if(verbose>3) printf("requested_frames: '%s'\n", argv[ai]);
110 if(integerListExpandFromString(argv[ai++], ",;", &framelist, 1)<1) {
111 fprintf(stderr, "Error: invalid frame definition.\n");
112 return(1);
113 }
114 integerListSort(&framelist);
115 }
116 if(ai<argc) {strlcpy(outfile, argv[ai], FILENAME_MAX); ai++;}
117 if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
118
119 /* Did we get all the information that we need? */
120 if(!imgfile[0]) {
121 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
122 return(1);
123 }
124 if(xmov==0 && ymov==0) {fprintf(stderr, "Error: no movement was required.\n"); return(1);}
125 if(!outfile[0]) strcpy(outfile, imgfile);
126
127
128 /* In verbose mode print options */
129 if(verbose>1) {
130 printf("imgfile := %s\n", imgfile);
131 printf("outfile := %s\n", outfile);
132 printf("fill := %d\n", fill_area);
133 printf("x := %d\n", xmov);
134 printf("y := %d\n", ymov);
135 if(framelist.nr>0) {
136 printf("frames := %d", framelist.list[0]);
137 for(int li=1; li<framelist.nr; li++) printf(", %d", framelist.list[li]);
138 printf("\n");
139 }
140 }
141
142
143 /*
144 * Read PET image
145 */
146 if(verbose>0) printf("reading %s\n", imgfile);
147 IMG img; imgInit(&img);
148 ret=imgRead(imgfile, &img);
149 if(ret) {
150 fprintf(stderr, "Error: %s\n", img.statmsg);
151 if(verbose>1) printf("ret := %d\n", ret);
152 integerListEmpty(&framelist); return(2);
153 }
154 /* Check if PET data is raw or image */
155 if(img.type!=IMG_TYPE_IMAGE) {
156 fprintf(stderr, "Error: %s is not an image.\n", imgfile);
157 imgEmpty(&img); integerListEmpty(&framelist); return(2);
158 }
159 if(verbose>1) {
160 printf("dimt := %d\n", img.dimt);
161 printf("dimx := %d\n", img.dimx);
162 printf("dimy := %d\n", img.dimy);
163 printf("dimz := %d\n", img.dimz);
164 }
165 /* Check that xmov and ymov are inside matrix size */
166 if(abs(xmov)>=img.dimx || abs(ymov)>=img.dimy) {
167 fprintf(stderr, "Error: cannot move outsize image matrix.\n");
168 imgEmpty(&img); integerListEmpty(&framelist); return(2);
169 }
170 /* Check that at least one of specified frames is found in image */
171 int movNr=0;
172 if(framelist.nr>0) {
173 for(int li=0; li<framelist.nr; li++)
174 if(framelist.list[li]>0 && framelist.list[li]<=img.dimt) movNr++;
175 if(movNr==0) {
176 fprintf(stderr, "Error: image does not contain specified frames.\n");
177 imgEmpty(&img); return(2);
178 }
179 if(verbose>1 && movNr!=framelist.nr) printf("%d frame(s) will be moved.\n", movNr);
180 } else {
181 movNr=img.dimt;
182 }
183 /* Fill framelist with all frame numbers, if not given by user */
184 if(framelist.nr==0) {
185 for(int fi=1; fi<=img.dimt; fi++) integerListAdd(&framelist, fi, 0);
186 if(verbose>1) {
187 printf("frames := %d", framelist.list[0]);
188 for(int li=1; li<framelist.nr; li++) printf(", %d", framelist.list[li]);
189 printf("\n");
190 }
191 }
192
193
194 /*
195 * Movement
196 */
197 if(verbose>0) printf("processing...\n");
198 ymov=-ymov;
199 int fi, zi, yi, xi;
200 for(int li=0, movNr=0; li<framelist.nr; li++) {
201 fi=framelist.list[li]-1; if(fi<0 || fi>=img.dimt) continue;
202 if(verbose>2) printf(" moving pixels on frame %d\n", fi+1);
203 /* Movement in y direction */
204 if(ymov<0) {
205 for(yi=-ymov; yi<img.dimy; yi++) {
206 if(verbose>8) printf("y: [%d] -> [%d]\n", yi, yi+ymov);
207 for(zi=0; zi<img.dimz; zi++) for(xi=0; xi<img.dimx; xi++)
208 img.m[zi][yi+ymov][xi][fi]=img.m[zi][yi][xi][fi];
209 }
210 for(yi=img.dimy+ymov; yi<img.dimy; yi++) {
211 if(verbose>8) printf("y: [%d]=0\n", yi);
212 for(zi=0; zi<img.dimz; zi++) for(xi=0; xi<img.dimx; xi++)
213 if(fill_area && yi>0)
214 img.m[zi][yi][xi][fi]=img.m[zi][yi-1][xi][fi];
215 else
216 img.m[zi][yi][xi][fi]=0.0;
217 }
218 } else if(ymov>0) {
219 for(yi=img.dimy-ymov-1; yi>=0; yi--) {
220 if(verbose>8) printf("y: [%d] -> [%d]\n", yi, yi+ymov);
221 for(zi=0; zi<img.dimz; zi++) for(xi=0; xi<img.dimx; xi++)
222 img.m[zi][yi+ymov][xi][fi]=img.m[zi][yi][xi][fi];
223 }
224 for(yi=ymov-1; yi>=0; yi--) {
225 if(verbose>8) printf("y: [%d]=0\n", yi);
226 for(zi=0; zi<img.dimz; zi++) for(xi=0; xi<img.dimx; xi++)
227 if(fill_area && yi<img.dimy-1)
228 img.m[zi][yi][xi][fi]=img.m[zi][yi+1][xi][fi];
229 else
230 img.m[zi][yi][xi][fi]=0.0;
231 }
232 }
233 /* Movement in x direction */
234 if(xmov<0) {
235 for(xi=-xmov; xi<img.dimx; xi++) {
236 if(verbose>8) printf("x: [%d] -> [%d]\n", xi, xi+xmov);
237 for(zi=0; zi<img.dimz; zi++) for(yi=0; yi<img.dimy; yi++)
238 img.m[zi][yi][xi+xmov][fi]=img.m[zi][yi][xi][fi];
239 }
240 for(xi=img.dimx+xmov; xi<img.dimx; xi++) {
241 if(verbose>8) printf("x: [%d]=0\n", xi);
242 for(zi=0; zi<img.dimz; zi++) for(yi=0; yi<img.dimy; yi++)
243 if(fill_area && xi>0)
244 img.m[zi][yi][xi][fi]=img.m[zi][yi][xi-1][fi];
245 else
246 img.m[zi][yi][xi][fi]=0.0;
247 }
248 } else if(xmov>0) {
249 for(xi=img.dimx-xmov-1; xi>=0; xi--) {
250 if(verbose>8) printf("x: [%d] -> [%d]\n", xi, xi+xmov);
251 for(zi=0; zi<img.dimz; zi++) for(yi=0; yi<img.dimy; yi++)
252 img.m[zi][yi][xi+xmov][fi]=img.m[zi][yi][xi][fi];
253 }
254 for(xi=xmov-1; xi>=0; xi--) {
255 if(verbose>8) printf("x: [%d]=0\n", xi);
256 for(zi=0; zi<img.dimz; zi++) for(yi=0; yi<img.dimy; yi++)
257 if(fill_area && xi<img.dimx-1)
258 img.m[zi][yi][xi][fi]=img.m[zi][yi][xi+1][fi];
259 else
260 img.m[zi][yi][xi][fi]=0.0;
261 }
262 }
263 movNr++;
264 }
265 integerListEmpty(&framelist);
266 if(verbose>1) printf("%d moved frames.\n", movNr);
267
268
269 /*
270 * Save the modified image
271 */
272 if(verbose>0) printf("writing image %s\n", outfile);
273 ret=imgWrite(outfile, &img);
274 if(ret) {
275 fprintf(stderr, "Error: %s\n", img.statmsg);
276 imgEmpty(&img); return(11);
277 }
278 imgEmpty(&img);
279 if(verbose>0) printf("done.\n\n");
280
281 return(0);
282}
283/*****************************************************************************/
284
285/*****************************************************************************/
int atoi_with_check(const char *int_as_string, int *result_value)
Definition decpoint.c:238
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
int integerListEmpty(INTEGER_LIST *l)
Definition intex.c:175
int integerListInit(INTEGER_LIST *l)
Definition intex.c:161
int integerListSort(INTEGER_LIST *l)
Definition intex.c:219
int integerListExpandFromString(const char *s1, const char *s2, INTEGER_LIST *l, const int ifnew)
Definition intex.c:278
int integerListAdd(INTEGER_LIST *l, int v, int ifnew)
Definition intex.c:190
Header file for libtpcimgio.
#define IMG_TYPE_IMAGE
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
char type
float **** m
unsigned short int dimt
unsigned short int dimz
unsigned short int dimy
const char * statmsg