Skip to content

registration

Neil Horner edited this page Dec 14, 2020 · 17 revisions

Overview

Registration in LAMA is done using [elastix which must me installed prior to running. See getting started

There is generally several stages to the registration process.

Rigid

This stage aligns images performing only linear translations aligning and centring all the embryos .

Affine/Similarity

This stage adds scaling and shears.

deformable/non-linear

This stage aligns images taking into account local differences. The step is split into several stages where each stage the grid spacing is reduced in order to firstly align larger structures, until finally aligning the smallest structures possible.

Running the pipeline

The parameters for the registration are entered into a config file

##Example configs

population average config

This config can be used for creating population averages.

generate_new_target_each_stage = true instructs lama to create a new fixed image after each registration stage by creating a mean iage of the previous stage outputs.

Each registration stage is defined by a registration_stage_params entry. Ensure that each resolution in the deformable registration by registration_stage_params and has a NumberOfResolutions = 1.

# This folder is relative to the folder that the config is in. Can use ../target for example is the target 
# folder is one level up from the config
target_folder = "target" 

threads = 64
filetype = "nrrd"
fixed_volume = "E15_5_pop_avg.nrrd"
fixed_mask = "E15_reg_mask.nrrd"
generate_new_target_each_stage = true
skip_transform_inversion = true
staging = "none" 

# Rigid
[[registration_stage_params]]
stage_id = "rigid"

[registration_stage_params.elastix_parameters]
Metric = "AdvancedNormalizedCorrelation"
Registration = "MultiResolutionRegistration"
MaximumNumberOfIterations = 400
NumberOfResolutions = 4
NumberOfSpatialSamples = 100000
Transform = "EulerTransform"
SP_a = [ 1000.0, 1000.0, 500.0, 500.0,]
SP_alpha = 0.602
SP_A = 50.0
FixedLimitRangeRatio = 0.0
MovingLimitRangeRatio = 0.0
FixedKernelBSplineOrder = 1
MovingKernelBSplineOrder = 3
UseDifferentiableOverlap = "false"


# Affine
[[registration_stage_params]]
stage_id = "affine"

[registration_stage_params.elastix_parameters]
Registration = "MultiResolutionRegistration"
NumberOfResolutions = 4
Transform = "AffineTransform"
Metric = "AdvancedNormalizedCorrelation"
MaximumNumberOfIterations = 500
NumberOfSpatialSamples = 1000000

### def1
[[registration_stage_params]]
stage_id = "deformable_128"
[registration_stage_params.elastix_parameters]
Registration = "MultiResolutionRegistration"
NumberOfResolutions = 1
NumberOfSpatialSamples = 200000
MaximumStepLength = 3.0
NumberOfGradientMeasurements = 10
NumberOfSamplesForExactGradient = 20000
NumberOfJacobianMeasurements = 4000
MaximumNumberOfIterations = 250
AutomaticParameterEstimation = "true"
UseAdaptiveStepSizes = "true"
ASGDParameterEstimationMethod = "DisplacementDistribution"
Transform = "BSplineTransform"
Metric = "AdvancedMattesMutualInformation"
FinalGridSpacingInVoxels = 128

##def3
[[registration_stage_params]]
stage_id = "deformable_64"
inherit_elx_params = "deformable_128"
[registration_stage_params.elastix_parameters]
FinalGridSpacingInVoxels = 64


##def4
[[registration_stage_params]]
stage_id = "deformable_32"
inherit_elx_params = "deformable_128"
[registration_stage_params.elastix_parameters]
MaximumStepLength = 2.0
FinalGridSpacingInVoxels = 32


##def5
[[registration_stage_params]]
stage_id = "deformable_16"
inherit_elx_params = "deformable_32"
[registration_stage_params.elastix_parameters]
NumberOfResolutions = 1
Metric = [ "AdvancedMattesMutualInformation", "TransformBendingEnergyPenalty",]
Registration = "MultiMetricMultiResolutionRegistration"
FinalGridSpacingInVoxels = 16
MaximumStepLength = 1.0
Metric0Weight = 1.0
Metric1Weight = 50


##def6
[[registration_stage_params]]
stage_id = "deformable_8"
inherit_elx_params = "deformable_16"
[registration_stage_params.elastix_parameters]
MaximumStepLength = 1.0
FinalGridSpacingInVoxels = 8

[global_elastix_params]
FixedInternalImagePixelType = "float"
MovingInternalImagePixelType = "float"
FixedImageDimension = 3
MovingImageDimension = 3
UseDirectionCosines = "true"
FixedImagePyramid = "FixedShrinkingImagePyramid"
MovingImagePyramid = "MovingShrinkingImagePyramid"
ResultImagePixelType = "float"
ResultImageFormat = "nrrd"
CompressResultImage = "true"
Interpolator = "BSplineInterpolator"
ResampleInterpolator = "FinalBSplineInterpolator"
Resampler = "DefaultResampler"
NumberOfHistogramBins = 32
HowToCombineTransforms = "Compose"
NewSamplesEveryIteration = "true"
ImageSampler = "Random"
FinalBSplineInterpolationOrder = 3
BSplineInterpolationOrder = 3
DefaultPixelValue = 0
WriteTransformParametersEachIteration = "false"
WriteResultImage = "true"
WriteResultImageAfterEachResolution = "true"
AutomaticScalesEstimation = "true"
AutomaticTransformInitialization = "true"
Optimizer = "AdaptiveStochasticGradientDescent"

Data generation config

The following config is for generating data to run statistical analysis on

generate_new_target_each_stage = false This ensures that the populaiton average is used as the target for each step. Notes that there is just one deformable regisrtation stage deformable_192_to_10 which contains multiple resolutions which are handled by elastx.

target_folder = "target"
threads = 64
filetype = "nrrd" # Currently only works with nrrd output
fixed_volume = "bcm_stb_avg_081020.nrrd"
label_map = "bcm_stb_avg_081020_atlas_v1.nrrd"
fixed_mask = "bcm_stb_avg_081020_reg_mask.nrrd"
stats_mask = "bcm_stb_avg_081020_tight_mask.nrrd"
generate_new_target_each_stage = false
skip_transform_inversion = false
staging = "embryo_volume"
fix_folding = "false"

[generate_deformation_fields]
192_to_10 = [ "deformable_192_to_10",]

###### define the registration shedule ########################

[[registration_stage_params]]
stage_id = "rigid"

[registration_stage_params.elastix_parameters]
Metric = "AdvancedMattesMutualInformation"
Registration = "MultiResolutionRegistration"
MaximumNumberOfIterations = 400
NumberOfResolutions = 4
NumberOfSpatialSamples = 20000
Transform = "EulerTransform"
SP_a = [ 1000.0, 1000.0, 500.0, 500.0,]
SP_alpha = 0.602
SP_A = 50.0
UseDifferentiableOverlap = "false"

[[registration_stage_params]]
stage_id = "similarity"
[registration_stage_params.elastix_parameters]
Registration = "MultiResolutionRegistration"
NumberOfResolutions = 4
Transform = "SimilarityTransform"
Metric = "AdvancedMattesMutualInformation"
MaximumNumberOfIterations = 500
NumberOfSpatialSamples = 20000

[[registration_stage_params]]
stage_id = "affine"
[registration_stage_params.elastix_parameters]
Registration = "MultiResolutionRegistration"
NumberOfResolutions = 4
Transform = "AffineTransform"
Metric = "AdvancedMattesMutualInformation"
MaximumNumberOfIterations = 500
NumberOfSpatialSamples = 20000


[[registration_stage_params]]
stage_id = "deformable_192_to_10"

[registration_stage_params.elastix_parameters]
Registration = "MultiMetricMultiResolutionRegistration"
NumberOfResolutions = 6

AutomaticParameterEstimation = "true"
UseAdaptiveStepSizes = "true"
Transform = "BSplineTransform"
Metric = [ "AdvancedMattesMutualInformation", "TransformBendingEnergyPenalty",]
Metric0Weight = [ 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
Metric2Weight = [0.0, 0.0, 0.0, 0.0, 25.0, 25.0]
FinalGridSpacingInVoxels = 8

NumberOfSpatialSamples = [10000, 10000, 10000, 10000, 50000, 50000]
MaximumNumberOfIterations = 1500

GridSpacingSchedule = [9.6, 4.8, 2.4, 1.6, 1.2, 1.0]
FixedImagePyramidSchedule = [ 
6.0, 6.0, 6.0, 
4.0, 4.0, 4.0, 
2.0, 2.0, 2.0, 
1.0, 1.0, 1.0, 
1.0, 1.0, 1.0,
1.0, 1.0, 1.0]
MovingImagePyramidSchedule = [  
6.0, 6.0, 6.0, 
4.0, 4.0, 4.0, 
2.0, 2.0, 2.0, 
1.0, 1.0, 1.0, 
1.0, 1.0, 1.0,
1.0, 1.0, 1.0]
#################################################



#### Parameters that apply to each stage
[global_elastix_params]
FixedInternalImagePixelType = "float"
MovingInternalImagePixelType = "float"
FixedImageDimension = 3
MovingImageDimension = 3
UseDirectionCosines = "true"
FixedImagePyramid = "FixedSmoothingImagePyramid"
MovingImagePyramid = "MovingSmoothingImagePyramid"
ResultImagePixelType = "short"
ResultImageFormat = "nrrd"
CompressResultImage = "true"
Interpolator = "BSplineInterpolator"
ResampleInterpolator = "FinalBSplineInterpolator"
Resampler = "DefaultResampler"
NumberOfHistogramBins = 32
HowToCombineTransforms = "Compose"
NewSamplesEveryIteration = "true"
ImageSampler = "RandomCoordinate"
FinalBSplineInterpolationOrder = 3
BSplineInterpolationOrder = 3
DefaultPixelValue = 0
WriteTransformParametersEachIteration = "false"
WriteTransformParametersEachResolution = "true"
WriteResultImage = "true"
WriteResultImageAfterEachResolution = "true"
AutomaticScalesEstimation = "true"
AutomaticTransformInitialization = "true"
Optimizer = "AdaptiveStochasticGradientDescent"
UseRandomSampleRegion = "false"

Notes on parameters

target_folder = "target" threads = 64 fixed_volume = "bcm_stb_avg_081020.nrrd" label_map = "bcm_stb_avg_081020_atlas_v1.nrrd" fixed_mask = "bcm_stb_avg_081020_reg_mask.nrrd" stats_mask = "bcm_stb_avg_081020_tight_mask.nrrd" generate_new_target_each_stage = false skip_transform_inversion = false staging = "embryo_volume" fix_folding = "false"

Parallelised registration

Elastix is able to parallelise individual image registration tasks across different CPUs on the same machine.
To set the number of CPUs to use in LAMA use (defaults to all cores)

threads = 8