Skip to content

Commit 2ffec74

Browse files
committed
added interface for MeasureImageSimilarity
1 parent 2ee584b commit 2ffec74

File tree

2 files changed

+123
-1
lines changed

2 files changed

+123
-1
lines changed

nipype/interfaces/ants/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""Top-level namespace for ants."""
66

77
# Registraiton programs
8-
from .registration import ANTS, Registration
8+
from .registration import ANTS, Registration, MeasureImageSimilarity
99

1010
# Resampling Programs
1111
from .resampling import (ApplyTransforms, ApplyTransformsToPoints, WarpImageMultiTransform,

nipype/interfaces/ants/registration.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,3 +1034,125 @@ def _list_outputs(self):
10341034
if len(self.inputs.save_state):
10351035
outputs['save_state'] = os.path.abspath(self.inputs.save_state)
10361036
return outputs
1037+
1038+
1039+
class MeasureImageSimilarityInputSpec(ANTSCommandInputSpec):
1040+
dimension = traits.Enum(
1041+
2, 3, 4,
1042+
argstr='--dimensionality %d', position=1,
1043+
desc='Dimensionality of the fixed/moving image pair',
1044+
)
1045+
fixed_image = File(
1046+
exists=True, mandatory=True,
1047+
desc='Image to which the moving image is warped',
1048+
)
1049+
moving_image = File(
1050+
exists=True, mandatory=True,
1051+
desc='Image to apply transformation to (generally a coregistered functional)',
1052+
)
1053+
metric = traits.Enum(
1054+
"CC", "MI", "Mattes", "MeanSquares", "Demons", "GC",
1055+
argstr="%s", mandatory=True,
1056+
)
1057+
metric_weight = traits.Float(
1058+
requires=['metric'], default=1.0, usedefault=True,
1059+
desc='The "metricWeight" variable is not used.',
1060+
)
1061+
radius_or_number_of_bins = traits.Int(
1062+
requires=['metric'], mandatory=True,
1063+
desc='The number of bins in each stage for the MI and Mattes metric, '
1064+
'or the radius for other metrics',
1065+
)
1066+
sampling_strategy = traits.Enum(
1067+
"None", "Regular", "Random",
1068+
requires=['metric'], default="None", usedefault=True,
1069+
desc='Manner of choosing point set over which to optimize the metric. '
1070+
'Defaults to "None" (i.e. a dense sampling of one sample per voxel).'
1071+
)
1072+
sampling_percentage = traits.Either(
1073+
traits.Range(low=0.0, high=1.0),
1074+
requires=['metric'], mandatory=True,
1075+
desc='Percentage of points accessible to the sampling strategy over which '
1076+
'to optimize the metric.'
1077+
)
1078+
fixed_image_mask = File(
1079+
exists=True, argstr='%s',
1080+
desc='mask used to limit metric sampling region of the fixed image',
1081+
)
1082+
moving_image_mask = File(
1083+
exists=True, requires=['fixed_image_mask'],
1084+
desc='mask used to limit metric sampling region of the moving image',
1085+
)
1086+
1087+
1088+
class MeasureImageSimilarityOutputSpec(TraitedSpec):
1089+
similarity = traits.Float()
1090+
1091+
1092+
class MeasureImageSimilarity(ANTSCommand):
1093+
"""
1094+
1095+
1096+
Examples
1097+
--------
1098+
1099+
>>> from nipype.interfaces.ants import MeasureImageSimilarity
1100+
>>> sim = MeasureImageSimilarity()
1101+
>>> sim.inputs.dimension = 3
1102+
>>> sim.inputs.metric = 'MI'
1103+
>>> sim.inputs.fixed_image = 'T1.nii'
1104+
>>> sim.inputs.moving_image = 'resting.nii'
1105+
>>> sim.inputs.metric_weight = 1.0
1106+
>>> sim.inputs.radius_or_number_of_bins = 5
1107+
>>> sim.inputs.sampling_strategy = 'Regular'
1108+
>>> sim.inputs.sampling_percentage = 1.0
1109+
>>> sim.inputs.fixed_image_mask = 'mask.nii'
1110+
>>> sim.inputs.moving_image_mask = 'mask.nii.gz'
1111+
>>> sim.cmdline # doctest: +ALLOW_UNICODE
1112+
u'MeasureImageSimilarity --dimensionality 3 --masks ["mask.nii","mask.nii.gz"] \
1113+
--metric MI["T1.nii","resting.nii",1.0,5,Regular,1.0]'
1114+
"""
1115+
_cmd = 'MeasureImageSimilarity'
1116+
input_spec = MeasureImageSimilarityInputSpec
1117+
output_spec = MeasureImageSimilarityOutputSpec
1118+
1119+
def _metric_constructor(self):
1120+
retval = '--metric {metric}["{fixed_image}","{moving_image}",{metric_weight},'\
1121+
'{radius_or_number_of_bins},{sampling_strategy},{sampling_percentage}]'\
1122+
.format(
1123+
metric=self.inputs.metric,
1124+
fixed_image=self.inputs.fixed_image,
1125+
moving_image=self.inputs.moving_image,
1126+
metric_weight=self.inputs.metric_weight,
1127+
radius_or_number_of_bins=self.inputs.radius_or_number_of_bins,
1128+
sampling_strategy=self.inputs.sampling_strategy,
1129+
sampling_percentage=self.inputs.sampling_percentage,
1130+
)
1131+
return retval
1132+
1133+
def _mask_constructor(self):
1134+
if self.inputs.moving_image_mask:
1135+
retval = '--masks ["{fixed_image_mask}","{moving_image_mask}"]'\
1136+
.format(
1137+
fixed_image_mask=self.inputs.fixed_image_mask,
1138+
moving_image_mask=self.inputs.moving_image_mask,
1139+
)
1140+
else:
1141+
retval = '--masks "{fixed_image_mask}"'\
1142+
.format(
1143+
fixed_image_mask=self.inputs.fixed_image_mask,
1144+
)
1145+
return retval
1146+
1147+
def _format_arg(self, opt, spec, val):
1148+
if opt == 'metric':
1149+
return self._metric_constructor()
1150+
elif opt == 'fixed_image_mask':
1151+
return self._mask_constructor()
1152+
return super(MeasureImageSimilarity, self)._format_arg(opt, spec, val)
1153+
1154+
def aggregate_outputs(self, runtime=None, needed_outputs=None):
1155+
outputs = self._outputs()
1156+
stdout = runtime.stdout.split('\n')
1157+
outputs.similarity = float(stdout[0])
1158+
return outputs

0 commit comments

Comments
 (0)