Skip to content

Commit 620e8b2

Browse files
committed
Merge pull request #361 from chrisfilo/enh/similarity
Added similarity calculation interface
2 parents 9fc331e + 75fabfb commit 620e8b2

File tree

3 files changed

+93
-1
lines changed

3 files changed

+93
-1
lines changed

CHANGES

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Since last release
22
==================
33

4-
* ENH: Interface for WatershedBEM from the MNE software package
4+
* ENH: New interfaces: nipy.Similarity, WatershedBEM
55

66
* FIX: Afni outputs should inherit from TraitedSpec
77

nipype/interfaces/nipy/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from .model import FitGLM, EstimateContrast
22
from .preprocess import ComputeMask, FmriRealign4d
3+
from .utils import Similarity

nipype/interfaces/nipy/utils.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
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

Comments
 (0)