TPCCLIB
Loading...
Searching...
No Matches
imgcomp.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "libtpcimgio.h"
7/*****************************************************************************/
8
9/*****************************************************************************/
17 IMG *img1,
19 IMG *img2,
23 float accuracy
24) {
25 int ret=0;
26
27 if(img1==NULL || img2==NULL) return(1);
28 ret=imgMatchHeader(img1, img2); if(ret!=0) return(100+ret);
29 ret=imgMatchFrames(img1, img2); if(ret!=0) return(200+ret);
30 ret=imgMatchPlanes(img1, img2); if(ret!=0) return(300+ret);
31 ret=imgMatchMatrix(img1, img2, (double)accuracy); if(ret!=0) return(400+ret);
32 ret=imgMatchTransform(img1, img2); if(ret!=0) return(500+ret);
33 return(0);
34}
35/*****************************************************************************/
36
37/*****************************************************************************/
49 IMG *img1,
51 IMG *img2,
53 double accuracy
54) {
55
56 int xi, yi, pi, fi;
57 double s;
58
59 for(pi=0; pi<img1->dimz; pi++) for(yi=0; yi<img1->dimy; yi++)
60 for(xi=0; xi<img1->dimx; xi++) for(fi=0; fi<img1->dimt; fi++) {
61 s=fabs(img1->m[pi][yi][xi][fi]+img2->m[pi][yi][xi][fi])/2.0;
62 if(accuracy==0.0 || s==0.0) {
63 if(img1->m[pi][yi][xi][fi]!=img2->m[pi][yi][xi][fi]){
64 fprintf(stderr, "Mismatch in image matrix.\n");
65 return(1);
66 }
67 } else {
68 if(fabs(img1->m[pi][yi][xi][fi]-img2->m[pi][yi][xi][fi])/s > (1.0-accuracy)) {
69 fprintf(stderr, "Mismatch in image matrix.\n");
70 printf("img[%d][%d][%d][%d]: %g vs %g\n", pi, yi, xi, fi,
71 img1->m[pi][yi][xi][fi], img2->m[pi][yi][xi][fi]);
72 return(1);
73 }
74 }
75 }
76 return 0;
77}
78/*****************************************************************************/
79
80/*****************************************************************************/
87 IMG *img1,
89 IMG *img2
90) {
91 int i;
92 float f;
93
94 if(img1->xform[0]!=img2->xform[0]) {
95 fprintf(stderr, "In the header: Mismatching qform.\n");
96 return 1;
97 }
98 if(img1->xform[1]!=img2->xform[1]) {
99 fprintf(stderr, "In the header: Mismatching sform.\n");
100 return 1;
101 }
102
103 for(i=0; i<18; i++) {
104 f=img1->quatern[i]-img2->quatern[i];
105 if(fabs(f)>1.0E-05) {
106 fprintf(stderr, "In the header: Mismatching transformation parameter.\n");
107 return 1;
108 }
109 }
110
111 for(i=0; i<12; i++) {
112 f=img1->mt[i]-img2->mt[i];
113 if(fabs(f)>1.0E-05) {
114 fprintf(stderr, "In the header: Mismatching matrix transformation.\n");
115 return 1;
116 }
117 }
118
119 return 0;
120}
121/*****************************************************************************/
122
123/*****************************************************************************/
130 IMG *img1,
132 IMG *img2
133) {
134
135 if(img1->unit!=img2->unit){
136 fprintf(stderr, "In the header: Mismatching unit.\n");
137 return 1;
138 }
139
140 // Not always preserved in read&write, therefore tested if present in both
141 if(img1->calibrationFactor>0.0 && img2->calibrationFactor>0.0 &&
143 {
144 fprintf(stderr, "In the header: Mismatching calibration factor.\n");
145 return 1;
146 }
147
148 if(img1->zoom!=img2->zoom){
149 fprintf(stderr, "In the header: Mismatching zoom.\n");
150 return 1;
151 }
152 if(strcasecmp(img1->radiopharmaceutical,img2->radiopharmaceutical)){
153 fprintf(stderr, "In the header: Mismatching radiopharmaceutical.\n");
154 return 1;
155 }
156 if(img1->isotopeHalflife!=img2->isotopeHalflife){
157 fprintf(stderr, "In the header: Mismatching isotope halflife.\n");
158 return 1;
159 }
160 if(img1->decayCorrection!=img2->decayCorrection){
161 fprintf(stderr, "In the header: One of the images is not corrected for decay.\n");
162 return 1;
163 }
164 if(img1->branchingFraction!=img2->branchingFraction){
165 fprintf(stderr, "In the header: Mismatching branching ratio.\n");
166 return 1;
167 }
168 if(img1->scanStart!=img2->scanStart){
169 fprintf(stderr, "In the header: Mismatching scan start times.\n");
170 fprintf(stderr, "difftime := %g s\n", difftime(img1->scanStart, img2->scanStart));
171 return 1;
172 }
173 if(img1->orientation!=img2->orientation){
174 fprintf(stderr, "In the header: Mismatching orientation.\n");
175 return 1;
176 }
177 if(img1->axialFOV!=img2->axialFOV){
178 fprintf(stderr, "In the header: Mismatching axial FOV.\n");
179 return 1;
180 }
181 if(img1->transaxialFOV!=img2->transaxialFOV){
182 fprintf(stderr, "In the header: Mismatching transaxial FOV.\n");
183 return 1;
184 }
185 if(img1->sampleDistance!=img2->sampleDistance){
186 fprintf(stderr, "In the header: Mismatching sample distance.\n");
187 return 1;
188 }
189
190 if(strcasecmp(img1->studyNr,img2->studyNr)){
191 fprintf(stderr, "In the header: Mismatching study number.\n");
192 return 1;
193 }
194 if(strcmp(img1->userProcessCode,img2->userProcessCode)){
195 fprintf(stderr, "In the header: Mismatching user process code.\n");
196 return 1;
197 }
198 if(strcmp(img1->studyDescription,img2->studyDescription)){
199 fprintf(stderr, "In the header: Mismatching study description.\n");
200 return 1;
201 }
202 if(strcasecmp(img1->patientName,img2->patientName)){
203 fprintf(stderr, "In the header: Mismatching patient name.\n");
204 return 1;
205 }
206 if(strcasecmp(img1->patientID,img2->patientID)){
207 fprintf(stderr, "In the header: Mismatching patient ID.\n");
208 return 1;
209 }
210
211 if(img1->type!=IMG_TYPE_UNKNOWN && img2->type!=IMG_TYPE_UNKNOWN &&
212 img1->type!=img2->type)
213 {
214 fprintf(stderr, "In the header: Mismatching image type.\n");
215 return 1;
216 }
217
218 if(img1->sizex!=img2->sizex){
219 fprintf(stderr, "In the header: Mismatching size (x-axis).\n");
220 return 1;
221 }
222 if(img1->sizey!=img2->sizey){
223 fprintf(stderr, "In the header: Mismatching size (y-axis).\n");
224 return 1;
225 }
226 if(img1->sizez!=img2->sizez){
227 fprintf(stderr, "In the header: Mismatching size (z-axis).\n");
228 return 1;
229 }
230 if(img1->gapx!=img2->gapx){
231 fprintf(stderr, "In the header: Mismatching x gap.\n");
232 return 1;
233 }
234 if(img1->gapy!=img2->gapy){
235 fprintf(stderr, "In the header: Mismatching y gap.\n");
236 return 1;
237 }
238 if(img1->gapz!=img2->gapz){
239 fprintf(stderr, "In the header: Mismatching z gap.\n");
240 return 1;
241 }
242
243 if(img1->resolutionx!=img2->resolutionx){
244 fprintf(stderr, "In the header: Mismatching resolution (x-axis).\n");
245 return 1;
246 }
247 if(img1->resolutiony!=img2->resolutiony){
248 fprintf(stderr, "In the header: Mismatching resolution (y-axis).\n");
249 return 1;
250 }
251 if(img1->resolutionz!=img2->resolutionz){
252 fprintf(stderr, "In the header: Mismatching resolution (z-axis).\n");
253 return 1;
254 }
255
256 if(img1->scanner!=img2->scanner){
257 fprintf(stderr, "In the header: Mismatching scanner.\n");
258 return 1;
259 }
260 if(img1->modality!=img2->modality){
261 fprintf(stderr, "In the header: Mismatching modality.\n");
262 return 1;
263 }
264 if(img1->_dataType!=img2->_dataType){
265 fprintf(stderr, "In the header: Mismatching data type.\n");
266 return 1;
267 }
268 if(img1->_fileFormat!=img2->_fileFormat){
269 fprintf(stderr, "In the header: Mismatching file format.\n");
270 return 1;
271 }
272 if(img1->isWeight!=img2->isWeight){
273 fprintf(stderr, "In the header: Mismatching in weights.\n");
274 return 1;
275 }
276
277 return 0;
278}
279/*****************************************************************************/
280
281/*****************************************************************************/
288 IMG *img1,
290 IMG *img2
291) {
292 if(img1->dimt!=img2->dimt) return(1);
293 for(int fi=0; fi<img1->dimt; fi++) {
294 if(fabs(img1->start[fi]-img2->start[fi])>0.001) return(11);
295 if(fabs(img1->end[fi]-img2->end[fi])>0.001) return(12);
296 if(fabs(img1->mid[fi]-img2->mid[fi])>0.001) return(13);
297 }
298 return(0);
299}
300/*****************************************************************************/
301
302/*****************************************************************************/
309 IMG *img1,
311 IMG *img2
312) {
313 if(img1->dimz!=img2->dimz) return(1);
314 for(int zi=0; zi<img1->dimz; zi++) {
315 if(img1->planeNumber[zi]!=img2->planeNumber[zi]) return(11);
316 }
317 return(0);
318}
319/*****************************************************************************/
320
321/*****************************************************************************/
330 IMG *img1,
332 IMG *img2,
335 VOXEL_4D *absdiff,
337 float *abs_max,
340 VOXEL_4D *reldiff,
342 float *rel_max
343) {
344
345 int xi, yi, zi, ti;
346 float s, v, absmax=0.0, relmax=0.0;
347
348 /* Initiate result voxels */
349 if(absdiff!=NULL) absdiff->x=absdiff->y=absdiff->z=absdiff->t=0;
350 if(abs_max!=NULL) *abs_max=0;
351 if(reldiff!=NULL) reldiff->x=reldiff->y=reldiff->z=reldiff->t=0;
352 if(rel_max!=NULL) *rel_max=0;
353
354 /* Check input */
355 if(img1==NULL || img2==NULL) return 1;
356 if(img1->dimx!=img2->dimx) return 2;
357 if(img1->dimy!=img2->dimy) return 3;
358 if(img1->dimz!=img2->dimz) return 4;
359 if(img1->dimt!=img2->dimt) return 5;
360
361
362 /* Search for max absolute difference */
363 for(zi=0; zi<img1->dimz; zi++) for(yi=0; yi<img1->dimy; yi++)
364 for(xi=0; xi<img1->dimx; xi++) for(ti=0; ti<img1->dimt; ti++) {
365 s=fabs(img1->m[zi][yi][xi][ti]-img2->m[zi][yi][xi][ti]);
366 if(s>absmax) {
367 absmax=s;
368 if(absdiff!=NULL) {absdiff->x=xi+1; absdiff->y=yi+1; absdiff->z=zi+1; absdiff->t=ti+1;}
369 }
370 }
371 //printf("absmax := %g\n", absmax);
372 if(abs_max!=NULL) *abs_max=absmax;
373
374
375 /* Search for max relational difference.
376 If relational difference is Inf (image average is zero), then relmax
377 is set to FLT_MAX, and from those pixels the one where
378 absolute difference is highest is searched */
379 float local_absmax=0.0;
380 for(zi=0; zi<img1->dimz; zi++) for(yi=0; yi<img1->dimy; yi++)
381 for(xi=0; xi<img1->dimx; xi++) for(ti=0; ti<img1->dimt; ti++) {
382 s=fabs(img1->m[zi][yi][xi][ti]-img2->m[zi][yi][xi][ti]);
383 v=0.5*fabs(img1->m[zi][yi][xi][ti]+img2->m[zi][yi][xi][ti]);
384 if(v>0.0) {
385 s/=v;
386 if(s>relmax && local_absmax==0.0) {
387 relmax=s;
388 if(reldiff!=NULL) {reldiff->x=xi+1; reldiff->y=yi+1; reldiff->z=zi+1; reldiff->t=ti+1;}
389 }
390 } else if(s>0.0) { // if relational max is find out the pixel where
391 if(s>local_absmax) {
392 local_absmax=s;
393 if(reldiff!=NULL) {reldiff->x=xi+1; reldiff->y=yi+1; reldiff->z=zi+1; reldiff->t=ti+1;}
394 }
395 }
396 }
397 if(local_absmax>0.0) relmax=FLT_MAX;
398 //printf("relmax := %g\n", relmax);
399 if(rel_max!=NULL) *rel_max=relmax;
400
401 /* Was there any difference? 0=yes, -1=no */
402 if(absmax>0.0 || relmax>0.0) return 0; else return -1;
403}
404/*****************************************************************************/
405
406/*****************************************************************************/
414 IMG *img1,
416 IMG *img2,
418 double *ss
419) {
420 if(ss!=NULL) *ss=0.0;
421 if(img1==NULL || img2==NULL) return(1);
422 if(img1->dimz!=img2->dimz) return(2);
423 if(img1->dimy!=img2->dimy) return(3);
424 if(img1->dimx!=img2->dimx) return(4);
425 if(img1->dimt!=img2->dimt) return(5);
426
427 double sumsqr=0.0;
428 for(int z=0; z<img1->dimz; z++)
429 for(int y=0; y<img1->dimy; y++)
430 for(int x=0; x<img1->dimx; x++)
431 for(int i=0; i<img1->dimt; i++) {
432 double d=img1->m[z][y][x][i]-img2->m[z][y][x][i];
433 sumsqr+=d*d;
434 }
435 if(ss!=NULL) *ss=sumsqr;
436
437 return(0);
438}
439/*****************************************************************************/
440
441/*****************************************************************************/
449 IMG *d1,
451 IMG *d2
452) {
453 if(d1==NULL || d2==NULL) return(1);
454 if(d1->dimz!=d2->dimz) return(1);
455 if(d1->dimy!=d2->dimy) return(1);
456 if(d1->dimx!=d2->dimx) return(1);
457 return(0);
458}
459/*****************************************************************************/
460
461/*****************************************************************************/
int imgMatchPlanes(IMG *img1, IMG *img2)
Definition imgcomp.c:307
int imgSS(IMG *img1, IMG *img2, double *ss)
Definition imgcomp.c:412
int imgMatchMatrix(IMG *img1, IMG *img2, double accuracy)
Definition imgcomp.c:47
int imgMatchHeader(IMG *img1, IMG *img2)
Definition imgcomp.c:128
int imgMatchTransform(IMG *img1, IMG *img2)
Definition imgcomp.c:85
int imgMaxDifference(IMG *img1, IMG *img2, VOXEL_4D *absdiff, float *abs_max, VOXEL_4D *reldiff, float *rel_max)
Definition imgcomp.c:328
int imgMatchFrames(IMG *img1, IMG *img2)
Definition imgcomp.c:286
int imgMatch(IMG *img1, IMG *img2, float accuracy)
Definition imgcomp.c:15
int imgMatchMatrixSize(IMG *d1, IMG *d2)
Definition imgcomp.c:447
Header file for libtpcimgio.
#define IMG_TYPE_UNKNOWN
float sizex
unsigned short int dimx
float branchingFraction
char type
float resolutionx
char patientName[32]
float resolutiony
char studyDescription[32]
float sampleDistance
float gapx
float **** m
char decayCorrection
float transaxialFOV
short int xform[2]
char unit
time_t scanStart
int _fileFormat
char userProcessCode[11]
unsigned short int dimt
int _dataType
int * planeNumber
char patientID[16]
int scanner
float sizey
float * start
unsigned short int dimz
int modality
unsigned short int dimy
int orientation
float * end
float calibrationFactor
float mt[12]
float quatern[18]
float zoom
char radiopharmaceutical[32]
float isotopeHalflife
char studyNr[MAX_STUDYNR_LEN+1]
float gapy
float gapz
float axialFOV
float * mid
char isWeight
float sizez
float resolutionz