@@ -26,6 +26,26 @@ class ANTSInputSpec(ANTSCommandInputSpec):
26
26
desc = ('image to apply transformation to (generally a coregistered '
27
27
'functional)' ))
28
28
29
+ # Not all metrics are appropriate for all modalities. Also, not all metrics
30
+ # are efficeint or appropriate at all resolution levels, Some metrics perform
31
+ # well for gross global registraiton, but do poorly for small changes (i.e.
32
+ # Mattes), and some metrics do well for small changes but don't work well for
33
+ # gross level changes (i.e. 'CC').
34
+ #
35
+ # This is a two stage registration. in the first stage
36
+ # [ 'Mattes', .................]
37
+ # ^^^^^^ <- First stage
38
+ # Do a unimodal registration of the first elements of the fixed/moving input
39
+ # list use the"CC" as the metric.
40
+ #
41
+ # In the second stage
42
+ # [ ....., ['Mattes','CC'] ]
43
+ # ^^^^^^^^^^^^^^^ <- Second stage
44
+ # Do a multi-modal registration where the first elements of fixed/moving
45
+ # input list use 'CC' metric and that is added to 'Mattes' metric result of
46
+ # the second elements of the fixed/moving input.
47
+ #
48
+ # Cost = Sum_i ( metricweight[i] Metric_i ( fixedimage[i], movingimage[i]) )
29
49
metric = traits .List (traits .Enum ('CC' , 'MI' , 'SMI' , 'PR' , 'SSD' ,
30
50
'MSQ' , 'PSE' ), mandatory = True , desc = '' )
31
51
@@ -440,13 +460,15 @@ class Registration(ANTSCommand):
440
460
441
461
>>> # Test multiple metrics per stage
442
462
>>> reg5 = copy.deepcopy(reg)
443
- >>> reg5.inputs.metric = ['CC', ['CC', 'Mattes']]
444
- >>> reg5.inputs.metric_weight = [1, [.5]*2]
445
- >>> reg5.inputs.radius_or_number_of_bins = [4, [32]*2]
463
+ >>> reg5.inputs.fixed_image = [ 'fixed1.nii', 'fixed2.nii' ]
464
+ >>> reg5.inputs.moving_image = [ 'moving1.nii', 'moving2.nii' ]
465
+ >>> reg5.inputs.metric = ['Mattes', ['Mattes', 'CC']]
466
+ >>> reg5.inputs.metric_weight = [1, [.5,.5]]
467
+ >>> reg5.inputs.radius_or_number_of_bins = [32, [32,4] ]
446
468
>>> reg5.inputs.sampling_strategy = ['Random', None] # use default strategy in second stage
447
469
>>> reg5.inputs.sampling_percentage = [0.05, [0.05, 0.10]]
448
470
>>> reg5.cmdline
449
- 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --restore-state trans.mat --save-state trans.mat --transform Affine[ 2.0 ] --metric CC [ fixed1.nii, moving1.nii, 1, 4 , Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric CC [ fixed1.nii, moving1.nii, 0.5, 32, None, 0.05 ] --metric Mattes[ fixed1 .nii, moving1 .nii, 0.5, 32 , None, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
471
+ 'antsRegistration --collapse-output-transforms 0 --dimensionality 3 --initial-moving-transform [ trans.mat, 1 ] --initialize-transforms-per-stage 0 --interpolation Linear --output [ output_, output_warped_image.nii.gz ] --restore-state trans.mat --save-state trans.mat --transform Affine[ 2.0 ] --metric Mattes [ fixed1.nii, moving1.nii, 1, 32 , Random, 0.05 ] --convergence [ 1500x200, 1e-08, 20 ] --smoothing-sigmas 1.0x0.0vox --shrink-factors 2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --transform SyN[ 0.25, 3.0, 0.0 ] --metric Mattes [ fixed1.nii, moving1.nii, 0.5, 32, None, 0.05 ] --metric CC[ fixed2 .nii, moving2 .nii, 0.5, 4 , None, 0.1 ] --convergence [ 100x50x30, 1e-09, 20 ] --smoothing-sigmas 2.0x1.0x0.0vox --shrink-factors 3x2x1 --use-estimate-learning-rate-once 1 --use-histogram-matching 1 --winsorize-image-intensities [ 0.0, 1.0 ] --write-composite-transform 1'
450
472
"""
451
473
DEF_SAMPLING_STRATEGY = 'None'
452
474
"""The default sampling strategy argument."""
@@ -466,14 +488,12 @@ def _formatMetric(self, index):
466
488
----------
467
489
index: the stage index
468
490
"""
469
- # The common fixed image.
470
- fixed = self .inputs .fixed_image [0 ]
471
- # The common moving image.
472
- moving = self .inputs .moving_image [0 ]
473
491
# The metric name input for the current stage.
474
492
name_input = self .inputs .metric [index ]
475
493
# The stage-specific input dictionary.
476
494
stage_inputs = dict (
495
+ fixed_image = self .inputs .fixed_image [0 ],
496
+ moving_image = self .inputs .moving_image [0 ],
477
497
metric = name_input ,
478
498
weight = self .inputs .metric_weight [index ],
479
499
radius_or_bins = self .inputs .radius_or_number_of_bins [index ],
@@ -499,19 +519,32 @@ def _formatMetric(self, index):
499
519
if isinstance (name_input , list ):
500
520
items = stage_inputs .items ()
501
521
indexes = range (0 , len (name_input ))
502
- # dict-comprehension only works with python 2.7 and up
503
- #specs = [{k: v[i] for k, v in items} for i in indexes]
504
- specs = [dict ([(k , v [i ]) for k , v in items ]) for i in indexes ]
522
+ specs = list ()
523
+ for i in indexes :
524
+ temp = dict ([(k , v [i ]) for k , v in items ])
525
+ if i > len ( self .inputs .fixed_image ):
526
+ temp ["fixed_image" ] = self .inputs .fixed_image [0 ]
527
+ else :
528
+ temp ["fixed_image" ] = self .inputs .fixed_image [i ]
529
+
530
+ if i > len ( self .inputs .moving_image ):
531
+ temp ["moving_image" ] = self .inputs .moving_image [0 ]
532
+ else :
533
+ temp ["moving_image" ] = self .inputs .moving_image [i ]
534
+
535
+ specs .append ( temp )
505
536
else :
506
537
specs = [stage_inputs ]
507
538
508
539
# Format the --metric command line metric arguments, one per
509
540
# specification.
510
- return [self ._formatMetricArgument (fixed , moving , ** spec ) for spec in specs ]
541
+ return [self ._formatMetricArgument (** spec ) for spec in specs ]
511
542
512
- def _formatMetricArgument (self , fixed , moving , ** kwargs ):
543
+ def _formatMetricArgument (self , ** kwargs ):
513
544
retval = '%s[ %s, %s, %g, %d' % (kwargs ['metric' ],
514
- fixed , moving , kwargs ['weight' ],
545
+ kwargs ['fixed_image' ],
546
+ kwargs ['moving_image' ],
547
+ kwargs ['weight' ],
515
548
kwargs ['radius_or_bins' ])
516
549
517
550
# The optional sampling strategy.
0 commit comments