1
+ import warnings
2
+
3
+ import nibabel as nb
4
+
5
+ from ...utils .misc import package_check
6
+
7
+ try :
8
+ package_check ('nipy' )
9
+ except Exception , e :
10
+ warnings .warn ('nipy not installed' )
11
+ else :
12
+ from nipy .algorithms .registration .histogram_registration import HistogramRegistration
13
+ from nipy .algorithms .registration .affine import Affine
14
+
15
+ from ..base import (TraitedSpec , BaseInterface , traits ,
16
+ BaseInterfaceInputSpec , File , isdefined )
17
+
18
+
19
+ class SimilarityInputSpec (BaseInterfaceInputSpec ):
20
+
21
+ volume1 = File (exists = True , desc = "3D volume" , mandatory = True )
22
+ volume2 = File (exists = True , desc = "3D volume" , mandatory = True )
23
+ mask1 = File (exists = True , desc = "3D volume" , mandatory = True )
24
+ mask2 = File (exists = True , desc = "3D volume" , mandatory = True )
25
+ metric = traits .Either (traits .Enum ('cc' , 'cr' , 'crl1' , 'mi' , 'nmi' , 'slr' ),
26
+ traits .Callable (),
27
+ desc = """str or callable
28
+ Cost-function for assessing image similarity. If a string,
29
+ one of 'cc': correlation coefficient, 'cr': correlation
30
+ ratio, 'crl1': L1-norm based correlation ratio, 'mi': mutual
31
+ information, 'nmi': normalized mutual information, 'slr':
32
+ supervised log-likelihood ratio. If a callable, it should
33
+ take a two-dimensional array representing the image joint
34
+ histogram as an input and return a float.""" , usedefault = True )
35
+
36
+
37
+ class SimilarityOutputSpec (TraitedSpec ):
38
+
39
+ similarity = traits .Float (desc = "Similarity between volume 1 and 2" )
40
+
41
+
42
+ class Similarity (BaseInterface ):
43
+ """Calculates similarity between two 3D volumes. Both volumes have to be in
44
+ the same coordinate system, same space within that coordinate system and
45
+ with the same voxel dimensions.
46
+
47
+ Example
48
+ -------
49
+ >>> from nipype.interfaces.nipy.utils import Similarity
50
+ >>> similarity = Similarity()
51
+ >>> similarity.inputs.volume1 = 'rc1s1.nii'
52
+ >>> similarity.inputs.volume2 = 'rc1s2.nii'
53
+ >>> similarity.inputs.metric = 'cr'
54
+ >>> res = similarity.run() # doctest: +SKIP
55
+ """
56
+
57
+ input_spec = SimilarityInputSpec
58
+ output_spec = SimilarityOutputSpec
59
+
60
+ def _run_interface (self , runtime ):
61
+
62
+ vol1_nii = nb .load (self .inputs .volume1 )
63
+ vol2_nii = nb .load (self .inputs .volume2 )
64
+
65
+ if isdefined (self .inputs .mask1 ):
66
+ mask1_nii = nb .load (self .inputs .mask1 )
67
+ mask1_nii = nb .Nifti1Image (nb .load (self .inputs .mask1 ).get_data () == 1 , mask1_nii .get_affine (),
68
+ mask1_nii .get_header ())
69
+ else :
70
+ mask1_nii = None
71
+
72
+ if isdefined (self .inputs .mask2 ):
73
+ mask2_nii = nb .load (self .inputs .mask2 )
74
+ mask2_nii = nb .Nifti1Image (nb .load (self .inputs .mask2 ).get_data () == 1 , mask2_nii .get_affine (),
75
+ mask2_nii .get_header ())
76
+ else :
77
+ mask2_nii = None
78
+
79
+ histreg = HistogramRegistration (from_img = vol1_nii ,
80
+ to_img = vol2_nii ,
81
+ similarity = self .inputs .metric ,
82
+ from_mask = mask1_nii ,
83
+ to_mask = mask2_nii )
84
+ self ._similarity = histreg .eval (Affine ())
85
+
86
+ return runtime
87
+
88
+ def _list_outputs (self ):
89
+ outputs = self ._outputs ().get ()
90
+ outputs ['similarity' ] = self ._similarity
91
+ return outputs
0 commit comments