10#include "tpcclibConfig.h"
29static char *info[] = {
30 "Reconstruct PET image from attenuation and normalization corrected",
31 "2D PET sinogram using median root prior (MRP) [1,2,3].",
32 "This program does not correct image data for decay.",
33 "Image is corrected for the dead-time based on factors in the sinogram.",
34 "Image data is written in units ECAT counts per pixel per second.",
36 "Not for clinical use! Program is not thoroughly tested!",
38 "Usage: @P [Options] scnfile imgfile",
42 " Set zoom factor; by default 1.0 (no zoom).",
44 " Set image x and y dimensions; by default 128.",
45 " -rot[ation]=<value>",
46 " Set image rotation in degrees, -180 - 180; by default 0 (no rotation).",
48 " Set image shift in x direction (in cm); by default 0.",
50 " Set image shift in y direction (in cm); by default 0.",
52 " Divide image voxel values by voxel volume (mL); by default the voxel",
53 " volume is corrected later during image calibration.",
55 " Set beta value, usually 0.1 - 0.9; by default 0.3.",
57 " Set mask dimension for median filter, either 3 (3x3) or 5 (5x5 without",
58 " corener pixels); by default 3.",
60 " Set maximum number of iterations; by default 150.",
62 " Set the number of iterations without prior; by default 1.",
64 " Set the number of OS sets (acceleration); by default 1.",
68 " @P -dim=256 a2345dy1.scn a2345dy1.img",
71 "1. Alenius S, Ruotsalainen U. Bayesian image reconstruction for emission",
72 " tomography based on median root prior.",
73 " Eur J Nucl Med. 1997;24(3): 258-265.",
74 "2. Alenius S, Ruotsalainen U. Generalization of median root prior",
75 " reconstruction. IEEE Trans Med Imaging 2002; 21(11): 1413-1420.",
76 "3. Katoh C, Ruotsalainen U, Laine H, Alenius S, Iida H, Nuutila P, Knuuti J.",
77 " Iterative reconstruction based on median root prior in quantification of",
78 " myocardial blood flow and oxygen metabolism.",
79 " J Nucl Med. 1999;40(5):862-867.",
81 "See also: ecatnorm, edecay, ecalibr, atnmake, eframe, ecatfbp, img2scn",
83 "Keywords: ECAT, sinogram, image, reconstruction, MRP",
102int main(
int argc,
char **argv)
104 int ai, help=0, version=0, verbose=1;
105 char scnfile[FILENAME_MAX], imgfile[FILENAME_MAX];
111 float shiftX=0.0, shiftY=0.0;
123 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
124 scnfile[0]=imgfile[0]=(char)0;
126 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
127 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
129 if(strncasecmp(cptr,
"ITER=", 5)==0) {
130 maxIterNr=atoi(cptr+5);
if(maxIterNr>1)
continue;
131 }
else if(strncasecmp(cptr,
"SKIP=", 5)==0) {
132 skipPriorNr=atoi(cptr+5);
if(skipPriorNr>0)
continue;
133 }
else if(strncasecmp(cptr,
"OS=", 3)==0) {
134 osSetNr=atoi(cptr+3);
135 if(osSetNr==0 || osSetNr==1 || osSetNr==2)
continue;
136 if(osSetNr==4 || osSetNr==8 || osSetNr==16)
continue;
137 if(osSetNr==32 || osSetNr==64 || osSetNr==128)
continue;
138 }
else if(strncasecmp(cptr,
"DIM=", 4)==0) {
139 imgDim=atoi(cptr+4);
if(imgDim>1 && imgDim<=2048)
continue;
140 }
else if(strncasecmp(cptr,
"MASK=", 5)==0) {
141 maskDim=atoi(cptr+5);
if(maskDim==3 || maskDim==5)
continue;
142 }
else if(strncasecmp(cptr,
"ZOOM=", 5)==0) {
143 zoom=
atof_dpi(cptr+5);
if(zoom>0.1 && zoom<100.0)
continue;
144 }
else if(strncasecmp(cptr,
"BETA=", 5)==0) {
145 beta=
atof_dpi(cptr+5);
if(beta>0.05 && beta<100.0)
continue;
146 }
else if(strncasecmp(cptr,
"ROTATION=", 9)==0) {
149 if(v>=-180.0 && v<=180.0) {rotate=v;
continue;}
150 }
else if(strncasecmp(cptr,
"ROT=", 4)==0) {
153 if(v>-360.0 && v<360.0) {rotate=v;
continue;}
154 }
else if(strncasecmp(cptr,
"X=", 2)==0) {
157 if(v>-50.0 && v<50.0) {shiftX=10.0*v;
continue;}
158 }
else if(strncasecmp(cptr,
"Y=", 2)==0) {
161 if(v>-50.0 && v<50.0) {shiftY=10.0*v;
continue;}
163 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
168 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
173 if(ai<argc) {
strlcpy(scnfile, argv[ai++], FILENAME_MAX);}
174 if(ai<argc) {
strlcpy(imgfile, argv[ai++], FILENAME_MAX);}
176 fprintf(stderr,
"Error: too many arguments.\n");
182 fprintf(stderr,
"Error: missing command-line argument; use --help\n");
188 printf(
"scnfile := %s\n", scnfile);
189 printf(
"imgfile := %s\n", imgfile);
190 printf(
"Beta := %g\n", beta);
191 printf(
"Zoom := %g\n", zoom);
192 printf(
"Dimension := %d\n", imgDim);
193 printf(
"Mask := %d\n", maskDim);
194 printf(
"Rotation := %g\n", rotate);
195 printf(
"X_shift_mm := %g\n", shiftX);
196 printf(
"Y_shift_mm := %g\n", shiftY);
197 printf(
"volume_correction := %d\n", pervol);
198 printf(
"maxIterNr := %d\n", maxIterNr);
199 printf(
"skipPriorNr := %d\n", skipPriorNr);
200 printf(
"osSetNr := %d\n", osSetNr);
204 if(strcasecmp(imgfile, scnfile)==0) {
205 fprintf(stderr,
"Error: original sinogram must not be overwritten.\n");
210 fprintf(stderr,
"Error: invalid image dimension.\n");
218 if(verbose>0) printf(
"reading sinogram %s\n", scnfile);
222 fprintf(stderr,
"Error: %s\n", scn.
statmsg);
223 if(verbose>1) printf(
"ret := %d\n", ret);
227 printf(
"dimx := %d\n", scn.
dimx);
228 printf(
"dimy := %d\n", scn.
dimy);
229 printf(
"dimz := %d\n", scn.
dimz);
230 printf(
"dimt := %d\n", scn.
dimt);
234 fprintf(stderr,
"Error: file is not a sinogram.\n");
243 if(verbose>0) printf(
"MRP reconstruction... (may take a long time)\n");
244 ret=
imgMRP(&scn, &img, imgDim, zoom, shiftX, shiftY, rotate,
245 maxIterNr, skipPriorNr, beta, maskDim, osSetNr,
248 fprintf(stderr,
"Error in reconstruction.\n");
249 if(verbose>1) printf(
"ret := %d\n", ret);
258 if(verbose>0) printf(
"correcting for voxel volume\n");
262 for(zi=0; zi<img.
dimz; zi++)
263 for(yi=0; yi<img.
dimy; yi++)
264 for(xi=0; xi<img.
dimx; xi++)
265 for(ti=0; ti<img.
dimt; ti++)
266 img.
m[zi][yi][xi][ti]/=vol;
268 fprintf(stderr,
"Warning: cannot correct for pixel volume.\n");
275 if(verbose>0) printf(
"writing image %s\n", imgfile);
277 fprintf(stderr,
"Error: %s\n", img.
statmsg);
283 if(verbose>0) fprintf(stdout,
"done.\n");
int atof_with_check(char *double_as_string, double *result_value)
double atof_dpi(char *str)
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 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 libtpcrec.
int imgMRP(IMG *scn, IMG *img, int imgDim, float zoom, float shiftX, float shiftY, float rotation, int maxIterNr, int skipPriorNr, float beta, int maskDim, int osSetNr, int verbose)