Commit 8a69bfd8 authored by Kasper Marstal's avatar Kasper Marstal Committed by GitHub

Merge pull request #365 from SuperElastix/SELX-351-Add-ComposeDisplacementFieldComponent

ENH: Add DisplacementFieldComposer and inverse consistency metric
parents b10ef18a e7f4c933
{
"Components": [
{
"Name": "DisplacementField",
"NameOfClass": "ItkDisplacementFieldSourceComponent",
"Dimensionality": "3"
},
{
"Name": "WarpingDisplacementField",
"NameOfClass": "ItkDisplacementFieldSourceComponent",
"Dimensionality": "3"
},
{
"Name": "DisplacementFieldComposer",
"NameOfClass": "ItkDisplacementFieldComposerComponent",
"Dimensionality": "3"
},
{
"Name": "DisplacementFieldSink",
"NameOfClass": "ItkDisplacementFieldSinkComponent",
"Dimensionality": "3"
}
],
"Connections": [
{
"Out": "DisplacementField",
"In": "DisplacementFieldComposer",
"NameOfInterface": "itkDisplacementFieldInterface"
},
{
"Out": "WarpingDisplacementField",
"In": "DisplacementFieldComposer",
"NameOfInterface": "itkWarpingDisplacementFieldInterface"
},
{
"Out": "DisplacementFieldComposer",
"In": "DisplacementFieldSink"
}
]
}
......@@ -23,7 +23,7 @@ python -m ContinuousRegistration.Source.make_registration_scripts --superelastix
# find $CRC_OUTPUT_DIR -type f -name "*.sh" -exec "{}" \;
# Register images in parallel
# find $CRC_OUTPUT_DIR -type f -name "*.sh" | parallel -j4 bash
find $CRC_OUTPUT_DIR -type f -name "*.sh" | parallel -j6 bash
# Evaluate registrations, generate visualizations, and generate leaderboard
python -m ContinuousRegistration.Source.make_evaluation --superelastix $SUPERELASTIX_BUILD_DIR/SuperElastix-build/bin/SuperElastix --submissions-directory $SUPERELASTIX_SOURCE_DIR/ContinuousRegistration/Submissions --output-directory $CRC_OUTPUT_DIR $CRC_DATASETS $CRC_BLUEPRINT_FILE_NAME --max-number-of-registrations-per-dataset $CRC_MAX_NUM_REG_PER_DATASET --make-image-checkerboards True --make-label-checkerboards True --make-difference-images True
......
......@@ -2,8 +2,7 @@ import glob, csv, re, stat
from abc import ABCMeta
from itertools import combinations
from ContinuousRegistration.Source.metrics import tre, hausdorff, inverse_consistency_labels, \
inverse_consistency_points, label_overlap
from ContinuousRegistration.Source.metrics import tre, hausdorff, inverse_consistency, label_overlap
from ContinuousRegistration.Source.util import *
class Dataset:
......@@ -84,14 +83,14 @@ class Dataset:
tre_0, tre_1 = tre(superelastix, point_sets, disp_field_paths)
hausdorff_0, hausdorff_1 = hausdorff(superelastix, point_sets, disp_field_paths)
inverse_consistency_points_0, inverse_consistency_points_1 = inverse_consistency_points(
superelastix, point_sets, disp_field_paths)
inverse_consistency_0, inverse_consistency_1 = inverse_consistency(
superelastix, disp_field_paths, file_names['mask_file_names'])
return {
file_names['disp_field_file_names'][0]:
merge_dicts(tre_0, hausdorff_0, inverse_consistency_points_0),
merge_dicts(tre_0, hausdorff_0, inverse_consistency_0),
file_names['disp_field_file_names'][1]:
merge_dicts(tre_1, hausdorff_1, inverse_consistency_points_1)
merge_dicts(tre_1, hausdorff_1, inverse_consistency_1)
}
@staticmethod
......@@ -108,16 +107,16 @@ class Dataset:
os.path.join(output_directory, file_names['disp_field_file_names'][1]),
)
inverse_consistency_atlas_0, inverse_consistency_atlas_1 = inverse_consistency_labels(
superelastix, file_names['ground_truth_file_names'], disp_field_paths)
inverse_consistency_0, inverse_consistency_1 = inverse_consistency(
superelastix, disp_field_paths, file_names['mask_file_names'])
dice_0, dice_1 = label_overlap(superelastix, file_names['ground_truth_file_names'], disp_field_paths)
return {
file_names['disp_field_file_names'][0]:
merge_dicts(inverse_consistency_atlas_0, dice_0),
merge_dicts(inverse_consistency_0, dice_0),
file_names['disp_field_file_names'][1]:
merge_dicts(inverse_consistency_atlas_1, dice_1)
merge_dicts(inverse_consistency_1, dice_1)
}
@staticmethod
......@@ -901,7 +900,6 @@ def load_datasets(parameters):
datasets[cumc12.name] = cumc12
logging.debug('Using files:\n{0}'.format(json.dumps(cumc12.file_names, indent=2)))
if parameters.dirlab_input_directory is not None:
logging.info('Loading dataset DIRLAB.')
dirlab = DIRLAB(parameters.dirlab_input_directory,
......
......@@ -114,83 +114,160 @@ if __name__ == '__main__':
"Datasets": ["POPI"],
"Components": [
{
"Name": "FixedImage",
"NameOfClass": "ItkToNiftiImageSourceComponent",
"PixelType": "float",
"Name": "RegistrationMethod",
"NameOfClass": "ItkImageRegistrationMethodv4Component",
"NumberOfLevels": "3" ,
"ShrinkFactorsPerLevel": [ "16", "8", "4", "2", "1" ],
"SmoothingSigmasPerLevel": [ "16", "8", "4", "2", "1" ],
"Dimensionality": "3"
},
{
"Name": "FixedMask",
"Name": "FixedImageCropper",
"NameOfClass": "ItkCropperComponent",
"Dimensionality": "3",
"PixelType": "float",
"Pad": 16
},
{
"Name": "MovingImageCropper",
"NameOfClass": "ItkCropperComponent",
"Dimensionality": "3",
"PixelType": "float",
"Pad": 16
},
{
"Name": "FixedImage",
"NameOfClass": "ItkImageSourceComponent",
"PixelType": "unsigned char",
"Dimensionality": "3"
},
{
"Name": "MovingImage",
"NameOfClass": "ItkToNiftiImageSourceComponent",
"PixelType": "float",
"NameOfClass": "ItkImageSourceComponent",
"Dimensionality": "3"
},
{
"Name": "FixedMask",
"NameOfClass": "ItkImageSourceComponent",
"Dimensionality": "3",
"PixelType": "unsigned char"
},
{
"Name": "MovingMask",
"NameOfClass": "ItkImageSourceComponent",
"PixelType": "unsigned char",
"Dimensionality": "3",
"PixelType": "unsigned char"
},
{
"Name": "DisplacementField",
"NameOfClass": "ItkDisplacementFieldSinkComponent",
"Dimensionality": "3"
},
{
"Name": "SplineToDisplacementField",
"NameOfClass": "NiftyregSplineToDisplacementFieldComponent"
"Name": "Metric",
"NameOfClass": "ItkANTSNeighborhoodCorrelationImageToImageMetricv4Component",
"Dimensionality": "3"
},
{
"Name": "DisplacementField",
"NameOfClass": "DisplacementFieldNiftiToItkImageSinkComponent",
"Name": "Optimizer",
"NameOfClass": "ItkGradientDescentOptimizerv4Component",
"NumberOfIterations": "32",
"LearningRate": "1.0",
"EstimateScales": "False",
"EstimateLearningRate": "False"
},
{
"Name": "Transform",
"NameOfClass": "ItkGaussianExponentialDiffeomorphicTransformComponent",
"InternalComputationValueType": "double",
"Dimensionality": "3",
"GaussianSmoothingVarianceForTheConstantVelocityField": "1.0",
"GaussianSmoothingVarianceForTheUpdateField": "1.0"
},
{
"Name": "TransformToDisplacementFilter",
"NameOfClass": "ItkTransformDisplacementFilterComponent",
"Dimensionality": "3"
}
},
{
"Name": "TransformResolutionAdaptor",
"NameOfClass": "ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorsContainerComponent",
"ShrinkFactorsPerLevel": [ "16", "8", "4", "2", "1" ],
"Dimensionality": "3"
},
],
"Connections": [
{
"Out": "FixedImage",
"In": "NiftyRegAffine",
"NameOfInterface": "NiftyregReferenceImageInterface"
"In": "FixedImageCropper",
"NameOfInterface": "itkImageInterface"
},
{
"Out": "MovingImage",
"In": "NiftyRegAffine",
"NameOfInterface": "NiftyregFloatingImageInterface"
"Out": "FixedMask",
"In": "FixedImageCropper",
"NameOfInterface": "itkImageMaskInterface"
},
{
"Out": "NiftyRegAffine",
"In": "NiftyRegSpline",
"NameOfInterface": "NiftyregAffineMatrixInterface"
"Out": "FixedImageCropper",
"In": "RegistrationMethod",
"NameOfInterface": "itkImageFixedInterface"
},
{
"Out": "FixedImage",
"In": "NiftyRegSpline",
"NameOfInterface": "NiftyregReferenceImageInterface"
"Out": "MovingImage",
"In": "MovingImageCropper",
"NameOfInterface": "itkImageInterface"
},
{
"Out": "MovingImage",
"In": "NiftyRegSpline",
"NameOfInterface": "NiftyregFloatingImageInterface"
"Out": "MovingMask",
"In": "MovingImageCropper",
"NameOfInterface": "itkImageMaskInterface"
},
{
"Out": "NiftyRegSpline",
"In": "SplineToDisplacementField",
"NameOfInterface": "NiftyregControlPointPositionImageInterface"
"Out": "MovingImageCropper",
"In": "RegistrationMethod",
"NameOfInterface": "itkImageMovingInterface"
},
{
"Out": "FixedImage",
"In": "SplineToDisplacementField",
"NameOfInterface": "NiftyregReferenceImageInterface"
"Out": "RegistrationMethod",
"In": "TransformToDisplacementFilter",
"NameOfInterface": "itkTransformInterface"
},
{
"Out": "SplineToDisplacementField",
"Out": "TransformToDisplacementFilter",
"In": "DisplacementField",
"NameOfInterface": "NiftyregDisplacementFieldImageInterface"
"NameOfInterface": "itkDisplacementFieldInterface"
},
{
"Out": "FixedImage",
"In": "DisplacementField",
"Out": "Metric",
"In": "RegistrationMethod",
"NameOfInterface": "itkMetricv4Interface"
},
{
"Out": "FixedImageCropper",
"In": "Transform",
"NameOfInterface": "itkImageDomainFixedInterface"
},
{
"Out": "Transform",
"In": "RegistrationMethod",
"NameOfInterface": "itkTransformInterface"
},
{
"Out": "FixedImageCropper",
"In": "TransformResolutionAdaptor",
"NameOfInterface": "itkImageDomainFixedInterface"
},
{
"Out": "TransformResolutionAdaptor",
"In": "RegistrationMethod"
},
{
"Out": "Optimizer",
"In": "RegistrationMethod",
"NameOfInterface": "itkOptimizerv4Interface"
},
{
"Out": "FixedImageCropper",
"In": "TransformToDisplacementFilter",
"NameOfInterface": "itkImageDomainFixedInterface"
}
]
......@@ -199,10 +276,10 @@ if __name__ == '__main__':
space = hp.choice('HyperOpt', [
{
"NiftyRegAffineHyperOptComponent": {
"Name": "NiftyRegAffine",
"NameOfClass": "NiftyregAladinComponent",
"NumberOfResolutions": hp.quniform('NiftyRegAffine_NumberOfResolutions', 2, 5, 1),
"NumberOfIterations": "30"
"Name": "TransformResolutionAdaptor",
"NameOfClass": "ItkGaussianExponentialDiffeomorphicTransformParametersAdaptorsContainerComponent",
"ShrinkFactorsPerLevel": [ "16", "8", "4", "2" ],
"Dimensionality": "3"
},
"NiftyRegBSplineHyperOptComponent": {
"Name": "NiftyRegSpline",
......
import numpy as np
import SimpleITK as sitk
from ContinuousRegistration.Source.util import warp_image, warp_point_set
from ContinuousRegistration.Source.util import warp_image, warp_point_set, compose_displacement_fields
from ContinuousRegistration.Source.util import logging
def tre(superelastix, point_sets, deformation_field_file_names):
try:
point_set_fixed0_to_moving1 = warp_point_set(superelastix, point_sets[0], deformation_field_file_names[0])
point_set_fixed1_to_moving0 = warp_point_set(superelastix, point_sets[1], deformation_field_file_names[1])
except Exception as e:
except Exception:
logging.error('Failed to compute tre for image pair (%s, %s).' % deformation_field_file_names)
return (
{
'1. TRE': np.NaN
},
{
'1. TRE': np.NaN
}
{'1. TRE': np.NaN},
{'1. TRE': np.NaN}
)
return (
{
'1. TRE': np.nanmean(np.sqrt(np.nansum((point_set_fixed0_to_moving1 - point_sets[1]) ** 2, -1)))
},
{
'1. TRE': np.nanmean(np.sqrt(np.nansum((point_set_fixed1_to_moving0 - point_sets[0]) ** 2, -1)))
}
{'1. TRE': np.nanmean(np.sqrt(np.nansum((point_set_fixed0_to_moving1 - point_sets[1]) ** 2, -1)))},
{'1. TRE': np.nanmean(np.sqrt(np.nansum((point_set_fixed1_to_moving0 - point_sets[0]) ** 2, -1)))}
)
def hausdorff(superelastix, point_sets, deformation_field_file_names):
try:
point_set_fixed0_to_moving1 = warp_point_set(superelastix, point_sets[0], deformation_field_file_names[0])
point_set_fixed1_to_moving0 = warp_point_set(superelastix, point_sets[1], deformation_field_file_names[1])
except Exception as e:
except Exception:
logging.error('Failed to compute hausdorff for image pair (%s, %s).' % deformation_field_file_names)
return (
{
'2. Hausdorff': np.NaN
},
{
'2. Hausdorff': np.NaN
}
{'2. Hausdorff': np.NaN},
{'2. Hausdorff': np.NaN}
)
return (
{
'2. Hausdorff': np.nanmax(np.sqrt(np.nansum((point_set_fixed0_to_moving1 - point_sets[1]) ** 2, -1)))
},
{
'2. Hausdorff': np.nanmax(np.sqrt(np.nansum((point_set_fixed1_to_moving0 - point_sets[0]) ** 2, -1)))
}
{'2. Hausdorff': np.nanmax(np.sqrt(np.nansum((point_set_fixed0_to_moving1 - point_sets[1]) ** 2, -1)))},
{'2. Hausdorff': np.nanmax(np.sqrt(np.nansum((point_set_fixed1_to_moving0 - point_sets[0]) ** 2, -1)))}
)
def inverse_consistency_points(superelastix, point_sets, deformation_field_file_names):
try:
point_set_fixed0_to_moving1 = warp_point_set(superelastix, point_sets[0], deformation_field_file_names[0])
point_set_fixed0_to_moving1_to_fixed0 = warp_point_set(superelastix, point_set_fixed0_to_moving1, deformation_field_file_names[1])
point_set_fixed1_to_moving0 = warp_point_set(superelastix, point_sets[1], deformation_field_file_names[1])
point_set_fixed1_to_moving0_to_fixed1 = warp_point_set(superelastix, point_set_fixed1_to_moving0, deformation_field_file_names[0])
except Exception as e:
logging.error('Failed to compute inverse consistency points for image pair (%s, %s).' % deformation_field_file_names)
return ({'3. InverseConsistencyTRE': np.NaN }, { '3. InverseConsistencyTRE': np.NaN })
return (
{
'3. InverseConsistencyTRE': np.nanmean(np.sqrt(np.nansum((point_set_fixed0_to_moving1_to_fixed0 - point_sets[0]) ** 2, -1)))
},
{
'3. InverseConsistencyTRE': np.nanmean(np.sqrt(np.nansum((point_set_fixed1_to_moving0_to_fixed1 - point_sets[1]) ** 2, -1)))
}
)
def inverse_consistency_labels(superelastix, label_file_names, deformation_field_file_names):
labelOverlapMeasurer = sitk.LabelOverlapMeasuresImageFilter()
labelOverlapMeasurer.SetGlobalDefaultCoordinateTolerance(1.0)
label_image_moving0_to_fixed1_file_name = warp_image(superelastix, label_file_names[0], deformation_field_file_names[1], 'inverse_consistency_label_0_to_1')
label_image_moving0_to_fixed1_to_moving0_file_name = warp_image(superelastix, label_image_moving0_to_fixed1_file_name, deformation_field_file_names[0], 'inverse_consistency_label_0_to_1_to_0')
label_image_moving1_to_fixed0_file_name = warp_image(superelastix, label_file_names[1], deformation_field_file_names[0], 'inverse_consistency_label_1_to_0')
label_image_moving1_to_fixed0_to_moving1_file_name = warp_image(superelastix, label_image_moving1_to_fixed0_file_name, deformation_field_file_names[1], 'inverse_consistency_label_1_to_0_to_1')
def inverse_consistency(superelastix, displacement_field_file_names, mask_file_names):
try:
label_image_0 = sitk.ReadImage(label_file_names[0])
labelOverlapMeasurer.Execute(label_image_0, sitk.Cast(sitk.ReadImage(label_image_moving0_to_fixed1_to_moving0_file_name), label_image_0.GetPixelID()))
dsc_0 = labelOverlapMeasurer.GetDiceCoefficient()
except Exception as e:
logging.error('Failed to compute inverse consistency DSC for %s' % label_file_names[0])
dsc_0 = np.NaN
composed_0 = sitk.GetArrayFromImage(sitk.ReadImage(compose_displacement_fields(superelastix, displacement_field_file_names[0], displacement_field_file_names[1])))
composed_1 = sitk.GetArrayFromImage(sitk.ReadImage(compose_displacement_fields(superelastix, displacement_field_file_names[1], displacement_field_file_names[0])))
except Exception:
return (
{'3. InverseConsistency': np.NaN},
{'3. InverseConsistency': np.NaN}
)
try:
label_image_1 = sitk.ReadImage(label_file_names[1])
labelOverlapMeasurer.Execute(label_image_1, sitk.Cast(sitk.ReadImage(label_image_moving1_to_fixed0_to_moving1_file_name), label_image_1.GetPixelID()))
dsc_1 = labelOverlapMeasurer.GetDiceCoefficient()
except Exception as e:
logging.error('Failed to compute inverse consistency DSC for %s' % label_file_names[1])
dsc_1 = np.NaN
mask_0 = sitk.GetArrayFromImage(sitk.ReadImage(mask_file_names[0])) > 0
norm_0 = np.linalg.norm(composed_0, axis=-1)
norm_0 = norm_0[mask_0]
norm_0 = np.ma.array(norm_0, mask=np.isnan(norm_0))
mask_1 = sitk.GetArrayFromImage(sitk.ReadImage(mask_file_names[1])) > 0
norm_1 = np.linalg.norm(composed_1, axis=-1)
norm_1 = norm_1[mask_1]
norm_1 = np.ma.array(norm_1, mask=np.isnan(norm_1))
return (
{
'2. InverseConsistencyDSC': dsc_0
},
{
'2. InverseConsistencyDSC': dsc_1
}
{'3. InverseConsistency': np.mean(norm_0)},
{'3. InverseConsistency': np.mean(norm_1)}
)
......@@ -118,11 +75,9 @@ def label_overlap(superelastix, label_file_names, deformation_field_file_names):
labelOverlapMeasurer.Execute(label_image_1, label_image_0_to_1)
dsc_0 = labelOverlapMeasurer.GetDiceCoefficient()
jaccard_0 = labelOverlapMeasurer.GetJaccardCoefficient()
union_0 = labelOverlapMeasurer.GetUnionOverlap()
vol_0 = labelOverlapMeasurer.GetVolumeSimilarity()
except Exception as e:
logging.error('Failed to compute DSC for %s: %s' % (label_file_names[0], e))
dsc_0 = jaccard_0 = union_0 = vol_0 = np.NaN
dsc_0 = jaccard_0 = np.NaN
label_image_1_to_0_file_name = warp_image(superelastix, label_file_names[1], deformation_field_file_names[0], 'dsc_label_1_to_0')
......@@ -132,23 +87,11 @@ def label_overlap(superelastix, label_file_names, deformation_field_file_names):
labelOverlapMeasurer.Execute(label_image_0, label_image_1_to_0)
dsc_1 = labelOverlapMeasurer.GetDiceCoefficient()
jaccard_1 = labelOverlapMeasurer.GetJaccardCoefficient()
union_1 = labelOverlapMeasurer.GetUnionOverlap()
vol_1 = labelOverlapMeasurer.GetVolumeSimilarity()
except Exception as e:
logging.error('Failed to compute DSC for %s' % label_file_names[1])
dsc_1 = jaccard_1 = union_1 = vol_1 = np.NaN
dsc_1 = jaccard_1 = np.NaN
return (
{
'1. Dice Similarity Coefficient': dsc_0,
'3. Jaccard Coefficient': jaccard_0,
'4. Union Coefficient': union_0,
'5. VolumeSimilarity': vol_0
},
{
'1. Dice Similarity Coefficient': dsc_1,
'3. Jaccard Coefficient': jaccard_1,
'4. Union Coefficient': union_1,
'5. VolumeSimilarity': vol_1
}
{'1. Dice Similarity Coefficient': dsc_0, '2. Jaccard Coefficient': jaccard_0},
{'1. Dice Similarity Coefficient': dsc_1, '2. Jaccard Coefficient': jaccard_1}
)
......@@ -338,6 +338,27 @@ def warp_image(superelastix, input_image_file_name, disp_field_file_name, type_n
return output_image_file_name
def compose_displacement_fields(superelastix, disp_field_file_name_0, disp_field_file_name_1):
output_image_base_name, output_image_ext = disp_field_file_name_0.split(os.extsep, 1)
output_image_file_name = output_image_base_name + '_inverse_consistency' + "." + output_image_ext
try:
stdout = subprocess.check_output([superelastix,
'--conf', os.path.join(os.path.dirname(os.path.realpath(__file__)), 'compose_displacement_fields.json'),
'--in', 'WarpingDisplacementField=%s' % disp_field_file_name_0,
'DisplacementField=%s' % disp_field_file_name_1,
'--out', 'DisplacementFieldSink=%s' % output_image_file_name,
'--loglevel', 'trace',
'--logfile', os.path.splitext(output_image_file_name)[0] + '.log'])
except Exception as e:
logging.error('Failed to compose blueprints %s and %s' % (disp_field_file_name_0, disp_field_file_name_1))
raise e
return output_image_file_name
def index2point(image, index_set):
dim = image.GetDimension()
direction = np.array(image.GetDirection()).reshape((dim, dim))
......
#=========================================================================
#
# Copyright Leiden University Medical Center, Erasmus University Medical
# Center and contributors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0.txt
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#=========================================================================
set(${MODULE}_INCLUDE_DIRS
${${MODULE}_SOURCE_DIR}/include)
set( ${MODULE}_TEST_SOURCE_FILES
${${MODULE}_SOURCE_DIR}/test/selxDisplacementFieldComposerTest.cxx)
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* Center and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef selxDisplacementFieldComposerComponent_h
#define selxDisplacementFieldComposerComponent_h
#include "selxSuperElastixComponent.h"
#include "selxItkObjectInterfaces.h"
#include "itkComposeDisplacementFieldsImageFilter.h"
namespace selx {
template< int Dimensionality, class TPixel, class CoordRepType >
class ItkDisplacementFieldComposerComponent : public
SuperElastixComponent<
Accepting< itkDisplacementFieldInterface< Dimensionality, CoordRepType >, itkWarpingDisplacementFieldInterface< Dimensionality, CoordRepType > >,
Providing< itkDisplacementFieldInterface< Dimensionality, CoordRepType >, UpdateInterface > >
{
public:
typedef ItkDisplacementFieldComposerComponent< Dimensionality, TPixel, CoordRepType > Self;
typedef SuperElastixComponent<
Accepting< itkDisplacementFieldInterface< Dimensionality, CoordRepType >, itkWarpingDisplacementFieldInterface< Dimensionality, CoordRepType > >,
Providing< itkDisplacementFieldInterface< Dimensionality, CoordRepType >, UpdateInterface > > Superclass;
typedef std::shared_ptr< Self > Pointer;
typedef std::shared_ptr< const Self > ConstPointer;
ItkDisplacementFieldComposerComponent( const std::string & name, LoggerImpl & logger );
using DisplacementFieldInterfaceType = typename itkDisplacementFieldInterface< Dimensionality, CoordRepType >::Type;
using DisplacementFieldInterfacePointer = typename DisplacementFieldInterfaceType::Pointer;
using WarpingDisplacementFieldInterfaceType = typename itkWarpingDisplacementFieldInterface< Dimensionality, CoordRepType >::Type;
using WarpingDisplacementFieldInterfacePointer = typename WarpingDisplacementFieldInterfaceType::Pointer;
using DisplacementFieldType = typename DisplacementFieldInterfaceType::ItkDisplacementFieldType;
using DisplacementFieldPointer = typename DisplacementFieldType::Pointer;
using WarpingDisplacementFieldType = typename WarpingDisplacementFieldInterfaceType::ItkDisplacementFieldType;
using WarpingDisplacementFieldPointer = typename WarpingDisplacementFieldType::Pointer;
using ComposeDisplacementFieldsImageFilterType = typename itk::ComposeDisplacementFieldsImageFilter< DisplacementFieldType, DisplacementFieldType >;
using ComposeDisplacementFieldsImageFilterPointer = typename ComposeDisplacementFieldsImageFilterType::Pointer;
// Accept interfaces
int Accept( DisplacementFieldInterfacePointer ) override;
int Accept( WarpingDisplacementFieldInterfacePointer ) override;
// Provide interfaces
DisplacementFieldPointer GetItkDisplacementField() override;
// Base methods
void BeforeUpdate();
bool MeetsCriterion( const ComponentBase::CriterionType & criterion ) override;
static const char * GetDescription() { return "Warp a point set based on a deformation field"; };
protected:
// return the class name and the template arguments to identify this component.
static inline const std::map< std::string, std::string > TemplateProperties()
{
return {
{ keys::NameOfClass, "ItkDisplacementFieldComposerComponent" },
{ keys::PixelType, PodString< TPixel >::Get() },
{ keys::CoordRepType, PodString< CoordRepType >::Get() },
{ keys::Dimensionality, std::to_string( Dimensionality ) }
};
}
private:
ComposeDisplacementFieldsImageFilterPointer m_ComposeDisplacementFieldsImageFilter;
DisplacementFieldPointer m_DisplacementField;
WarpingDisplacementFieldPointer m_WarpingDisplacementField;
};
} // namespace selx
#ifndef ITK_MANUAL_INSTANTIATION
#include "selxDisplacementFieldComposerComponent.hxx"
#endif
#endif // selxDisplacementFieldComposerComponent_h
/*=========================================================================
*
* Copyright Leiden University Medical Center, Erasmus University Medical
* Center and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef selxDisplacementFieldComposerComponent_hxx
#define selxDisplacementFieldComposerComponent_hxx
#include "selxDisplacementFieldComposerComponent.h"
#include "selxCheckTemplateProperties.h"
namespace selx {
template< int Dimensionality, class TPixel, class CoordRepType >
ItkDisplacementFieldComposerComponent< Dimensionality, TPixel, CoordRepType >
::ItkDisplacementFieldComposerComponent( const std::string& name, LoggerImpl& logger ) : Superclass( name, logger ) {