8#include "tpcclibConfig.h"
23static char *info[] = {
24 "Verify that data in two PET images are similar. ECAT 6.3 and 7, NIfTI-1,",
25 "Analyze 7.5 and microPET formats are (partially) supported.",
26 "Returns 0 if files match and a nonzero value otherwise.",
28 "Usage: @P [Options] image1 image2",
35 " All values in the headers (excluding transformation parameters)",
36 " are required to match (y) or not tested (n, default).",
38 " Transformation parameters in the headers are required to match (y),",
39 " or not tested (n, default).",
41 " Planes numbers are required to match (y, default) or not tested (n).",
43 " Frame times are required to match (y, default) or not tested (n).",
45 " Absolute result differences must not exceed the specified limit value;",
46 " by default no difference is allowed.",
48 " Relative differences must not exceed the specified percent limit.",
54 " Calculates sum-of-squares between image pixel values.",
57 "Image1 and image2 must be in the same format, and they must have same",
58 "matrix size and plane numbers.",
60 "See also: tacmatch, resmatch, imgcalc, imgunit, ecatmax, img2tif",
62 "Keywords: Image, tool, software testing",
81int main(
int argc,
char **argv)
83 int ai, help=0, version=0, verbose=1;
84 double ROUGH_TEST_LIMIT=0.001;
85 double AROUND_TEST_LIMIT=0.1;
92 char file1[FILENAME_MAX], file2[FILENAME_MAX], *cptr;
103 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
104 file1[0]=file2[0]=(char)0;
107 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
110 if(strncasecmp(cptr,
"ROUGHLY", 4)==0) {
111 accur=ROUGH_TEST_LIMIT;
continue;
112 }
else if(strncasecmp(cptr,
"AROUND", 3)==0) {
113 accur=AROUND_TEST_LIMIT;
continue;
114 }
else if(strncasecmp(cptr,
"ABS=", 4)==0) {
115 cptr+=4; test_abs=
atof_dpi(cptr);
if(test_abs>=0.0)
continue;
116 }
else if(strncasecmp(cptr,
"REL=", 4)==0) {
117 cptr+=4; accur=0.01*
atof_dpi(cptr);
if(accur>=0.0)
continue;
118 }
else if(strncasecmp(cptr,
"HEADER=", 7)==0) {
120 if(strncasecmp(cptr,
"YES", 1)==0) {isHeader=1;
continue;}
121 if(strncasecmp(cptr,
"NO", 1)==0) {isHeader=0;
continue;}
122 }
else if(strncasecmp(cptr,
"TRANSFORM=", 10)==0) {
124 if(strncasecmp(cptr,
"YES", 1)==0) {isTransform=1;
continue;}
125 if(strncasecmp(cptr,
"NO", 1)==0) {isTransform=0;
continue;}
126 }
else if(strncasecmp(cptr,
"ALL", 1)==0) {
127 isHeader=1;
continue;
128 }
else if(strncasecmp(cptr,
"PLANES=", 7)==0) {
130 if(strncasecmp(cptr,
"YES", 1)==0) {isPlanes=1;
continue;}
131 if(strncasecmp(cptr,
"NO", 1)==0) {isPlanes=0;
continue;}
132 }
else if(strncasecmp(cptr,
"FRAMES=", 7)==0) {
134 if(strncasecmp(cptr,
"YES", 1)==0) {isFrames=1;
continue;}
135 if(strncasecmp(cptr,
"NO", 1)==0) {isFrames=0;
continue;}
136 }
else if(strcasecmp(cptr,
"SS")==0) {
139 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
144 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
149 if(ai<argc)
strlcpy(file1, argv[ai++], FILENAME_MAX);
150 if(ai<argc)
strlcpy(file2, argv[ai++], FILENAME_MAX);
151 if(ai<argc) {fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
return(1);}
154 if(!file2[0]) {
tpcPrintUsage(argv[0], info, stdout);
return(1);}
159 for(ai=0; ai<argc; ai++) printf(
"%s ", argv[ai]);
161 printf(
"file1 := %s\n", file1);
162 printf(
"file2 := %s\n", file2);
163 printf(
"isHeader := %d\n", isHeader);
164 printf(
"isTransform := %d\n", isTransform);
165 printf(
"isPlanes := %d\n", isPlanes);
166 printf(
"isFrames := %d\n", isFrames);
167 printf(
"accur := %g\n", accur);
168 printf(
"test_abs := %g\n", test_abs);
169 printf(
"calcSS := %d\n", calcSS);
174 if(access(file1, 0) == -1) {
175 fprintf(stderr,
"Error: file '%s' not found.\n", file1);
return(2);}
176 if(access(file2, 0) == -1) {
177 fprintf(stderr,
"Error: file '%s' not found.\n", file2);
return(2);}
183 if(verbose>1) fprintf(stdout,
"reading image %s\n", file1);
185 if(ret) {fprintf(stderr,
"Error: %s\n", img1.
statmsg);
return(2);}
186 if(verbose>1) fprintf(stdout,
"reading image %s\n", file2);
189 fprintf(stderr,
"Error: %s\n", img2.
statmsg);
196 if(verbose>1) fprintf(stdout,
"testing image size etc\n");
198 if(verbose>0) fprintf(stderr,
"Mismatching image type.\n");
202 if(verbose>0) fprintf(stderr,
"Mismatching number of frames.\n");
206 if(verbose>0) fprintf(stderr,
"Mismatching number of pixels (dimension x).\n");
210 if(verbose>0) fprintf(stderr,
"Mismatching number of pixels (dimension y).\n");
214 if(verbose>0) fprintf(stderr,
"Mismatching number of planes.\n");
222 if(verbose>1) fprintf(stdout,
"testing header contents\n");
225 if(verbose>0) fprintf(stdout,
"Image headers do not match.\n");
234 if(verbose>1) fprintf(stdout,
"testing header transformation parameters\n");
237 if(verbose>0) fprintf(stdout,
"Image transformation parameters do not match.\n");
246 if(verbose>1) fprintf(stdout,
"testing plane numbers\n");
249 if(verbose>0) fprintf(stdout,
"Plane numbers do not match.\n");
258 if(verbose>1) fprintf(stdout,
"testing frame times\n");
261 if(verbose>0) fprintf(stdout,
"Frame times do not match.\n");
271 if(
imgSS(&img1, &img2, &ss)!=0 || !isfinite(ss)) {
272 fprintf(stderr,
"Error: cannot calculate sum-of-squares.\n");
275 printf(
"SS := %e\n", ss);
283 if(verbose>1) fprintf(stdout,
"testing pixel values\n");
293 &maxabsvoxel, &maxabs, &maxrelvoxel, &maxrel);
295 fprintf(stdout,
"Error in testing pixel values (%d).\n", ret);
299 if(verbose>0) fprintf(stdout,
"Images match.\n");
304 printf(
"max_absolute_difference := %g\n", maxabs);
306 printf(
"max_absolute_difference_at := %d,%d,%d,%d\n",
307 maxabsvoxel.
z, maxabsvoxel.
y, maxabsvoxel.
x, maxabsvoxel.
t);
308 printf(
"max_relational_difference := %g\n", maxrel);
310 printf(
"max_relational_difference_at := %d,%d,%d,%d\n",
311 maxrelvoxel.
z, maxrelvoxel.
y, maxrelvoxel.
x, maxrelvoxel.
t);
313 if(maxabs>test_abs && maxrel>accur) {
314 if(verbose>0) fprintf(stdout,
"Images do not match.\n");
316 printf(
" %g > %g\n", maxabs, test_abs);
317 printf(
" %g > %g\n", maxrel, accur);
322 if(maxabs>0.0 && maxabs<=test_abs) {
323 if(verbose>0) printf(
"Maximal absolute difference is below the limit.\n");
324 if(verbose>1) printf(
" %g <= %g\n", maxabs, test_abs);
326 if(maxrel>0.0 && maxrel<=accur) {
327 if(verbose>0) printf(
"Maximal relational difference is below the limit.\n");
328 if(verbose>1) printf(
" %g <= %g\n", maxrel, accur);
332 if(verbose>0) fprintf(stdout,
"Images are similar within specified limits.\n");
double atof_dpi(char *str)
void imgEmpty(IMG *image)
int imgMatchPlanes(IMG *img1, IMG *img2)
int imgSS(IMG *img1, IMG *img2, double *ss)
int imgMatchHeader(IMG *img1, IMG *img2)
int imgMatchTransform(IMG *img1, IMG *img2)
int imgMaxDifference(IMG *img1, IMG *img2, VOXEL_4D *absdiff, float *abs_max, VOXEL_4D *reldiff, float *rel_max)
int imgMatchFrames(IMG *img1, IMG *img2)
int imgRead(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)