TPCCLIB
Toggle main menu visibility
Loading...
Searching...
No Matches
libtpcimgio
imgcomp.c
Go to the documentation of this file.
1
5
/*****************************************************************************/
6
#include "
libtpcimgio.h
"
7
/*****************************************************************************/
8
9
/*****************************************************************************/
15
int
imgMatch
(
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
/*****************************************************************************/
47
int
imgMatchMatrix
(
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
/*****************************************************************************/
85
int
imgMatchTransform
(
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
/*****************************************************************************/
128
int
imgMatchHeader
(
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 &&
142
img1->
calibrationFactor
!=img2->
calibrationFactor
)
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
/*****************************************************************************/
286
int
imgMatchFrames
(
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
/*****************************************************************************/
307
int
imgMatchPlanes
(
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
/*****************************************************************************/
328
int
imgMaxDifference
(
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
/*****************************************************************************/
412
int
imgSS
(
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
/*****************************************************************************/
447
int
imgMatchMatrixSize
(
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
/*****************************************************************************/
imgMatchPlanes
int imgMatchPlanes(IMG *img1, IMG *img2)
Definition
imgcomp.c:307
imgSS
int imgSS(IMG *img1, IMG *img2, double *ss)
Definition
imgcomp.c:412
imgMatchMatrix
int imgMatchMatrix(IMG *img1, IMG *img2, double accuracy)
Definition
imgcomp.c:47
imgMatchHeader
int imgMatchHeader(IMG *img1, IMG *img2)
Definition
imgcomp.c:128
imgMatchTransform
int imgMatchTransform(IMG *img1, IMG *img2)
Definition
imgcomp.c:85
imgMaxDifference
int imgMaxDifference(IMG *img1, IMG *img2, VOXEL_4D *absdiff, float *abs_max, VOXEL_4D *reldiff, float *rel_max)
Definition
imgcomp.c:328
imgMatchFrames
int imgMatchFrames(IMG *img1, IMG *img2)
Definition
imgcomp.c:286
imgMatch
int imgMatch(IMG *img1, IMG *img2, float accuracy)
Definition
imgcomp.c:15
imgMatchMatrixSize
int imgMatchMatrixSize(IMG *d1, IMG *d2)
Definition
imgcomp.c:447
libtpcimgio.h
Header file for libtpcimgio.
IMG_TYPE_UNKNOWN
#define IMG_TYPE_UNKNOWN
Definition
libtpcimgio.h:1491
IMG
Definition
libtpcimgio.h:1657
IMG::sizex
float sizex
Definition
libtpcimgio.h:1714
IMG::dimx
unsigned short int dimx
Definition
libtpcimgio.h:1780
IMG::branchingFraction
float branchingFraction
Definition
libtpcimgio.h:1690
IMG::type
char type
Definition
libtpcimgio.h:1704
IMG::resolutionx
float resolutionx
Definition
libtpcimgio.h:1726
IMG::patientName
char patientName[32]
Definition
libtpcimgio.h:1679
IMG::resolutiony
float resolutiony
Definition
libtpcimgio.h:1728
IMG::studyDescription
char studyDescription[32]
Definition
libtpcimgio.h:1698
IMG::sampleDistance
float sampleDistance
Definition
libtpcimgio.h:1712
IMG::gapx
float gapx
Definition
libtpcimgio.h:1720
IMG::m
float **** m
Definition
libtpcimgio.h:1799
IMG::decayCorrection
char decayCorrection
Definition
libtpcimgio.h:1688
IMG::transaxialFOV
float transaxialFOV
Definition
libtpcimgio.h:1710
IMG::xform
short int xform[2]
Definition
libtpcimgio.h:1741
IMG::unit
char unit
Definition
libtpcimgio.h:1673
IMG::scanStart
time_t scanStart
Definition
libtpcimgio.h:1692
IMG::_fileFormat
int _fileFormat
Definition
libtpcimgio.h:1735
IMG::userProcessCode
char userProcessCode[11]
Definition
libtpcimgio.h:1696
IMG::dimt
unsigned short int dimt
Definition
libtpcimgio.h:1778
IMG::_dataType
int _dataType
Definition
libtpcimgio.h:1732
IMG::planeNumber
int * planeNumber
Definition
libtpcimgio.h:1809
IMG::patientID
char patientID[16]
Definition
libtpcimgio.h:1681
IMG::scanner
int scanner
Definition
libtpcimgio.h:1737
IMG::sizey
float sizey
Definition
libtpcimgio.h:1716
IMG::start
float * start
Definition
libtpcimgio.h:1815
IMG::dimz
unsigned short int dimz
Definition
libtpcimgio.h:1784
IMG::modality
int modality
Definition
libtpcimgio.h:1739
IMG::dimy
unsigned short int dimy
Definition
libtpcimgio.h:1782
IMG::orientation
int orientation
Definition
libtpcimgio.h:1694
IMG::end
float * end
Definition
libtpcimgio.h:1817
IMG::calibrationFactor
float calibrationFactor
Definition
libtpcimgio.h:1675
IMG::mt
float mt[12]
Definition
libtpcimgio.h:1747
IMG::quatern
float quatern[18]
Definition
libtpcimgio.h:1744
IMG::zoom
float zoom
Definition
libtpcimgio.h:1706
IMG::radiopharmaceutical
char radiopharmaceutical[32]
Definition
libtpcimgio.h:1683
IMG::isotopeHalflife
float isotopeHalflife
Definition
libtpcimgio.h:1685
IMG::studyNr
char studyNr[MAX_STUDYNR_LEN+1]
Definition
libtpcimgio.h:1677
IMG::gapy
float gapy
Definition
libtpcimgio.h:1722
IMG::gapz
float gapz
Definition
libtpcimgio.h:1724
IMG::axialFOV
float axialFOV
Definition
libtpcimgio.h:1708
IMG::mid
float * mid
Definition
libtpcimgio.h:1819
IMG::isWeight
char isWeight
Definition
libtpcimgio.h:1825
IMG::sizez
float sizez
Definition
libtpcimgio.h:1718
IMG::resolutionz
float resolutionz
Definition
libtpcimgio.h:1730
VOXEL_4D
Definition
libtpcimgio.h:1645
VOXEL_4D::y
int y
Definition
libtpcimgio.h:1649
VOXEL_4D::t
int t
Definition
libtpcimgio.h:1653
VOXEL_4D::x
int x
Definition
libtpcimgio.h:1647
VOXEL_4D::z
int z
Definition
libtpcimgio.h:1651
Generated on
for TPCCLIB by
1.17.0