diff --git a/CMakeLists.txt b/CMakeLists.txt index b1dfbaf6fea..709e0a136e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,8 +277,8 @@ mark_as_advanced(ITK_LEGACY_SILENT ITK_LEGACY_REMOVE ITK_FUTURE_LEGACY_REMOVE IT if(ITKV4_COMPATIBILITY AND ITK_LEGACY_REMOVE) message(FATAL_ERROR "Invalid configuration: ITKV4_COMPATIBILITY AND ITK_LEGACY_REMOVE can not both be ON") endif() -if (NOT ITK_LEGACY_SILENT AND ITKV3_COMPATIBILITY) - message(WARNING "ITKV3_COMPATIBILITY is removed starting in ITK version 5.0.") +if (ITKV3_COMPATIBILITY) + message(FATAL_ERROR "ITKV3_COMPATIBILITY is removed starting in ITK version 5.0, this option is no longer valid.") endif() #----------------------------------------------------------------------------- diff --git a/Examples/CMakeLists.txt b/Examples/CMakeLists.txt index c9226d19496..bcc8508c223 100644 --- a/Examples/CMakeLists.txt +++ b/Examples/CMakeLists.txt @@ -16,7 +16,3 @@ add_subdirectory(Segmentation) add_subdirectory(SpatialObjects) add_subdirectory(Statistics) add_subdirectory(RegistrationITKv4) - -if(ITKV3_COMPATIBILITY) - add_subdirectory(RegistrationITKv3) -endif() diff --git a/Examples/RegistrationITKv3/BSplineWarping1.cxx b/Examples/RegistrationITKv3/BSplineWarping1.cxx deleted file mode 100644 index cd0d55934ee..00000000000 --- a/Examples/RegistrationITKv3/BSplineWarping1.cxx +++ /dev/null @@ -1,364 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to deform a 2D image using a BSplineTransform. -// -// \index{BSplineTransform} -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" - -#include "itkBSplineTransform.h" -#include "itkTransformFileWriter.h" - -// Software Guide : EndCodeSnippet - -#include - -// The following section of code implements a Command observer -// used to monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandProgressUpdate : public itk::Command -{ -public: - using Self = CommandProgressUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandProgressUpdate() {}; - -public: - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - const itk::ProcessObject * filter = static_cast< const itk::ProcessObject * >( object ); - if( ! itk::ProgressEvent().CheckEvent( &event ) ) - { - return; - } - std::cout << filter->GetProgress() << std::endl; - } -}; - - -int main( int argc, char * argv[] ) -{ - - if( argc < 5 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " coefficientsFile fixedImage "; - std::cerr << "movingImage deformedMovingImage" << std::endl; - std::cerr << "[deformationField] [transformFile]" << std::endl; - return EXIT_FAILURE; - } - -// Software Guide : BeginCodeSnippet - constexpr unsigned int ImageDimension = 2; - - using PixelType = unsigned char; - using FixedImageType = itk::Image< PixelType, ImageDimension >; - using MovingImageType = itk::Image< PixelType, ImageDimension >; - - using FixedReaderType = itk::ImageFileReader< FixedImageType >; - using MovingReaderType = itk::ImageFileReader< MovingImageType >; - - using MovingWriterType = itk::ImageFileWriter< MovingImageType >; - - - FixedReaderType::Pointer fixedReader = FixedReaderType::New(); - fixedReader->SetFileName( argv[2] ); - - try - { - fixedReader->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - MovingReaderType::Pointer movingReader = MovingReaderType::New(); - MovingWriterType::Pointer movingWriter = MovingWriterType::New(); - - movingReader->SetFileName( argv[3] ); - movingWriter->SetFileName( argv[4] ); - - - FixedImageType::ConstPointer fixedImage = fixedReader->GetOutput(); - - - using FilterType = itk::ResampleImageFilter< MovingImageType, - FixedImageType >; - - FilterType::Pointer resampler = FilterType::New(); - - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, double >; - - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - - resampler->SetInterpolator( interpolator ); - - FixedImageType::SpacingType fixedSpacing = fixedImage->GetSpacing(); - FixedImageType::PointType fixedOrigin = fixedImage->GetOrigin(); - FixedImageType::DirectionType fixedDirection = fixedImage->GetDirection(); - - resampler->SetOutputSpacing( fixedSpacing ); - resampler->SetOutputOrigin( fixedOrigin ); - resampler->SetOutputDirection( fixedDirection ); - - - FixedImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion(); - FixedImageType::SizeType fixedSize = fixedRegion.GetSize(); - resampler->SetSize( fixedSize ); - resampler->SetOutputStartIndex( fixedRegion.GetIndex() ); - - - resampler->SetInput( movingReader->GetOutput() ); - - movingWriter->SetInput( resampler->GetOutput() ); -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// We instantiate now the type of the \code{BSplineTransform} using -// as template parameters the type for coordinates representation, the -// dimension of the space, and the order of the B-spline. -// -// \index{BSplineTransform!New} -// \index{BSplineTransform!Instantiation} -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet - - const unsigned int SpaceDimension = ImageDimension; - constexpr unsigned int SplineOrder = 3; - using CoordinateRepType = double; - - using TransformType = itk::BSplineTransform< - CoordinateRepType, - SpaceDimension, - SplineOrder >; - - TransformType::Pointer bsplineTransform = TransformType::New(); - -// Software Guide : EndCodeSnippet - -// Software Guide : BeginCodeSnippet - - constexpr unsigned int numberOfGridNodes = 7; - - TransformType::PhysicalDimensionsType fixedPhysicalDimensions; - TransformType::MeshSizeType meshSize; - - for( unsigned int i=0; i< SpaceDimension; i++ ) - { - fixedPhysicalDimensions[i] = fixedSpacing[i] * static_cast( - fixedSize[i] - 1 ); - } - meshSize.Fill( numberOfGridNodes - SplineOrder ); - - bsplineTransform->SetTransformDomainOrigin( fixedOrigin ); - bsplineTransform->SetTransformDomainPhysicalDimensions( - fixedPhysicalDimensions ); - bsplineTransform->SetTransformDomainMeshSize( meshSize ); - bsplineTransform->SetTransformDomainDirection( fixedDirection ); - - - using ParametersType = TransformType::ParametersType; - const unsigned int numberOfParameters = - bsplineTransform->GetNumberOfParameters(); - - const unsigned int numberOfNodes = numberOfParameters / SpaceDimension; - - ParametersType parameters( numberOfParameters ); - -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// The B-spline grid should now be fed with coeficients at each node. Since -// this is a two dimensional grid, each node should receive two coefficients. -// Each coefficient pair is representing a displacement vector at this node. -// The coefficients can be passed to the B-spline in the form of an array where -// the first set of elements are the first component of the displacements for -// all the nodes, and the second set of elemets is formed by the second -// component of the displacements for all the nodes. -// -// In this example we read such displacements from a file, but for convinience -// we have written this file using the pairs of $(x,y)$ displacement for every -// node. The elements read from the file should therefore be reorganized when -// assigned to the elements of the array. We do this by storing all the odd -// elements from the file in the first block of the array, and all the even -// elements from the file in the second block of the array. Finally the array -// is passed to the B-spline transform using the \code{SetParameters()}. -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet - std::ifstream infile; - - infile.open( argv[1] ); - - for( unsigned int n=0; n < numberOfNodes; n++ ) - { - infile >> parameters[n]; - infile >> parameters[n+numberOfNodes]; - } - - infile.close(); -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Finally the array is passed to the B-spline transform using the -// \code{SetParameters()}. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - - bsplineTransform->SetParameters( parameters ); - -// Software Guide : EndCodeSnippet - - CommandProgressUpdate::Pointer observer = CommandProgressUpdate::New(); - - resampler->AddObserver( itk::ProgressEvent(), observer ); - - -// Software Guide : BeginLatex -// -// At this point we are ready to use the transform as part of the resample -// filter. We trigger the execution of the pipeline by invoking -// \code{Update()} on the last filter of the pipeline, in this case writer. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - resampler->SetTransform( bsplineTransform ); - - try - { - movingWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } -// Software Guide : EndCodeSnippet - - - using VectorType = itk::Vector< float, ImageDimension >; - using DisplacementFieldType = itk::Image< VectorType, ImageDimension >; - - DisplacementFieldType::Pointer field = DisplacementFieldType::New(); - field->SetRegions( fixedRegion ); - field->SetOrigin( fixedOrigin ); - field->SetSpacing( fixedSpacing ); - field->SetDirection( fixedDirection ); - field->Allocate(); - - using FieldIterator = itk::ImageRegionIterator< DisplacementFieldType >; - FieldIterator fi( field, fixedRegion ); - - fi.GoToBegin(); - - TransformType::InputPointType fixedPoint; - TransformType::OutputPointType movingPoint; - DisplacementFieldType::IndexType index; - - VectorType displacement; - - while( ! fi.IsAtEnd() ) - { - index = fi.GetIndex(); - field->TransformIndexToPhysicalPoint( index, fixedPoint ); - movingPoint = bsplineTransform->TransformPoint( fixedPoint ); - displacement = movingPoint - fixedPoint; - fi.Set( displacement ); - ++fi; - } - - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - - fieldWriter->SetInput( field ); - - if( argc >= 6 ) - { - fieldWriter->SetFileName( argv[5] ); - try - { - fieldWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - } - - if( argc >= 7 ) - { - fieldWriter->SetFileName( argv[6] ); - try - { - using TransformWriterType = itk::TransformFileWriter; - TransformWriterType::Pointer transformWriter = TransformWriterType::New(); - transformWriter->AddTransform( bsplineTransform ); - transformWriter->SetFileName( argv[6] ); - transformWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/BSplineWarping2.cxx b/Examples/RegistrationITKv3/BSplineWarping2.cxx deleted file mode 100644 index 0ee5363b06b..00000000000 --- a/Examples/RegistrationITKv3/BSplineWarping2.cxx +++ /dev/null @@ -1,364 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to deform a 3D image using a BSplineTransform. -// -// \index{BSplineTransform} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" - -#include "itkBSplineTransform.h" -#include "itkTransformFileWriter.h" - -// Software Guide : EndCodeSnippet - -#include - -// The following section of code implements a Command observer -// used to monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandProgressUpdate : public itk::Command -{ -public: - using Self = CommandProgressUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandProgressUpdate() {}; - -public: - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - const itk::ProcessObject * filter = static_cast< const itk::ProcessObject * >( object ); - if( ! itk::ProgressEvent().CheckEvent( &event ) ) - { - return; - } - std::cout << filter->GetProgress() << std::endl; - } -}; - - -int main( int argc, char * argv[] ) -{ - - if( argc < 5 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " coefficientsFile fixedImage "; - std::cerr << "movingImage deformedMovingImage" << std::endl; - std::cerr << "[deformationField]" << std::endl; - return EXIT_FAILURE; - } - -// Software Guide : BeginCodeSnippet - constexpr unsigned int ImageDimension = 3; - - using PixelType = unsigned char; - using FixedImageType = itk::Image< PixelType, ImageDimension >; - using MovingImageType = itk::Image< PixelType, ImageDimension >; - - using FixedReaderType = itk::ImageFileReader< FixedImageType >; - using MovingReaderType = itk::ImageFileReader< MovingImageType >; - - using MovingWriterType = itk::ImageFileWriter< MovingImageType >; - - - FixedReaderType::Pointer fixedReader = FixedReaderType::New(); - fixedReader->SetFileName( argv[2] ); - - try - { - fixedReader->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - MovingReaderType::Pointer movingReader = MovingReaderType::New(); - MovingWriterType::Pointer movingWriter = MovingWriterType::New(); - - movingReader->SetFileName( argv[3] ); - movingWriter->SetFileName( argv[4] ); - - - FixedImageType::ConstPointer fixedImage = fixedReader->GetOutput(); - - - using FilterType = itk::ResampleImageFilter< MovingImageType, - FixedImageType >; - - FilterType::Pointer resampler = FilterType::New(); - - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, double >; - - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - - resampler->SetInterpolator( interpolator ); - - FixedImageType::SpacingType fixedSpacing = fixedImage->GetSpacing(); - FixedImageType::PointType fixedOrigin = fixedImage->GetOrigin(); - FixedImageType::DirectionType fixedDirection = fixedImage->GetDirection(); - - resampler->SetOutputSpacing( fixedSpacing ); - resampler->SetOutputOrigin( fixedOrigin ); - resampler->SetOutputDirection( fixedDirection ); - - - FixedImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion(); - FixedImageType::SizeType fixedSize = fixedRegion.GetSize(); - resampler->SetSize( fixedSize ); - resampler->SetOutputStartIndex( fixedRegion.GetIndex() ); - - - resampler->SetInput( movingReader->GetOutput() ); - - movingWriter->SetInput( resampler->GetOutput() ); -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// We instantiate now the type of the \code{BSplineTransform} using -// as template parameters the type for coordinates representation, the -// dimension of the space, and the order of the B-spline. -// -// \index{BSplineTransform!New} -// \index{BSplineTransform!Instantiation} -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet - - const unsigned int SpaceDimension = ImageDimension; - constexpr unsigned int SplineOrder = 3; - using CoordinateRepType = double; - - using TransformType = itk::BSplineTransform< - CoordinateRepType, - SpaceDimension, - SplineOrder >; - - TransformType::Pointer bsplineTransform = TransformType::New(); - -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginCodeSnippet - - constexpr unsigned int numberOfGridNodes = 8; - - TransformType::PhysicalDimensionsType fixedPhysicalDimensions; - TransformType::MeshSizeType meshSize; - - for( unsigned int i=0; i< SpaceDimension; i++ ) - { - fixedPhysicalDimensions[i] = fixedSpacing[i] * static_cast( - fixedSize[i] - 1 ); - } - meshSize.Fill( numberOfGridNodes - SplineOrder ); - - bsplineTransform->SetTransformDomainOrigin( fixedOrigin ); - bsplineTransform->SetTransformDomainPhysicalDimensions( - fixedPhysicalDimensions ); - bsplineTransform->SetTransformDomainMeshSize( meshSize ); - bsplineTransform->SetTransformDomainDirection( fixedDirection ); - - - using ParametersType = TransformType::ParametersType; - const unsigned int numberOfParameters = - bsplineTransform->GetNumberOfParameters(); - - const unsigned int numberOfNodes = numberOfParameters / SpaceDimension; - - ParametersType parameters( numberOfParameters ); -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// The B-spline grid should now be fed with coeficients at each node. Since -// this is a two dimensional grid, each node should receive two coefficients. -// Each coefficient pair is representing a displacement vector at this node. -// The coefficients can be passed to the B-spline in the form of an array where -// the first set of elements are the first component of the displacements for -// all the nodes, and the second set of elemets is formed by the second -// component of the displacements for all the nodes. -// -// In this example we read such displacements from a file, but for convinience -// we have written this file using the pairs of $(x,y)$ displacement for every -// node. The elements read from the file should therefore be reorganized when -// assigned to the elements of the array. We do this by storing all the odd -// elements from the file in the first block of the array, and all the even -// elements from the file in the second block of the array. Finally the array -// is passed to the B-spline transform using the \code{SetParameters()}. -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet - std::ifstream infile; - - infile.open( argv[1] ); - - for( unsigned int n=0; n < numberOfNodes; n++ ) - { - infile >> parameters[n]; // X coordinate - infile >> parameters[n+numberOfNodes]; // Y coordinate - infile >> parameters[n+numberOfNodes*2]; // Z coordinate - } - - infile.close(); -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Finally the array is passed to the B-spline transform using the -// \code{SetParameters()}. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - - bsplineTransform->SetParameters( parameters ); - -// Software Guide : EndCodeSnippet - - CommandProgressUpdate::Pointer observer = CommandProgressUpdate::New(); - - resampler->AddObserver( itk::ProgressEvent(), observer ); - - -// Software Guide : BeginLatex -// -// At this point we are ready to use the transform as part of the resample -// filter. We trigger the execution of the pipeline by invoking -// \code{Update()} on the last filter of the pipeline, in this case writer. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - resampler->SetTransform( bsplineTransform ); - - try - { - movingWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } -// Software Guide : EndCodeSnippet - - - using VectorType = itk::Vector< float, ImageDimension >; - using DisplacementFieldType = itk::Image< VectorType, ImageDimension >; - - DisplacementFieldType::Pointer field = DisplacementFieldType::New(); - field->SetRegions( fixedRegion ); - field->SetOrigin( fixedOrigin ); - field->SetSpacing( fixedSpacing ); - field->SetDirection( fixedDirection ); - field->Allocate(); - - using FieldIterator = itk::ImageRegionIterator< DisplacementFieldType >; - FieldIterator fi( field, fixedRegion ); - - fi.GoToBegin(); - - TransformType::InputPointType fixedPoint; - TransformType::OutputPointType movingPoint; - DisplacementFieldType::IndexType index; - - VectorType displacement; - - while( ! fi.IsAtEnd() ) - { - index = fi.GetIndex(); - field->TransformIndexToPhysicalPoint( index, fixedPoint ); - movingPoint = bsplineTransform->TransformPoint( fixedPoint ); - displacement = movingPoint - fixedPoint; - fi.Set( displacement ); - ++fi; - } - - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - - fieldWriter->SetInput( field ); - - if( argc >= 6 ) - { - fieldWriter->SetFileName( argv[5] ); - try - { - fieldWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - } - - if( argc >= 7 ) - { - fieldWriter->SetFileName( argv[6] ); - try - { - using TransformWriterType = itk::TransformFileWriter; - TransformWriterType::Pointer transformWriter = TransformWriterType::New(); - transformWriter->AddTransform( bsplineTransform ); - transformWriter->SetFileName( argv[6] ); - transformWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/CMakeLists.txt b/Examples/RegistrationITKv3/CMakeLists.txt deleted file mode 100644 index ff2c4a97697..00000000000 --- a/Examples/RegistrationITKv3/CMakeLists.txt +++ /dev/null @@ -1,169 +0,0 @@ -project(ITKv3ImageRegistration) - -add_executable(ITKv3ImageRegistration3 ImageRegistration3.cxx ) -target_link_libraries(ITKv3ImageRegistration3 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration5 ImageRegistration5.cxx ) -target_link_libraries(ITKv3ImageRegistration5 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration6 ImageRegistration6.cxx ) -target_link_libraries(ITKv3ImageRegistration6 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration8 ImageRegistration8.cxx ) -target_link_libraries(ITKv3ImageRegistration8 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration9 ImageRegistration9.cxx ) -target_link_libraries(ITKv3ImageRegistration9 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration10 ImageRegistration10.cxx ) -target_link_libraries(ITKv3ImageRegistration10 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration4 DeformableRegistration4.cxx ) -target_link_libraries(ITKv3DeformableRegistration4 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration4 ImageRegistration4.cxx ) -target_link_libraries(ITKv3ImageRegistration4 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration7 ImageRegistration7.cxx ) -target_link_libraries(ITKv3ImageRegistration7 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration11 ImageRegistration11.cxx ) -target_link_libraries(ITKv3ImageRegistration11 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration12 ImageRegistration12.cxx ) -target_link_libraries(ITKv3ImageRegistration12 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration13 ImageRegistration13.cxx ) -target_link_libraries(ITKv3ImageRegistration13 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration14 ImageRegistration14.cxx ) -target_link_libraries(ITKv3ImageRegistration14 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration15 ImageRegistration15.cxx ) -target_link_libraries(ITKv3ImageRegistration15 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration16 ImageRegistration16.cxx ) -target_link_libraries(ITKv3ImageRegistration16 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration18 ImageRegistration18.cxx ) -target_link_libraries(ITKv3ImageRegistration18 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration19 ImageRegistration19.cxx ) -target_link_libraries(ITKv3ImageRegistration19 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration20 ImageRegistration20.cxx ) -target_link_libraries(ITKv3ImageRegistration20 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration6 DeformableRegistration6.cxx ) -target_link_libraries(ITKv3DeformableRegistration6 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration7 DeformableRegistration7.cxx ) -target_link_libraries(ITKv3DeformableRegistration7 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration8 DeformableRegistration8.cxx ) -target_link_libraries(ITKv3DeformableRegistration8 ${ITK_LIBRARIES}) - -if( ITK_USE_FFTWD AND NOT ITK_USE_CUFFTW ) - add_executable(ITKv3DeformableRegistration9 DeformableRegistration9.cxx ) - target_link_libraries(ITKv3DeformableRegistration9 ${ITK_LIBRARIES}) - - add_executable(ITKv3DeformableRegistration10 DeformableRegistration10.cxx ) - target_link_libraries(ITKv3DeformableRegistration10 ${ITK_LIBRARIES}) -endif() - -add_executable(ITKv3MultiResImageRegistration1 MultiResImageRegistration1.cxx ) -target_link_libraries(ITKv3MultiResImageRegistration1 ${ITK_LIBRARIES}) - -add_executable(ITKv3MultiResImageRegistration2 MultiResImageRegistration2.cxx ) -target_link_libraries(ITKv3MultiResImageRegistration2 ${ITK_LIBRARIES}) - -add_executable(ITKv3MultiResImageRegistration3 MultiResImageRegistration3.cxx ) -target_link_libraries(ITKv3MultiResImageRegistration3 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration1 DeformableRegistration1.cxx ) -target_link_libraries(ITKv3DeformableRegistration1 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration11 DeformableRegistration11.cxx ) -target_link_libraries(ITKv3DeformableRegistration11 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration2 DeformableRegistration2.cxx ) -target_link_libraries(ITKv3DeformableRegistration2 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration3 DeformableRegistration3.cxx ) -target_link_libraries(ITKv3DeformableRegistration3 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration5 DeformableRegistration5.cxx ) -target_link_libraries(ITKv3DeformableRegistration5 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration12 DeformableRegistration12.cxx ) -target_link_libraries(ITKv3DeformableRegistration12 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration13 DeformableRegistration13.cxx ) -target_link_libraries(ITKv3DeformableRegistration13 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration14 DeformableRegistration14.cxx ) -target_link_libraries(ITKv3DeformableRegistration14 ${ITK_LIBRARIES}) - -add_executable(ITKv3ChangeInformationImageFilter ChangeInformationImageFilter.cxx ) -target_link_libraries(ITKv3ChangeInformationImageFilter ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration15 DeformableRegistration15.cxx ) -target_link_libraries(ITKv3DeformableRegistration15 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration16 DeformableRegistration16.cxx ) -target_link_libraries(ITKv3DeformableRegistration16 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformableRegistration17 DeformableRegistration17.cxx ) -target_link_libraries(ITKv3DeformableRegistration17 ${ITK_LIBRARIES}) - -add_executable(ITKv3DisplacementFieldInitialization DisplacementFieldInitialization.cxx ) -target_link_libraries(ITKv3DisplacementFieldInitialization ${ITK_LIBRARIES}) - -add_executable(ITKv3LandmarkWarping2 LandmarkWarping2.cxx ) -target_link_libraries(ITKv3LandmarkWarping2 ${ITK_LIBRARIES}) - -add_executable(ITKv3BSplineWarping1 BSplineWarping1.cxx ) -target_link_libraries(ITKv3BSplineWarping1 ${ITK_LIBRARIES}) - -add_executable(ITKv3BSplineWarping2 BSplineWarping2.cxx ) -target_link_libraries(ITKv3BSplineWarping2 ${ITK_LIBRARIES}) - -add_executable(ITKv3ThinPlateSplineWarp ThinPlateSplineWarp.cxx ) -target_link_libraries(ITKv3ThinPlateSplineWarp ${ITK_LIBRARIES}) - -add_executable(ITKv3ModelToImageRegistration1 ModelToImageRegistration1.cxx ) -target_link_libraries(ITKv3ModelToImageRegistration1 ${ITK_LIBRARIES}) - -add_executable(ITKv3ModelToImageRegistration2 ModelToImageRegistration2.cxx ) -target_link_libraries(ITKv3ModelToImageRegistration2 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration1 ImageRegistration1.cxx ) -target_link_libraries(ITKv3ImageRegistration1 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration2 ImageRegistration2.cxx ) -target_link_libraries(ITKv3ImageRegistration2 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistration17 ImageRegistration17.cxx ) -target_link_libraries(ITKv3ImageRegistration17 ${ITK_LIBRARIES}) - -add_executable(ITKv3ImageRegistrationHistogramPlotter ImageRegistrationHistogramPlotter.cxx ) -target_link_libraries(ITKv3ImageRegistrationHistogramPlotter ${ITK_LIBRARIES}) - -add_executable(ITKv3MeanSquaresImageMetric1 MeanSquaresImageMetric1.cxx ) -target_link_libraries(ITKv3MeanSquaresImageMetric1 ${ITK_LIBRARIES}) - -add_executable(ITKv3DeformationFieldJacobian DeformationFieldJacobian.cxx ) -target_link_libraries(ITKv3DeformationFieldJacobian ${ITK_LIBRARIES}) - -add_executable(ITKv3IterativeClosestPoint1 IterativeClosestPoint1.cxx ) -target_link_libraries(ITKv3IterativeClosestPoint1 ${ITK_LIBRARIES}) - -add_executable(ITKv3IterativeClosestPoint2 IterativeClosestPoint2.cxx ) -target_link_libraries(ITKv3IterativeClosestPoint2 ${ITK_LIBRARIES}) - -add_executable(ITKv3IterativeClosestPoint3 IterativeClosestPoint3.cxx ) -target_link_libraries(ITKv3IterativeClosestPoint3 ${ITK_LIBRARIES}) - -if(BUILD_TESTING) - add_subdirectory(test) -endif() diff --git a/Examples/RegistrationITKv3/ChangeInformationImageFilter.cxx b/Examples/RegistrationITKv3/ChangeInformationImageFilter.cxx deleted file mode 100644 index a2f47fb5181..00000000000 --- a/Examples/RegistrationITKv3/ChangeInformationImageFilter.cxx +++ /dev/null @@ -1,192 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// The \doxygen{ChangeInformationImageFilter} is commonly used to modify -// image metadata such as origin, spacing, and orientation. This filter -// leaves intact the pixel data of the image. This filter should be used -// with extreme caution, since it can easily change information that is -// critical for the safety of many medical image analysis tasks, such as -// measurement the volume of a tumor, or providing guidance for surgery. -// -// The following example illustrates the use of the ChangeInformation image -// filter in the context of generating synthetic inputs for image registration -// tests. -// -// \index{itk::ChangeInformationImageFilter} -// -// Software Guide : EndLatex - -#include "itkImage.h" -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" -#include "itkVersor.h" - -// Software Guide : BeginLatex -// -// The header file corresponding to this filter should be included first. -// -// \index{itk::ChangeInformationImageFilter!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkChangeInformationImageFilter.h" -// Software Guide : EndCodeSnippet - -int main( int argc, char * argv[] ) -{ - if( argc < 3 ) - { - std::cerr << "Usage: " << std::endl; - std::cerr << argv[0] << " inputImageFile outputImageFile" << std::endl; - std::cerr << " [scalingFactor] [translationX translationY translationZ]" << std::endl; - std::cerr << " [rotationZinDegrees]" << std::endl; - return EXIT_FAILURE; - } - - // Software Guide : BeginLatex - // - // Then the pixel and image types of the input and output must be defined. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using PixelType = unsigned char; - - constexpr unsigned int Dimension = 3; - - using ImageType = itk::Image< PixelType, Dimension >; - // Software Guide : EndCodeSnippet - - using ReaderType = itk::ImageFileReader< ImageType >; - using WriterType = itk::ImageFileWriter< ImageType >; - - ReaderType::Pointer reader = ReaderType::New(); - WriterType::Pointer writer = WriterType::New(); - - reader->SetFileName( argv[1] ); - writer->SetFileName( argv[2] ); - - // Software Guide : BeginLatex - // - // Using the image types, it is now possible to define the filter type - // and create the filter object. - // - // \index{itk::ChangeInformationImageFilter!instantiation} - // \index{itk::ChangeInformationImageFilter!New()} - // \index{itk::ChangeInformationImageFilter!Pointer} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using FilterType = itk::ChangeInformationImageFilter< ImageType >; - - FilterType::Pointer filter = FilterType::New(); - // Software Guide : EndCodeSnippet - - // - // The reader must be triggered in order to make possible to gather - // information from the input image. - // - try - { - reader->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - ImageType::ConstPointer inputImage = reader->GetOutput(); - - ImageType::PointType origin = inputImage->GetOrigin(); - ImageType::SpacingType spacing = inputImage->GetSpacing(); - ImageType::DirectionType direction = inputImage->GetDirection(); - - if( argc > 3 ) - { - double scale = std::stod( argv[3] ); - for(unsigned int i=0; iSetOutputSpacing( spacing ); - filter->ChangeSpacingOn(); - } - - if( argc > 6 ) - { - ImageType::PointType::VectorType translation; - - translation[0] = std::stod( argv[4] ); - translation[1] = std::stod( argv[5] ); - translation[2] = std::stod( argv[6] ); - - origin += translation; - - filter->SetOutputOrigin( origin ); - filter->ChangeOriginOn(); - } - - if( argc > 7 ) - { - double additionalAngle = std::stod( argv[7] ); - - itk::Versor< itk::SpacePrecisionType > rotation; - double angleInRadians = additionalAngle * itk::Math::pi / 180.0; - rotation.SetRotationAroundZ( angleInRadians ); - - ImageType::DirectionType newDirection = direction * rotation.GetMatrix(); - - filter->SetOutputDirection( newDirection ); - filter->ChangeDirectionOn(); - } - - // Software Guide : BeginLatex - // - // The input to the filter can be taken from any other filter, for example - // a reader. The output can be passed down the pipeline to other filters, - // for example, a writer. An update call on any downstream filter will - // trigger the execution of the median filter. - // - // \index{itk::ChangeInformationImageFilter!SetInput()} - // \index{itk::ChangeInformationImageFilter!GetOutput()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->SetInput( reader->GetOutput() ); - writer->SetInput( filter->GetOutput() ); - // Software Guide : EndCodeSnippet - - try - { - writer->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration1.cxx b/Examples/RegistrationITKv3/DeformableRegistration1.cxx deleted file mode 100644 index 10adf6a8310..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration1.cxx +++ /dev/null @@ -1,339 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkRescaleIntensityImageFilter.h" -#include "itkHistogramMatchingImageFilter.h" - -// Software Guide : BeginLatex -// -// The finite element (FEM) library within the Insight Toolkit can be -// used to solve deformable image registration problems. The first step in -// implementing a FEM-based registration is to include the appropriate -// header files. -// -// \index{Registration!Finite Element-Based} -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet -#include "itkFEMRegistrationFilter.h" - -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// Next, we use \code{using} type alias to instantiate all necessary classes. We -// define the image and element types we plan to use to solve a -// two-dimensional registration problem. We define multiple element -// types so that they can be used without recompiling the code. -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet -using DiskImageType = itk::Image; -using ImageType = itk::Image; -using ElementType = itk::fem::Element2DC0LinearQuadrilateralMembrane; -using ElementType2 = itk::fem::Element2DC0LinearTriangularMembrane; -using FEMObjectType = itk::fem::FEMObject<2>; -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// Note that in order to solve a three-dimensional registration -// problem, we would simply define 3D image and element types in lieu -// of those above. The following declarations could be used for a 3D -// problem: -// -// SoftwareGuide : EndLatex - - -// SoftwareGuide : BeginCodeSnippet -using fileImage3DType = itk::Image; -using Image3DType = itk::Image; -using Element3DType = itk::fem::Element3DC0LinearHexahedronMembrane; -using Element3DType2 = itk::fem::Element3DC0LinearTetrahedronMembrane; -using FEMObject3DType = itk::fem::FEMObject<3>; -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// Once all the necessary components have been instantiated, we can -// instantiate the \doxygen{FEMRegistrationFilter}, which depends on the -// image input and output types. -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet - using RegistrationType = - itk::fem::FEMRegistrationFilter; -// Software Guide : EndCodeSnippet - - -int main(int argc, char *argv[]) -{ - const char *fixedImageName, *movingImageName; - if ( argc < 2 ) - { - std::cout << "Image file names missing" << std::endl; - std::cout << "Usage: " << argv[0] << " fixedImageFile movingImageFile" - << std::endl; - return EXIT_FAILURE; - } - else - { - fixedImageName = argv[1]; - movingImageName = argv[2]; - } - - -// Software Guide : BeginLatex -// -// In order to begin the registration, we declare an instance of the -// FEMRegistrationFilter and set its parameters. For simplicity, we will call -// it \code{registrationFilter}. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - RegistrationType::Pointer registrationFilter = RegistrationType::New(); - registrationFilter->SetMaxLevel(1); - registrationFilter->SetUseNormalizedGradient( true ); - registrationFilter->ChooseMetric( 0 ); - - unsigned int maxiters = 20; - float E = 100; - float p = 1; - registrationFilter->SetElasticity(E, 0); - registrationFilter->SetRho(p, 0); - registrationFilter->SetGamma(1., 0); - registrationFilter->SetAlpha(1.); - registrationFilter->SetMaximumIterations( maxiters, 0 ); - registrationFilter->SetMeshPixelsPerElementAtEachResolution(4, 0); - registrationFilter->SetWidthOfMetricRegion(1, 0); - registrationFilter->SetNumberOfIntegrationPoints(2, 0); - registrationFilter->SetDoLineSearchOnImageEnergy( 0 ); - registrationFilter->SetTimeStep(1.); - registrationFilter->SetEmployRegridding(false); - registrationFilter->SetUseLandmarks(false); -// Software Guide : EndCodeSnippet - - - // Read the image files - using FileSourceType = itk::ImageFileReader< DiskImageType >; - - FileSourceType::Pointer movingfilter = FileSourceType::New(); - movingfilter->SetFileName( movingImageName ); - FileSourceType::Pointer fixedfilter = FileSourceType::New(); - fixedfilter->SetFileName( fixedImageName ); - std::cout << " reading moving " << movingImageName << std::endl; - std::cout << " reading fixed " << fixedImageName << std::endl; - - - try - { - movingfilter->Update(); - } - catch( itk::ExceptionObject & e ) - { - std::cerr << "Exception caught during reference file reading " << std::endl; - std::cerr << e << std::endl; - return EXIT_FAILURE; - } - try - { - fixedfilter->Update(); - } - catch( itk::ExceptionObject & e ) - { - std::cerr << "Exception caught during target file reading " << std::endl; - std::cerr << e << std::endl; - return EXIT_FAILURE; - } - - - // Rescale the image intensities so that they fall between 0 and 255 - using FilterType = itk::RescaleIntensityImageFilter; - FilterType::Pointer movingrescalefilter = FilterType::New(); - FilterType::Pointer fixedrescalefilter = FilterType::New(); - - movingrescalefilter->SetInput(movingfilter->GetOutput()); - fixedrescalefilter->SetInput(fixedfilter->GetOutput()); - - constexpr double desiredMinimum = 0.0; - constexpr double desiredMaximum = 255.0; - - movingrescalefilter->SetOutputMinimum( desiredMinimum ); - movingrescalefilter->SetOutputMaximum( desiredMaximum ); - movingrescalefilter->UpdateLargestPossibleRegion(); - fixedrescalefilter->SetOutputMinimum( desiredMinimum ); - fixedrescalefilter->SetOutputMaximum( desiredMaximum ); - fixedrescalefilter->UpdateLargestPossibleRegion(); - - - // Histogram match the images - using HEFilterType = itk::HistogramMatchingImageFilter; - HEFilterType::Pointer IntensityEqualizeFilter = HEFilterType::New(); - - IntensityEqualizeFilter->SetReferenceImage( fixedrescalefilter->GetOutput() ); - IntensityEqualizeFilter->SetInput( movingrescalefilter->GetOutput() ); - IntensityEqualizeFilter->SetNumberOfHistogramLevels( 100); - IntensityEqualizeFilter->SetNumberOfMatchPoints( 15); - IntensityEqualizeFilter->ThresholdAtMeanIntensityOn(); - IntensityEqualizeFilter->Update(); - - // Set the images for registration filter - registrationFilter->SetFixedImage(fixedrescalefilter->GetOutput()); - registrationFilter->SetMovingImage(IntensityEqualizeFilter->GetOutput()); - - - itk::ImageFileWriter::Pointer writer; - writer = itk::ImageFileWriter::New(); - std::string ofn="fixed.mha"; - writer->SetFileName(ofn.c_str()); - writer->SetInput(registrationFilter->GetFixedImage() ); - - try - { - writer->Write(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - ofn="moving.mha"; - itk::ImageFileWriter::Pointer writer2; - writer2 = itk::ImageFileWriter::New(); - writer2->SetFileName(ofn.c_str()); - writer2->SetInput(registrationFilter->GetMovingImage() ); - - try - { - writer2->Write(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - -// Software Guide : BeginLatex -// -// In order to initialize the mesh of elements, we must first create -// ``dummy'' material and element objects and assign them to the -// registration filter. These objects are subsequently used to -// either read a predefined mesh from a file or generate a mesh using -// the software. The values assigned to the fields within the -// material object are arbitrary since they will be replaced with -// those specified earlier. Similarly, the element -// object will be replaced with those from the desired mesh. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - // Create the material properties - itk::fem::MaterialLinearElasticity::Pointer m; - m = itk::fem::MaterialLinearElasticity::New(); - m->SetGlobalNumber(0); - // Young's modulus of the membrane - m->SetYoungsModulus(registrationFilter->GetElasticity()); - m->SetCrossSectionalArea(1.0); // Cross-sectional area - m->SetThickness(1.0); // Thickness - m->SetMomentOfInertia(1.0); // Moment of inertia - m->SetPoissonsRatio(0.); // Poisson's ratio -- DONT CHOOSE 1.0!! - m->SetDensityHeatProduct(1.0); // Density-Heat capacity product - - // Create the element type - ElementType::Pointer e1=ElementType::New(); - e1->SetMaterial(m); - registrationFilter->SetElement(e1); - registrationFilter->SetMaterial(m); -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// Now we are ready to run the registration: -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - registrationFilter->RunRegistration(); -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// To output the image resulting from the registration, we can call -// \code{GetWarpedImage()}. The image is written in floating point -// format. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - itk::ImageFileWriter::Pointer warpedImageWriter; - warpedImageWriter = itk::ImageFileWriter::New(); - warpedImageWriter->SetInput( registrationFilter->GetWarpedImage() ); - warpedImageWriter->SetFileName("warpedMovingImage.mha"); - try - { - warpedImageWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// We can also output the displacement field resulting from the -// registration; we can call \code{GetDisplacementField()} to get the -// multi-component image. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - using DispWriterType = itk::ImageFileWriter; - DispWriterType::Pointer dispWriter = DispWriterType::New(); - dispWriter->SetInput( registrationFilter->GetDisplacementField() ); - dispWriter->SetFileName("displacement.mha"); - try - { - dispWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } -// Software Guide : EndCodeSnippet - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration11.cxx b/Examples/RegistrationITKv3/DeformableRegistration11.cxx deleted file mode 100644 index 919fa68fa56..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration11.cxx +++ /dev/null @@ -1,215 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkRescaleIntensityImageFilter.h" -#include "itkHistogramMatchingImageFilter.h" - -#include "itkFEMRegistrationFilter.h" - - -/* Example of FEM-base deformable registration in 3D */ - - -constexpr unsigned int Dimension = 3; -using FileImageType = itk::Image; -using ImageType = itk::Image; - -using ElementType = itk::fem::Element3DC0LinearHexahedronMembrane; -using ElementType2 = itk::fem::Element3DC0LinearTetrahedronMembrane; -using FEMObjectType = itk::fem::FEMObject; - -using RegistrationType = itk::fem::FEMRegistrationFilter; - - -int main(int argc, char *argv[]) -{ - const char *fixedImageName, *movingImageName; - if ( argc < 2 ) - { - std::cout << "Image file names missing" << std::endl; - std::cout << "Usage: " << argv[0] << " fixedImageFile movingImageFile" << std::endl; - return EXIT_FAILURE; - } - else - { - fixedImageName = argv[1]; - movingImageName = argv[2]; - } - - // Setup registration parameters - RegistrationType::Pointer registrationFilter = RegistrationType::New(); - registrationFilter->SetMaxLevel(1); - registrationFilter->SetUseNormalizedGradient( true ); - registrationFilter->ChooseMetric( 0 ); - - unsigned int maxiters = 20; - float E = 10; - float p = 1; - registrationFilter->SetElasticity(E, 0); - registrationFilter->SetRho(p, 0); - registrationFilter->SetGamma(1., 0); - registrationFilter->SetAlpha(1.); - registrationFilter->SetMaximumIterations( maxiters, 0 ); - registrationFilter->SetMeshPixelsPerElementAtEachResolution(4, 0); - registrationFilter->SetWidthOfMetricRegion(1, 0); - registrationFilter->SetNumberOfIntegrationPoints(2, 0); - registrationFilter->SetDescentDirectionMinimize(); - registrationFilter->SetDoLineSearchOnImageEnergy( 0 ); - registrationFilter->SetTimeStep(1.); - registrationFilter->SetEmployRegridding(false); - registrationFilter->SetUseLandmarks(false); - - // Read the image files - using FileSourceType = itk::ImageFileReader< FileImageType >; - - FileSourceType::Pointer movingfilter = FileSourceType::New(); - movingfilter->SetFileName( movingImageName ); - FileSourceType::Pointer fixedfilter = FileSourceType::New(); - fixedfilter->SetFileName( fixedImageName ); - - std::cout << " reading moving "; - std::cout << movingImageName << std::endl; - std::cout << " reading fixed "; - std::cout << fixedImageName << std::endl; - - - try - { - movingfilter->Update(); - } - catch( itk::ExceptionObject & e ) - { - std::cerr << "Exception caught during reference file reading "; - std::cerr << std::endl << e << std::endl; - return EXIT_FAILURE; - } - try - { - fixedfilter->Update(); - } - catch( itk::ExceptionObject & e ) - { - std::cerr << "Exception caught during target file reading "; - std::cerr << std::endl << e << std::endl; - return EXIT_FAILURE; - } - - - // Rescale the image intensities so that they fall between 0 and 255 - using FilterType = itk::RescaleIntensityImageFilter< - FileImageType, ImageType >; - - FilterType::Pointer movingrescalefilter = FilterType::New(); - FilterType::Pointer fixedrescalefilter = FilterType::New(); - - movingrescalefilter->SetInput(movingfilter->GetOutput()); - fixedrescalefilter->SetInput(fixedfilter->GetOutput()); - - constexpr double desiredMinimum = 0.0; - constexpr double desiredMaximum = 255.0; - - movingrescalefilter->SetOutputMinimum( desiredMinimum ); - movingrescalefilter->SetOutputMaximum( desiredMaximum ); - movingrescalefilter->UpdateLargestPossibleRegion(); - fixedrescalefilter->SetOutputMinimum( desiredMinimum ); - fixedrescalefilter->SetOutputMaximum( desiredMaximum ); - fixedrescalefilter->UpdateLargestPossibleRegion(); - - - // Histogram match the images - using HEFilterType = itk::HistogramMatchingImageFilter; - HEFilterType::Pointer IntensityEqualizeFilter = HEFilterType::New(); - - IntensityEqualizeFilter->SetReferenceImage( fixedrescalefilter->GetOutput() ); - IntensityEqualizeFilter->SetInput( movingrescalefilter->GetOutput() ); - IntensityEqualizeFilter->SetNumberOfHistogramLevels( 100); - IntensityEqualizeFilter->SetNumberOfMatchPoints( 15); - IntensityEqualizeFilter->ThresholdAtMeanIntensityOn(); - IntensityEqualizeFilter->Update(); - - registrationFilter->SetFixedImage(fixedrescalefilter->GetOutput()); - registrationFilter->SetMovingImage(IntensityEqualizeFilter->GetOutput()); - - - itk::ImageFileWriter::Pointer writer; - writer = itk::ImageFileWriter::New(); - - writer->SetFileName("fixed.mhd"); - writer->SetInput(registrationFilter->GetFixedImage() ); - writer->Write(); - - itk::ImageFileWriter::Pointer writer2; - writer2 = itk::ImageFileWriter::New(); - writer2->SetFileName("moving.mhd"); - writer2->SetInput(registrationFilter->GetMovingImage() ); - writer2->Write(); - - - // Create the material properties - itk::fem::MaterialLinearElasticity::Pointer m; - m = itk::fem::MaterialLinearElasticity::New(); - m->SetGlobalNumber(0); - m->SetYoungsModulus(registrationFilter->GetElasticity()); // Young's modulus used in the membrane - m->SetCrossSectionalArea(1.0); // Cross-sectional area - m->SetThickness(1.0); // Thickness - m->SetMomentOfInertia(1.0); // Moment of inertia - m->SetPoissonsRatio(0.); // Poisson's ratio -- DONT CHOOSE 1.0!! - m->SetDensityHeatProduct(1.0); // Density-Heat capacity product - - // Create the element type - ElementType::Pointer e1=ElementType::New(); - e1->SetMaterial(m); - registrationFilter->SetElement(e1); - registrationFilter->SetMaterial(m); - - // Run registration - registrationFilter->RunRegistration(); - - // Warp the moving image and write it to a file. - writer->SetFileName("warpedMovingImage.mhd"); - writer->SetInput( registrationFilter->GetWarpedImage() ); - try - { - writer->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - // output the displacement field - using DispWriterType = itk::ImageFileWriter; - DispWriterType::Pointer dispWriter = DispWriterType::New(); - dispWriter->SetInput( registrationFilter->GetDisplacementField() ); - dispWriter->SetFileName("displacement.mha"); - try - { - dispWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration13.cxx b/Examples/RegistrationITKv3/DeformableRegistration13.cxx deleted file mode 100644 index 47f3bfade90..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration13.cxx +++ /dev/null @@ -1,489 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example is almost identical to -// Section~\ref{sec:DeformableRegistration12}, with the difference that it -// illustrates who to use the RegularStepGradientDescentOptimizer for a -// deformable registration task. -// -// \index{itk::BSplineTransform} -// \index{itk::BSplineTransform!DeformableRegistration} -// \index{itk::RegularStepGradientDescentOptimizer} -// -// -// Software Guide : EndLatex - -#include "itkImageRegistrationMethod.h" -#include "itkMattesMutualInformationImageToImageMetric.h" - -#include "itkTimeProbesCollectorBase.h" -#include "itkMemoryProbesCollectorBase.h" - -// Software Guide : BeginLatex -// -// The following are the most relevant headers to this example. -// -// \index{itk::BSplineTransform!header} -// \index{itk::RegularStepGradientDescentOptimizer!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkBSplineTransform.h" -#include "itkRegularStepGradientDescentOptimizer.h" -// Software Guide : EndCodeSnippet -#include "itkMersenneTwisterRandomVariateGenerator.h" - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkSquaredDifferenceImageFilter.h" - - -// The following section of code implements a Command observer -// used to monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - std::cout << "Iteration : "; - std::cout << optimizer->GetCurrentIteration() << " "; - std::cout << optimizer->GetValue() << " "; - std::cout << std::endl; - } -}; - - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile outputImagefile "; - std::cerr << " [differenceOutputfile] [differenceBeforeRegistration] "; - std::cerr << " [deformationField] "; - std::cerr << " [useExplicitPDFderivatives ] [useCachingBSplineWeights ] "; - std::cerr << " [filenameForFinalTransformParameters] "; - std::cerr << std::endl; - return EXIT_FAILURE; - } - - - constexpr unsigned int ImageDimension = 2; - using PixelType = unsigned char; - - using FixedImageType = itk::Image< PixelType, ImageDimension >; - using MovingImageType = itk::Image< PixelType, ImageDimension >; - - - // Software Guide : BeginLatex - // - // We instantiate now the type of the \code{BSplineTransform} - // using as template parameters the type for coordinates representation, the - // dimension of the space, and the order of the BSpline. We also intantiate - // the type of the optimizer. - // - // \index{BSplineTransform!New} - // \index{BSplineTransform!Instantiation} - // \index{RegularStepGradientDescentOptimizer!Instantiation} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - const unsigned int SpaceDimension = ImageDimension; - constexpr unsigned int SplineOrder = 3; - using CoordinateRepType = double; - - using TransformType = itk::BSplineTransform< - CoordinateRepType, - SpaceDimension, - SplineOrder >; - - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - // Software Guide : EndCodeSnippet - - - using MetricType = itk::MattesMutualInformationImageToImageMetric< - FixedImageType, - MovingImageType >; - - using InterpolatorType = itk:: LinearInterpolateImageFunction< - MovingImageType, - double >; - - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - MetricType::Pointer metric = MetricType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetInterpolator( interpolator ); - - - TransformType::Pointer transform = TransformType::New(); - registration->SetTransform( transform ); - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - FixedImageType::ConstPointer fixedImage = fixedImageReader->GetOutput(); - - registration->SetFixedImage( fixedImage ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - fixedImageReader->Update(); - - FixedImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion(); - - registration->SetFixedImageRegion( fixedRegion ); - - unsigned int numberOfGridNodesInOneDimension = 7; - - // Software Guide : BeginCodeSnippet - - TransformType::PhysicalDimensionsType fixedPhysicalDimensions; - TransformType::MeshSizeType meshSize; - TransformType::OriginType fixedOrigin; - - for( unsigned int i=0; i< SpaceDimension; i++ ) - { - fixedOrigin[i] = fixedImage->GetOrigin()[i]; - fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] * - static_cast( - fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 ); - } - meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder ); - - transform->SetTransformDomainOrigin( fixedOrigin ); - transform->SetTransformDomainPhysicalDimensions( - fixedPhysicalDimensions ); - transform->SetTransformDomainMeshSize( meshSize ); - transform->SetTransformDomainDirection( fixedImage->GetDirection() ); - - using ParametersType = TransformType::ParametersType; - - const unsigned int numberOfParameters = - transform->GetNumberOfParameters(); - - ParametersType parameters( numberOfParameters ); - - parameters.Fill( 0.0 ); - - transform->SetParameters( parameters ); - - registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Next we set the parameters of the RegularStepGradientDescentOptimizer. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->SetMaximumStepLength( 10.0 ); - optimizer->SetMinimumStepLength( 0.01 ); - - optimizer->SetRelaxationFactor( 0.7 ); - optimizer->SetNumberOfIterations( 200 ); - // Software Guide : EndCodeSnippet - - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - metric->SetNumberOfHistogramBins( 50 ); - - const unsigned int numberOfSamples = - static_cast( fixedRegion.GetNumberOfPixels() * 60.0 / 100.0 ); - - metric->SetNumberOfSpatialSamples( numberOfSamples ); - - // For consistent results when regression testing. - metric->ReinitializeSeed( 121213 ); - - if( argc > 7 ) - { - // Define whether to calculate the metric derivative by explicitly - // computing the derivatives of the joint PDF with respect to the Transform - // parameters, or doing it by progressively accumulating contributions from - // each bin in the joint PDF. - metric->SetUseExplicitPDFDerivatives( std::stoi( argv[7] ) ); - } - - if( argc > 8 ) - { - // Define whether to cache the BSpline weights and indexes corresponding to - // each one of the samples used to compute the metric. Enabling caching will - // make the algorithm run faster but it will have a cost on the amount of memory - // that needs to be allocated. This option is only relevant when using the - // BSplineTransform. - metric->SetUseCachingOfBSplineWeights( std::stoi( argv[8] ) ); - } - - - // Add a time probe - itk::TimeProbesCollectorBase chronometer; - itk::MemoryProbesCollectorBase memorymeter; - - std::cout << std::endl << "Starting Registration" << std::endl; - - try - { - memorymeter.Start( "Registration" ); - chronometer.Start( "Registration" ); - - registration->Update(); - - chronometer.Stop( "Registration" ); - memorymeter.Stop( "Registration" ); - - std::cout << "Optimizer stop condition = " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - OptimizerType::ParametersType finalParameters = - registration->GetLastTransformParameters(); - - - // Report the time and memory taken by the registration - chronometer.Report( std::cout ); - memorymeter.Report( std::cout ); - - transform->SetParameters( finalParameters ); - - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( transform ); - resample->SetInput( movingImageReader->GetOutput() ); - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - - // This value is set to zero in order to make easier to perform - // regression testing in this example. However, for didactic - // exercise it will be better to set it to a medium gray value - // such as 100 or 128. - resample->SetDefaultPixelValue( 0 ); - - using OutputPixelType = unsigned char; - - using OutputImageType = itk::Image< OutputPixelType, ImageDimension >; - - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - - writer->SetFileName( argv[3] ); - - - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - - - try - { - writer->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - using DifferenceFilterType = itk::SquaredDifferenceImageFilter< - FixedImageType, - FixedImageType, - OutputImageType >; - - DifferenceFilterType::Pointer difference = DifferenceFilterType::New(); - - WriterType::Pointer writer2 = WriterType::New(); - writer2->SetInput( difference->GetOutput() ); - - - // Compute the difference image between the - // fixed and resampled moving image. - if( argc > 4 ) - { - difference->SetInput1( fixedImageReader->GetOutput() ); - difference->SetInput2( resample->GetOutput() ); - writer2->SetFileName( argv[4] ); - try - { - writer2->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - } - - - // Compute the difference image between the - // fixed and moving image before registration. - if( argc > 5 ) - { - writer2->SetFileName( argv[5] ); - difference->SetInput1( fixedImageReader->GetOutput() ); - difference->SetInput2( movingImageReader->GetOutput() ); - try - { - writer2->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - } - - // Generate the explicit deformation field resulting from - // the registration. - if( argc > 6 ) - { - - using VectorType = itk::Vector< float, ImageDimension >; - using DisplacementFieldType = itk::Image< VectorType, ImageDimension >; - - DisplacementFieldType::Pointer field = DisplacementFieldType::New(); - field->SetRegions( fixedRegion ); - field->SetOrigin( fixedImage->GetOrigin() ); - field->SetSpacing( fixedImage->GetSpacing() ); - field->SetDirection( fixedImage->GetDirection() ); - field->Allocate(); - - using FieldIterator = itk::ImageRegionIterator< DisplacementFieldType >; - FieldIterator fi( field, fixedRegion ); - - fi.GoToBegin(); - - TransformType::InputPointType fixedPoint; - TransformType::OutputPointType movingPoint; - DisplacementFieldType::IndexType index; - - VectorType displacement; - - while( ! fi.IsAtEnd() ) - { - index = fi.GetIndex(); - field->TransformIndexToPhysicalPoint( index, fixedPoint ); - movingPoint = transform->TransformPoint( fixedPoint ); - displacement = movingPoint - fixedPoint; - fi.Set( displacement ); - ++fi; - } - - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - - fieldWriter->SetInput( field ); - - fieldWriter->SetFileName( argv[6] ); - try - { - fieldWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - } - - // Optionally, save the transform parameters in a file - if( argc > 9 ) - { - std::ofstream parametersFile; - parametersFile.open( argv[9] ); - parametersFile << finalParameters << std::endl; - parametersFile.close(); - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration14.cxx b/Examples/RegistrationITKv3/DeformableRegistration14.cxx deleted file mode 100644 index e616269321b..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration14.cxx +++ /dev/null @@ -1,474 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates the use of the \doxygen{RegularStepGradientDescentOptimizer} -// in the context of a deformable registration problem. The code of this example is almost -// identical to the one in Section~\ref{sec:DeformableRegistration8}. -// -// \index{itk::BSplineTransform} -// \index{itk::BSplineTransform!DeformableRegistration} -// \index{itk::RegularStepGradientDescentOptimizer} -// -// -// Software Guide : EndLatex - -#include "itkImageRegistrationMethod.h" -#include "itkMattesMutualInformationImageToImageMetric.h" - -#include "itkTimeProbesCollectorBase.h" -#include "itkMemoryProbesCollectorBase.h" - -// Software Guide : BeginLatex -// -// The following are the most relevant headers to this example. -// -// \index{itk::BSplineTransform!header} -// \index{itk::RegularStepGradientDescentOptimizer!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkBSplineTransform.h" -#include "itkRegularStepGradientDescentOptimizer.h" -// Software Guide : EndCodeSnippet - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkSquaredDifferenceImageFilter.h" - -#include "itkTransformFileReader.h" - -// The following section of code implements a Command observer -// used to monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - std::cout << optimizer->GetCurrentIteration() << " "; - std::cout << optimizer->GetValue() << " "; - std::cout << std::endl; - } -}; - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile outputImagefile "; - std::cerr << " [differenceOutputfile] [differenceBeforeRegistration] "; - std::cerr << " [deformationField] "; - std::cerr << " [useExplicitPDFderivatives ] [useCachingBSplineWeights ] "; - std::cerr << " [filenameForFinalTransformParameters] "; - std::cerr << " [maximumStepLength] [maximumNumberOfIterations]"; - std::cerr << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int ImageDimension = 3; - using PixelType = signed short; - - using FixedImageType = itk::Image< PixelType, ImageDimension >; - using MovingImageType = itk::Image< PixelType, ImageDimension >; - - const unsigned int SpaceDimension = ImageDimension; - constexpr unsigned int SplineOrder = 3; - using CoordinateRepType = double; - - using TransformType = itk::BSplineTransform< - CoordinateRepType, - SpaceDimension, - SplineOrder >; - - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - - using MetricType = itk::MattesMutualInformationImageToImageMetric< - FixedImageType, - MovingImageType >; - - using InterpolatorType = itk:: LinearInterpolateImageFunction< - MovingImageType, - double >; - - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - MetricType::Pointer metric = MetricType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetInterpolator( interpolator ); - - TransformType::Pointer transform = TransformType::New(); - registration->SetTransform( transform ); - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - FixedImageType::ConstPointer fixedImage = fixedImageReader->GetOutput(); - - registration->SetFixedImage( fixedImage ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - fixedImageReader->Update(); - - FixedImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion(); - - registration->SetFixedImageRegion( fixedRegion ); - - unsigned int numberOfGridNodesInOneDimension = 5; - - // Software Guide : BeginCodeSnippet - - TransformType::PhysicalDimensionsType fixedPhysicalDimensions; - TransformType::MeshSizeType meshSize; - TransformType::OriginType fixedOrigin; - - for( unsigned int i=0; i< SpaceDimension; i++ ) - { - fixedOrigin[i] = fixedImage->GetOrigin()[i]; - fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] * - static_cast( - fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 ); - } - meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder ); - - transform->SetTransformDomainOrigin( fixedOrigin ); - transform->SetTransformDomainPhysicalDimensions( - fixedPhysicalDimensions ); - transform->SetTransformDomainMeshSize( meshSize ); - transform->SetTransformDomainDirection( fixedImage->GetDirection() ); - - using ParametersType = TransformType::ParametersType; - - const unsigned int numberOfParameters = - transform->GetNumberOfParameters(); - - ParametersType parameters( numberOfParameters ); - - parameters.Fill( 0.0 ); - - transform->SetParameters( parameters ); - - registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet - - parameters.Fill( 0.0 ); - - transform->SetParameters( parameters ); - - registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Next we set the parameters of the RegularStepGradientDescentOptimizer object. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->SetMaximumStepLength( 10.0 ); - optimizer->SetMinimumStepLength( 0.01 ); - - optimizer->SetRelaxationFactor( 0.7 ); - optimizer->SetNumberOfIterations( 50 ); - // Software Guide : EndCodeSnippet - - // Optionally, get the step length from the command line arguments - if( argc > 12 ) - { - optimizer->SetMaximumStepLength( std::stod( argv[12] ) ); - } - - // Optionally, get the number of iterations from the command line arguments - if( argc > 13 ) - { - optimizer->SetNumberOfIterations( std::stoi( argv[13] ) ); - } - - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - metric->SetNumberOfHistogramBins( 50 ); - - const unsigned int numberOfSamples = - static_cast( fixedRegion.GetNumberOfPixels() * 20.0 / 100.0 ); - - metric->SetNumberOfSpatialSamples( numberOfSamples ); - metric->ReinitializeSeed( 76926294 ); - - if( argc > 7 ) - { - // Define whether to calculate the metric derivative by explicitly - // computing the derivatives of the joint PDF with respect to the Transform - // parameters, or doing it by progressively accumulating contributions from - // each bin in the joint PDF. - metric->SetUseExplicitPDFDerivatives( std::stoi( argv[7] ) ); - } - - if( argc > 8 ) - { - // Define whether to cache the BSpline weights and indexes corresponding to - // each one of the samples used to compute the metric. Enabling caching will - // make the algorithm run faster but it will have a cost on the amount of memory - // that needs to be allocated. This option is only relevant when using the - // BSplineTransform. - metric->SetUseCachingOfBSplineWeights( std::stoi( argv[8] ) ); - } - - // Add time and memory probes - itk::TimeProbesCollectorBase chronometer; - itk::MemoryProbesCollectorBase memorymeter; - - std::cout << std::endl << "Starting Registration" << std::endl; - - try - { - memorymeter.Start( "Registration" ); - chronometer.Start( "Registration" ); - - registration->Update(); - - chronometer.Stop( "Registration" ); - memorymeter.Stop( "Registration" ); - - std::cout << "Optimizer stop condition = " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - OptimizerType::ParametersType finalParameters = - registration->GetLastTransformParameters(); - - // Report the time and memory taken by the registration - chronometer.Report( std::cout ); - memorymeter.Report( std::cout ); - - transform->SetParameters( finalParameters ); - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( transform ); - resample->SetInput( movingImageReader->GetOutput() ); - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - - // This value is set to zero in order to make easier to perform - // regression testing in this example. However, for didactic - // exercise it will be better to set it to a medium gray value - // such as 100 or 128. - resample->SetDefaultPixelValue( 0 ); - - using OutputPixelType = signed short; - - using OutputImageType = itk::Image< OutputPixelType, ImageDimension >; - - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - writer->SetFileName( argv[3] ); - - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - - try - { - writer->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - using DifferenceFilterType = itk::SquaredDifferenceImageFilter< - FixedImageType, - FixedImageType, - OutputImageType >; - - DifferenceFilterType::Pointer difference = DifferenceFilterType::New(); - - WriterType::Pointer writer2 = WriterType::New(); - writer2->SetInput( difference->GetOutput() ); - - // Compute the difference image between the - // fixed and resampled moving image. - if( argc > 4 ) - { - difference->SetInput1( fixedImageReader->GetOutput() ); - difference->SetInput2( resample->GetOutput() ); - writer2->SetFileName( argv[4] ); - try - { - writer2->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - } - - // Compute the difference image between the - // fixed and moving image before registration. - if( argc > 5 ) - { - writer2->SetFileName( argv[5] ); - difference->SetInput1( fixedImageReader->GetOutput() ); - difference->SetInput2( movingImageReader->GetOutput() ); - try - { - writer2->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - } - - // Generate the explicit deformation field resulting from - // the registration. - if( argc > 6 ) - { - - using VectorType = itk::Vector< float, ImageDimension >; - using DisplacementFieldType = itk::Image< VectorType, ImageDimension >; - - DisplacementFieldType::Pointer field = DisplacementFieldType::New(); - field->SetRegions( fixedRegion ); - field->SetOrigin( fixedImage->GetOrigin() ); - field->SetSpacing( fixedImage->GetSpacing() ); - field->SetDirection( fixedImage->GetDirection() ); - field->Allocate(); - - using FieldIterator = itk::ImageRegionIterator< DisplacementFieldType >; - FieldIterator fi( field, fixedRegion ); - - fi.GoToBegin(); - - TransformType::InputPointType fixedPoint; - TransformType::OutputPointType movingPoint; - DisplacementFieldType::IndexType index; - - VectorType displacement; - - while( ! fi.IsAtEnd() ) - { - index = fi.GetIndex(); - field->TransformIndexToPhysicalPoint( index, fixedPoint ); - movingPoint = transform->TransformPoint( fixedPoint ); - displacement = movingPoint - fixedPoint; - fi.Set( displacement ); - ++fi; - } - - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - - fieldWriter->SetInput( field ); - - fieldWriter->SetFileName( argv[6] ); - try - { - fieldWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - } - - // Optionally, save the transform parameters in a file - if( argc > 9 ) - { - std::ofstream parametersFile; - parametersFile.open( argv[9] ); - parametersFile << finalParameters << std::endl; - parametersFile.close(); - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration15.cxx b/Examples/RegistrationITKv3/DeformableRegistration15.cxx deleted file mode 100644 index 48cbea2bfc9..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration15.cxx +++ /dev/null @@ -1,866 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates a realistic pipeline for solving a full deformable registration problem. -// -// First the two images are roughly aligned by using a transform -// initialization, then they are registered using a rigid transform, that in -// turn, is used to initialize a registration with an affine transform. The -// transform resulting from the affine registration is used as the bulk -// transform of a BSplineTransform. The deformable registration is -// computed, and finally the resulting transform is used to resample the moving -// image. -// -// Software Guide : EndLatex - -#include "itkImageRegistrationMethod.h" -#include "itkMattesMutualInformationImageToImageMetric.h" - -#include "itkTimeProbesCollectorBase.h" -#include "itkMemoryProbesCollectorBase.h" - -// Software Guide : BeginLatex -// -// The following are the most relevant headers to this example. -// -// \index{itk::VersorRigid3DTransform!header} -// \index{itk::AffineTransform!header} -// \index{itk::BSplineTransform!header} -// \index{itk::RegularStepGradientDescentOptimizer!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkCenteredTransformInitializer.h" -#include "itkVersorRigid3DTransform.h" -#include "itkAffineTransform.h" -#include "itkBSplineTransform.h" -#include "itkRegularStepGradientDescentOptimizer.h" -// Software Guide : EndCodeSnippet - -#include "itkBSplineResampleImageFunction.h" -#include "itkBSplineDecompositionImageFilter.h" - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkSquaredDifferenceImageFilter.h" - - -#include "itkTransformFileReader.h" - -// The following section of code implements a Command observer -// used to monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - std::cout << optimizer->GetCurrentIteration() << " "; - std::cout << optimizer->GetValue() << " "; - std::cout << std::endl; - } -}; - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile outputImagefile "; - std::cerr << " [differenceOutputfile] [differenceBeforeRegistration] "; - std::cerr << " [deformationField] "; - std::cerr << " [useExplicitPDFderivatives ] [useCachingBSplineWeights ] "; - std::cerr << " [filenameForFinalTransformParameters] "; - std::cerr << " [numberOfGridNodesInsideImageInOneDimensionCoarse] "; - std::cerr << " [numberOfGridNodesInsideImageInOneDimensionFine] "; - std::cerr << " [maximumStepLength] [maximumNumberOfIterations]"; - std::cerr << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int ImageDimension = 3; - using PixelType = signed short; - - using FixedImageType = itk::Image< PixelType, ImageDimension >; - using MovingImageType = itk::Image< PixelType, ImageDimension >; - - - const unsigned int SpaceDimension = ImageDimension; - - constexpr unsigned int SplineOrder = 3; - using CoordinateRepType = double; - - using RigidTransformType = itk::VersorRigid3DTransform< double >; - - using AffineTransformType = itk::AffineTransform< double, SpaceDimension >; - - using DeformableTransformType = itk::BSplineTransform< - CoordinateRepType, - SpaceDimension, - SplineOrder >; - - using TransformInitializerType = itk::CenteredTransformInitializer< RigidTransformType, - FixedImageType, MovingImageType >; - - - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - - - using MetricType = itk::MattesMutualInformationImageToImageMetric< - FixedImageType, - MovingImageType >; - - using InterpolatorType = itk:: LinearInterpolateImageFunction< - MovingImageType, - double >; - - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - MetricType::Pointer metric = MetricType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetInterpolator( interpolator ); - - // Auxiliary identity transform. - using IdentityTransformType = itk::IdentityTransform; - IdentityTransformType::Pointer identityTransform = IdentityTransformType::New(); - - - // - // Read the Fixed and Moving images. - // - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - try - { - fixedImageReader->Update(); - movingImageReader->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - FixedImageType::ConstPointer fixedImage = fixedImageReader->GetOutput(); - - registration->SetFixedImage( fixedImage ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - // - // Add a time and memory probes collector for profiling the computation time - // of every stage. - // - itk::TimeProbesCollectorBase chronometer; - itk::MemoryProbesCollectorBase memorymeter; - - - // - // Setup the metric parameters - // - metric->SetNumberOfHistogramBins( 50 ); - - FixedImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion(); - - const unsigned int numberOfPixels = fixedRegion.GetNumberOfPixels(); - - metric->ReinitializeSeed( 76926294 ); - - - if( argc > 7 ) - { - // Define whether to calculate the metric derivative by explicitly - // computing the derivatives of the joint PDF with respect to the Transform - // parameters, or doing it by progressively accumulating contributions from - // each bin in the joint PDF. - metric->SetUseExplicitPDFDerivatives( std::stoi( argv[7] ) ); - } - - if( argc > 8 ) - { - // Define whether to cache the BSpline weights and indexes corresponding to - // each one of the samples used to compute the metric. Enabling caching will - // make the algorithm run faster but it will have a cost on the amount of memory - // that needs to be allocated. This option is only relevant when using the - // BSplineTransform. - metric->SetUseCachingOfBSplineWeights( std::stoi( argv[8] ) ); - } - - - // - // Initialize a rigid transform by using Image Intensity Moments - // - TransformInitializerType::Pointer initializer = TransformInitializerType::New(); - - RigidTransformType::Pointer rigidTransform = RigidTransformType::New(); - - initializer->SetTransform( rigidTransform ); - initializer->SetFixedImage( fixedImageReader->GetOutput() ); - initializer->SetMovingImage( movingImageReader->GetOutput() ); - initializer->MomentsOn(); - - - std::cout << "Starting Rigid Transform Initialization " << std::endl; - - memorymeter.Start( "Rigid Initialization" ); - chronometer.Start( "Rigid Initialization" ); - - initializer->InitializeTransform(); - - chronometer.Stop( "Rigid Initialization" ); - memorymeter.Stop( "Rigid Initialization" ); - - std::cout << "Rigid Transform Initialization completed" << std::endl; - std::cout << std::endl; - - registration->SetFixedImageRegion( fixedRegion ); - registration->SetInitialTransformParameters( rigidTransform->GetParameters() ); - - registration->SetTransform( rigidTransform ); - - // - // Define optimizer normaliztion to compensate for different dynamic range - // of rotations and translations. - // - using OptimizerScalesType = OptimizerType::ScalesType; - OptimizerScalesType optimizerScales( rigidTransform->GetNumberOfParameters() ); - const double translationScale = 1.0 / 1000.0; - - optimizerScales[0] = 1.0; - optimizerScales[1] = 1.0; - optimizerScales[2] = 1.0; - optimizerScales[3] = translationScale; - optimizerScales[4] = translationScale; - optimizerScales[5] = translationScale; - - optimizer->SetScales( optimizerScales ); - - optimizer->SetMaximumStepLength( 0.2000 ); - optimizer->SetMinimumStepLength( 0.0001 ); - - optimizer->SetNumberOfIterations( 200 ); - - // - // The rigid transform has 6 parameters we use therefore a few samples to run - // this stage. - // - // Regulating the number of samples in the Metric is equivalent to performing - // multi-resolution registration because it is indeed a sub-sampling of the - // image. - metric->SetNumberOfSpatialSamples( 10000L ); - - // - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - - std::cout << "Starting Rigid Registration " << std::endl; - - try - { - memorymeter.Start( "Rigid Registration" ); - chronometer.Start( "Rigid Registration" ); - - registration->Update(); - - chronometer.Stop( "Rigid Registration" ); - memorymeter.Stop( "Rigid Registration" ); - - std::cout << "Optimizer stop condition = " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - std::cout << "Rigid Registration completed" << std::endl; - std::cout << std::endl; - - rigidTransform->SetParameters( registration->GetLastTransformParameters() ); - - - // - // Perform Affine Registration - // - AffineTransformType::Pointer affineTransform = AffineTransformType::New(); - - affineTransform->SetCenter( rigidTransform->GetCenter() ); - affineTransform->SetTranslation( rigidTransform->GetTranslation() ); - affineTransform->SetMatrix( rigidTransform->GetMatrix() ); - - registration->SetTransform( affineTransform ); - registration->SetInitialTransformParameters( affineTransform->GetParameters() ); - - optimizerScales = OptimizerScalesType( affineTransform->GetNumberOfParameters() ); - - optimizerScales[0] = 1.0; - optimizerScales[1] = 1.0; - optimizerScales[2] = 1.0; - optimizerScales[3] = 1.0; - optimizerScales[4] = 1.0; - optimizerScales[5] = 1.0; - optimizerScales[6] = 1.0; - optimizerScales[7] = 1.0; - optimizerScales[8] = 1.0; - - optimizerScales[9] = translationScale; - optimizerScales[10] = translationScale; - optimizerScales[11] = translationScale; - - optimizer->SetScales( optimizerScales ); - - optimizer->SetMaximumStepLength( 0.2000 ); - optimizer->SetMinimumStepLength( 0.0001 ); - - optimizer->SetNumberOfIterations( 200 ); - - // - // The Affine transform has 12 parameters we use therefore a more samples to run - // this stage. - // - // Regulating the number of samples in the Metric is equivalent to performing - // multi-resolution registration because it is indeed a sub-sampling of the - // image. - metric->SetNumberOfSpatialSamples( 50000L ); - - - std::cout << "Starting Affine Registration " << std::endl; - - try - { - memorymeter.Start( "Affine Registration" ); - chronometer.Start( "Affine Registration" ); - - registration->Update(); - - chronometer.Stop( "Affine Registration" ); - memorymeter.Stop( "Affine Registration" ); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - std::cout << "Affine Registration completed" << std::endl; - std::cout << std::endl; - - affineTransform->SetParameters( registration->GetLastTransformParameters() ); - - - // - // Perform Deformable Registration - // - DeformableTransformType::Pointer bsplineTransformCoarse = DeformableTransformType::New(); - - unsigned int numberOfGridNodesInOneDimensionCoarse = 5; - - DeformableTransformType::PhysicalDimensionsType fixedPhysicalDimensions; - DeformableTransformType::MeshSizeType meshSize; - DeformableTransformType::OriginType fixedOrigin; - - for( unsigned int i=0; i< SpaceDimension; i++ ) - { - fixedOrigin[i] = fixedImage->GetOrigin()[i]; - fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] * - static_cast( - fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 ); - } - meshSize.Fill( numberOfGridNodesInOneDimensionCoarse - SplineOrder ); - - bsplineTransformCoarse->SetTransformDomainOrigin( fixedOrigin ); - bsplineTransformCoarse->SetTransformDomainPhysicalDimensions( - fixedPhysicalDimensions ); - bsplineTransformCoarse->SetTransformDomainMeshSize( meshSize ); - bsplineTransformCoarse->SetTransformDomainDirection( - fixedImage->GetDirection() ); - - using ParametersType = DeformableTransformType::ParametersType; - - unsigned int numberOfBSplineParameters = bsplineTransformCoarse->GetNumberOfParameters(); - - - optimizerScales = OptimizerScalesType( numberOfBSplineParameters ); - optimizerScales.Fill( 1.0 ); - - optimizer->SetScales( optimizerScales ); - - - ParametersType initialDeformableTransformParameters( numberOfBSplineParameters ); - initialDeformableTransformParameters.Fill( 0.0 ); - - bsplineTransformCoarse->SetParameters( initialDeformableTransformParameters ); - - registration->SetInitialTransformParameters( bsplineTransformCoarse->GetParameters() ); - registration->SetTransform( bsplineTransformCoarse ); - - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Next we set the parameters of the RegularStepGradientDescentOptimizer object. - // - // Software Guide : EndLatex - - - // Software Guide : BeginCodeSnippet - optimizer->SetMaximumStepLength( 10.0 ); - optimizer->SetMinimumStepLength( 0.01 ); - - optimizer->SetRelaxationFactor( 0.7 ); - optimizer->SetNumberOfIterations( 50 ); - // Software Guide : EndCodeSnippet - - - // Optionally, get the step length from the command line arguments - if( argc > 11 ) - { - optimizer->SetMaximumStepLength( std::stod( argv[12] ) ); - } - - // Optionally, get the number of iterations from the command line arguments - if( argc > 12 ) - { - optimizer->SetNumberOfIterations( std::stoi( argv[13] ) ); - } - - - // - // The BSpline transform has a large number of parameters, we use therefore a - // much larger number of samples to run this stage. - // - // Regulating the number of samples in the Metric is equivalent to performing - // multi-resolution registration because it is indeed a sub-sampling of the - // image. - metric->SetNumberOfSpatialSamples( numberOfBSplineParameters * 100 ); - - std::cout << std::endl << "Starting Deformable Registration Coarse Grid" << std::endl; - - try - { - memorymeter.Start( "Deformable Registration Coarse" ); - chronometer.Start( "Deformable Registration Coarse" ); - - registration->Update(); - - chronometer.Stop( "Deformable Registration Coarse" ); - memorymeter.Stop( "Deformable Registration Coarse" ); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - std::cout << "Deformable Registration Coarse Grid completed" << std::endl; - std::cout << std::endl; - - OptimizerType::ParametersType finalParameters = - registration->GetLastTransformParameters(); - - bsplineTransformCoarse->SetParameters( finalParameters ); - - // Software Guide : BeginLatex - // - // Once the registration has finished with the low resolution grid, we - // proceed to instantiate a higher resolution - // \code{BSplineTransform}. - // - // Software Guide : EndLatex - - DeformableTransformType::Pointer bsplineTransformFine = DeformableTransformType::New(); - - unsigned int numberOfGridNodesInOneDimensionFine = 5; - - meshSize.Fill( numberOfGridNodesInOneDimensionFine - SplineOrder ); - - bsplineTransformFine->SetTransformDomainOrigin( fixedOrigin ); - bsplineTransformFine->SetTransformDomainPhysicalDimensions( - fixedPhysicalDimensions ); - bsplineTransformFine->SetTransformDomainMeshSize( meshSize ); - bsplineTransformFine->SetTransformDomainDirection( - fixedImage->GetDirection() ); - - numberOfBSplineParameters = bsplineTransformFine->GetNumberOfParameters(); - - ParametersType parametersHigh( numberOfBSplineParameters ); - parametersHigh.Fill( 0.0 ); - - // Software Guide : BeginLatex - // - // Now we need to initialize the BSpline coefficients of the higher resolution - // transform. This is done by first computing the actual deformation field - // at the higher resolution from the lower resolution BSpline coefficients. - // Then a BSpline decomposition is done to obtain the BSpline coefficient of - // the higher resolution transform. - // - // Software Guide : EndLatex - - unsigned int counter = 0; - - for ( unsigned int k = 0; k < SpaceDimension; k++ ) - { - using ParametersImageType = DeformableTransformType::ImageType; - using ResamplerType = itk::ResampleImageFilter; - ResamplerType::Pointer upsampler = ResamplerType::New(); - - using FunctionType = itk::BSplineResampleImageFunction; - FunctionType::Pointer function = FunctionType::New(); - - upsampler->SetInput( bsplineTransformCoarse->GetCoefficientImages()[k] ); - upsampler->SetInterpolator( function ); - upsampler->SetTransform( identityTransform ); - upsampler->SetSize( bsplineTransformFine->GetCoefficientImages()[k]-> - GetLargestPossibleRegion().GetSize() ); - upsampler->SetOutputSpacing( bsplineTransformFine->GetCoefficientImages()[k]-> - GetSpacing() ); - upsampler->SetOutputOrigin( bsplineTransformFine->GetCoefficientImages()[k]-> - GetOrigin() ); - - using DecompositionType = - itk::BSplineDecompositionImageFilter; - DecompositionType::Pointer decomposition = DecompositionType::New(); - - decomposition->SetSplineOrder( SplineOrder ); - decomposition->SetInput( upsampler->GetOutput() ); - decomposition->Update(); - - ParametersImageType::Pointer newCoefficients = decomposition->GetOutput(); - - // copy the coefficients into the parameter array - using Iterator = itk::ImageRegionIterator; - Iterator it( newCoefficients, bsplineTransformFine->GetCoefficientImages()[k]-> - GetLargestPossibleRegion() ); - while ( !it.IsAtEnd() ) - { - parametersHigh[ counter++ ] = it.Get(); - ++it; - } - - } - - - optimizerScales = OptimizerScalesType( numberOfBSplineParameters ); - optimizerScales.Fill( 1.0 ); - - optimizer->SetScales( optimizerScales ); - - bsplineTransformFine->SetParameters( parametersHigh ); - - // Software Guide : BeginLatex - // - // We now pass the parameters of the high resolution transform as the initial - // parameters to be used in a second stage of the registration process. - // - // Software Guide : EndLatex - - std::cout << "Starting Registration with high resolution transform" << std::endl; - - // Software Guide : BeginCodeSnippet - registration->SetInitialTransformParameters( - bsplineTransformFine->GetParameters() ); - registration->SetTransform( bsplineTransformFine ); - // - // The BSpline transform at fine scale has a very large number of parameters, - // we use therefore a much larger number of samples to run this stage. In - // this case, however, the number of transform parameters is closer to the - // number of pixels in the image. Therefore we use the geometric mean of the - // two numbers to ensure that the number of samples is larger than the number - // of transform parameters and smaller than the number of samples. - // - // Regulating the number of samples in the Metric is equivalent to performing - // multi-resolution registration because it is indeed a sub-sampling of the - // image. - const unsigned long numberOfSamples = - static_cast( - std::sqrt( static_cast( numberOfBSplineParameters ) * - static_cast( numberOfPixels ) ) ); - metric->SetNumberOfSpatialSamples( numberOfSamples ); - - try - { - memorymeter.Start( "Deformable Registration Fine" ); - chronometer.Start( "Deformable Registration Fine" ); - registration->Update(); - chronometer.Stop( "Deformable Registration Fine" ); - memorymeter.Stop( "Deformable Registration Fine" ); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - // Software Guide : EndCodeSnippet - - std::cout << "Deformable Registration Fine Grid completed" << std::endl; - std::cout << std::endl; - - - // Report the time and memory taken by the registration - chronometer.Report( std::cout ); - memorymeter.Report( std::cout ); - - finalParameters = registration->GetLastTransformParameters(); - - bsplineTransformFine->SetParameters( finalParameters ); - - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( bsplineTransformFine ); - resample->SetInput( movingImageReader->GetOutput() ); - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - - // This value is set to zero in order to make easier to perform - // regression testing in this example. However, for didactic - // exercise it will be better to set it to a medium gray value - // such as 100 or 128. - resample->SetDefaultPixelValue( 0 ); - - using OutputPixelType = signed short; - - using OutputImageType = itk::Image< OutputPixelType, ImageDimension >; - - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - - writer->SetFileName( argv[3] ); - - - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - - std::cout << "Writing resampled moving image..."; - - try - { - writer->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - std::cout << " Done!" << std::endl; - - - using DifferenceFilterType = itk::SquaredDifferenceImageFilter< - FixedImageType, - FixedImageType, - OutputImageType >; - - DifferenceFilterType::Pointer difference = DifferenceFilterType::New(); - - WriterType::Pointer writer2 = WriterType::New(); - writer2->SetInput( difference->GetOutput() ); - - - // Compute the difference image between the - // fixed and resampled moving image. - if( argc > 4 ) - { - difference->SetInput1( fixedImageReader->GetOutput() ); - difference->SetInput2( resample->GetOutput() ); - writer2->SetFileName( argv[4] ); - - std::cout << "Writing difference image after registration..."; - - try - { - writer2->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - std::cout << " Done!" << std::endl; - } - - - // Compute the difference image between the - // fixed and moving image before registration. - if( argc > 5 ) - { - writer2->SetFileName( argv[5] ); - difference->SetInput1( fixedImageReader->GetOutput() ); - resample->SetTransform( identityTransform ); - - std::cout << "Writing difference image before registration..."; - - try - { - writer2->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - std::cout << " Done!" << std::endl; - } - - // Generate the explicit deformation field resulting from - // the registration. - if( argc > 6 ) - { - - using VectorType = itk::Vector< float, ImageDimension >; - using DisplacementFieldType = itk::Image< VectorType, ImageDimension >; - - DisplacementFieldType::Pointer field = DisplacementFieldType::New(); - field->SetRegions( fixedRegion ); - field->SetOrigin( fixedImage->GetOrigin() ); - field->SetSpacing( fixedImage->GetSpacing() ); - field->SetDirection( fixedImage->GetDirection() ); - field->Allocate(); - - using FieldIterator = itk::ImageRegionIterator< DisplacementFieldType >; - FieldIterator fi( field, fixedRegion ); - - fi.GoToBegin(); - - DeformableTransformType::InputPointType fixedPoint; - DeformableTransformType::OutputPointType movingPoint; - DisplacementFieldType::IndexType index; - - VectorType displacement; - - while( ! fi.IsAtEnd() ) - { - index = fi.GetIndex(); - field->TransformIndexToPhysicalPoint( index, fixedPoint ); - movingPoint = bsplineTransformFine->TransformPoint( fixedPoint ); - displacement = movingPoint - fixedPoint; - fi.Set( displacement ); - ++fi; - } - - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - - fieldWriter->SetInput( field ); - - fieldWriter->SetFileName( argv[6] ); - - std::cout << "Writing deformation field ..."; - - try - { - fieldWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - std::cout << " Done!" << std::endl; - } - - // Optionally, save the transform parameters in a file - if( argc > 9 ) - { - std::cout << "Writing transform parameter file ..."; - std::ofstream parametersFile; - parametersFile.open( argv[9] ); - parametersFile << finalParameters << std::endl; - parametersFile.close(); - std::cout << " Done!" << std::endl; - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration16.cxx b/Examples/RegistrationITKv3/DeformableRegistration16.cxx deleted file mode 100644 index 5b002a3ad7c..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration16.cxx +++ /dev/null @@ -1,339 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ -/******************************************************************************* - - Abstract: - Multiresolution demons registration - 4 multiresolution levels - Created: June 25 2008 - Last Revision 7/9/2008 - by Vidya Rajagopalan on 7/9/2008 - - Copyright (c) 2008, Bioimaging Systems Lab, Virginia Tech - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Virgina Tech nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGE. -*******************************************************************************/ -// Software Guide : BeginLatex -// -// This example illustrates the use of the -// \doxygen{MultiResolutionPDEDeformableRegistration} class for performing -// deformable registration of two $2D$ images using multiple resolution levels. -// -// The MultiResolution filter drives a DemonsRegistrationFilter -// at every level of resolution in the pyramid. -// -// \index{itk::MultiResolutionPDEDeformableRegistration} -// \index{itk::DemonsRegistrationFilter} -// -// Software Guide : EndLatex - -// -// CREDITS: -// -// This example was contributed to ITK by -// -// Vidya Rajagopalan, Bioimaging Systems Lab, Virginia Tech -// -// The example was improved during the NAMIC programming week on July 2008 -// http://wiki.na-mic.org/Wiki/index.php/2008_Summer_Project_Week -// -// National Alliance for Medical Image Computing (NAMIC), -// funded by the National Institutes of Health -// through the NIH Roadmap for Medical Research, -// Grant U54 EB005149. -// -// Data for these examples have been contributed by -// -// Paul Laurienti, Wake Forest University School of Medicine, -// Data acquired under NIH grant number NS042568 -// -// - -#include -#include - -// ITK IO includes -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -// ITK Registration includes -#include "itkMultiResolutionPDEDeformableRegistration.h" -#include "itkMultiResolutionImageRegistrationMethod.h" -#include "itkHistogramMatchingImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkWarpImageFilter.h" - -unsigned int RmsCounter = 0; -double MaxRmsE[4] = {0.8, 0.75, 0.4, 0.2}; - -// -// The following section of code implements a Command observer -// that will monitor the evolution of the registration process. -// This observer has a layer of intelligence, for deciding what -// MaximumRMS convergence criteria to use at every resolution level. -// -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - - // define ITK short-hand types - using PixelType = short; - using InternalPixelType = float; - using ImageType = itk::Image< PixelType, 2 >; - using InternalImageType = itk::Image< InternalPixelType, 2 >; - using VectorPixelType = itk::Vector< float, 2 >; - using DisplacementFieldType = itk::Image< VectorPixelType, 2 >; - using RegistrationFilterType = itk::DemonsRegistrationFilter< InternalImageType, - InternalImageType, DisplacementFieldType>; - -public: - - void Execute(const itk::Object *, const itk::EventObject & ) override - { - std::cout << "Warning: The const Execute method shouldn't be called" << std::endl; - } - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - RegistrationFilterType * filter = static_cast< RegistrationFilterType * >( caller ); - - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - if(filter) - { - filter->SetMaximumRMSError(MaxRmsE[RmsCounter]); - std::cout << filter->GetMetric() << " RMS Change: " << filter->GetRMSChange() << std::endl; - - std::cout << "Level Tolerance= "<GetMaximumRMSError ()<; - itkNewMacro( Self ); - -protected: - CommandResolutionLevelUpdate() {}; - -public: - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - void Execute(const itk::Object *, const itk::EventObject & ) override - { - std::cout << "----------------------------------" << std::endl; - RmsCounter = RmsCounter + 1; - std::cout << "----------------------------------" << std::endl; - } -}; - - -int main( int argc, char * argv [] ) -{ - - // Verify the number of parameters in the command line - if( argc != 5 ) - { - std::cerr << "usage: " << std::endl; - std::cerr << argv[0] << " fixedImage movingImage registeredImage deformationField" << std::endl; - return EXIT_FAILURE; - } - - // define ITK short-hand types - constexpr unsigned int Dimension = 2; - using PixelType = short; - using InternalPixelType = float; - using ImageType = itk::Image< PixelType, Dimension >; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - using ImageCasterType = itk::CastImageFilter< ImageType, InternalImageType >; - - - // setup input file readers - using ReaderType = itk::ImageFileReader< ImageType >; - ReaderType::Pointer targetReader = ReaderType::New(); - targetReader->SetFileName( argv[1] ); - targetReader->Update(); - - ReaderType::Pointer sourceReader = ReaderType::New(); - sourceReader->SetFileName( argv[2] ); - sourceReader->Update(); - - - // cast target and source to float - ImageCasterType::Pointer targetImageCaster = ImageCasterType::New(); - ImageCasterType::Pointer sourceImageCaster = ImageCasterType::New(); - targetImageCaster->SetInput( targetReader->GetOutput() ); - sourceImageCaster->SetInput( sourceReader->GetOutput() ); - - // match the histograms between source and target - using MatchingFilterType = itk::HistogramMatchingImageFilter< - InternalImageType, InternalImageType >; - - MatchingFilterType::Pointer matcher = MatchingFilterType::New(); - - matcher->SetInput( sourceImageCaster->GetOutput() ); - matcher->SetReferenceImage( targetImageCaster->GetOutput() ); - matcher->SetNumberOfHistogramLevels( 1024 ); - matcher->SetNumberOfMatchPoints( 7 ); - matcher->ThresholdAtMeanIntensityOn(); - - // setup the deformation field and filter - using VectorPixelType = itk::Vector< float, Dimension >; - - using DisplacementFieldType = itk::Image< VectorPixelType, Dimension >; - - using RegistrationFilterType = itk::DemonsRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType>; - - RegistrationFilterType::Pointer filter = RegistrationFilterType::New(); - - filter->SetStandardDeviations( 1.0 ); - - // - // Create the Command observer and register it with the registration filter. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - filter->AddObserver( itk::IterationEvent(), observer ); - - - // use multiresolution scheme - using MultiResRegistrationFilterType = itk::MultiResolutionPDEDeformableRegistration< - InternalImageType, - InternalImageType, - DisplacementFieldType >; - - MultiResRegistrationFilterType::Pointer multires = - MultiResRegistrationFilterType::New(); - - multires->SetRegistrationFilter( filter ); - multires->SetNumberOfLevels( 4 ); - multires->SetFixedImage( targetImageCaster->GetOutput() ); - multires->SetMovingImage( matcher->GetOutput() ); - unsigned int nIterations[4] = {40, 40, 32, 32 }; - multires->SetNumberOfIterations( nIterations ); - - // - // Create the Command observer and register it with the registration filter. - // - CommandResolutionLevelUpdate::Pointer levelobserver = CommandResolutionLevelUpdate::New(); - multires->AddObserver( itk::IterationEvent(), levelobserver ); - - // apply the registration filter - try - { - multires->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - // compute the output (warped) image - using WarperType = itk::WarpImageFilter< ImageType, ImageType, DisplacementFieldType >; - using InterpolatorType = itk::LinearInterpolateImageFunction< ImageType, double >; - - WarperType::Pointer warper = WarperType::New(); - - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - - ImageType::Pointer targetImage = targetReader->GetOutput(); - warper->SetInput( sourceReader->GetOutput() ); - warper->SetInterpolator( interpolator ); - warper->SetOutputSpacing( targetImage->GetSpacing() ); - warper->SetOutputOrigin( targetImage->GetOrigin() ); - warper->SetOutputDirection( targetImage->GetDirection() ); - warper->SetDisplacementField( multires->GetOutput() ); - - using WriterType = itk::ImageFileWriter< ImageType >; - WriterType::Pointer writer = WriterType::New(); - writer->SetFileName( argv[3] ); - writer->SetInput( warper->GetOutput() ); - - try - { - writer->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - // write the deformation field - using DeformationWriterType = itk::ImageFileWriter< DisplacementFieldType >; - DeformationWriterType::Pointer defwriter = DeformationWriterType::New(); - defwriter->SetFileName( argv[4] ); - defwriter->SetInput( multires->GetOutput() ); - - try - { - defwriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration17.cxx b/Examples/RegistrationITKv3/DeformableRegistration17.cxx deleted file mode 100644 index 4b134ffc90b..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration17.cxx +++ /dev/null @@ -1,340 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ -/******************************************************************************* - - Abstract: - Multiresolution symmetric forces demons registration - 4 multiresolution levels - Created: July 8 2008 - Last Revision 7/9/2008 - by Vidya Rajagopalan on 7/9/2008 - - Copyright (c) 2008, Bioimaging Systems Lab, Virginia Tech - All rights reserved. - - Redistribution and use in source and binary forms, with or without modification, - are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - * Neither the name of Virgina Tech nor the names of its contributors may - be used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGE. -*******************************************************************************/ -// Software Guide : BeginLatex -// -// This example illustrates the use of the -// \doxygen{MultiResolutionPDEDeformableRegistration} class for performing -// deformable registration of two $2D$ images using multiple resolution levels. -// -// The MultiResolution filter drives a SymmetricForcesDemonsRegistrationFilter -// at every level of resolution in the pyramid. -// -// \index{itk::MultiResolutionPDEDeformableRegistration} -// \index{itk::SymmetricForcesDemonsRegistrationFilter} -// -// Software Guide : EndLatex - -// -// CREDITS: -// -// This example was contributed to ITK by -// -// Vidya Rajagopalan, Bioimaging Systems Lab, Virginia Tech -// -// The example was improved during the NAMIC programming week on July 2008 -// http://wiki.na-mic.org/Wiki/index.php/2008_Summer_Project_Week -// -// National Alliance for Medical Image Computing (NAMIC), -// funded by the National Institutes of Health -// through the NIH Roadmap for Medical Research, -// Grant U54 EB005149. -// -// Data for these examples have been contributed by -// -// Paul Laurienti, Wake Forest University School of Medicine, -// Data acquired under NIH grant number NS042568 -// -// - -#include -#include - -// ITK IO includes -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -// ITK Registration includes -#include "itkMultiResolutionPDEDeformableRegistration.h" -#include "itkMultiResolutionImageRegistrationMethod.h" -#include "itkSymmetricForcesDemonsRegistrationFilter.h" -#include "itkHistogramMatchingImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkWarpImageFilter.h" - -unsigned int RmsCounter = 0; -double MaxRmsE[4] = {0.8, 0.75, 0.4, 0.2}; - -// The following section of code implements a Command observer -// that will monitor the evolution of the registration process. -// This observer has a layer of intelligence, for deciding what -// MaximumRMS convergence criteria to use at every resolution level. -// - -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - - // define ITK short-hand types - using PixelType = short; - using InternalPixelType = float; - using ImageType = itk::Image< PixelType, 2 >; - using InternalImageType = itk::Image< InternalPixelType, 2 >; - using VectorPixelType = itk::Vector< float, 2 >; - using DisplacementFieldType = itk::Image< VectorPixelType, 2 >; - using RegistrationFilterType = itk::SymmetricForcesDemonsRegistrationFilter< InternalImageType, - InternalImageType, DisplacementFieldType>; - - public: - - void Execute(const itk::Object *, const itk::EventObject & ) override - { - std::cout << "Warning: The const Execute method shouldn't be called" << std::endl; - } - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - RegistrationFilterType * filter = static_cast< RegistrationFilterType * >( caller ); - - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - - if(filter) - { - filter->SetMaximumRMSError(MaxRmsE[RmsCounter]); - std::cout << filter->GetMetric() << " RMS Change: " << filter->GetRMSChange() << std::endl; - - std::cout << "Level Tolerance= "<GetMaximumRMSError ()<; - itkNewMacro( Self ); - -protected: - CommandResolutionLevelUpdate() {}; - -public: - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - void Execute(const itk::Object *, const itk::EventObject & ) override - { - std::cout << "----------------------------------" << std::endl; - RmsCounter = RmsCounter + 1; - std::cout << "----------------------------------" << std::endl; - } -}; - - -int main( int argc, char * argv [] ) -{ - - // Verify the number of parameters in the command line - if( argc != 5 ) - { - std::cerr << "usage: " << std::endl; - std::cerr << argv[0] << " fixedImage movingImage registeredImage deformationField" << std::endl; - return EXIT_FAILURE; - } - - // define ITK short-hand types - constexpr unsigned int Dimension = 2; - using PixelType = short; - using InternalPixelType = float; - using ImageType = itk::Image< PixelType, Dimension >; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - using ImageCasterType = itk::CastImageFilter< ImageType, InternalImageType >; - - // setup input file readers - using ReaderType = itk::ImageFileReader< ImageType >; - ReaderType::Pointer targetReader = ReaderType::New(); - targetReader->SetFileName( argv[1] ); - targetReader->Update(); - - ReaderType::Pointer sourceReader = ReaderType::New(); - sourceReader->SetFileName( argv[2] ); - sourceReader->Update(); - - // cast target and source to float - ImageCasterType::Pointer targetImageCaster = ImageCasterType::New(); - ImageCasterType::Pointer sourceImageCaster = ImageCasterType::New(); - targetImageCaster->SetInput( targetReader->GetOutput() ); - sourceImageCaster->SetInput( sourceReader->GetOutput() ); - - // match the histograms between source and target - using MatchingFilterType = itk::HistogramMatchingImageFilter< - InternalImageType, InternalImageType >; - - MatchingFilterType::Pointer matcher = MatchingFilterType::New(); - - matcher->SetInput( sourceImageCaster->GetOutput() ); - matcher->SetReferenceImage( targetImageCaster->GetOutput() ); - matcher->SetNumberOfHistogramLevels( 1024 ); - matcher->SetNumberOfMatchPoints( 7 ); - matcher->ThresholdAtMeanIntensityOn(); - - // setup the deformation field and filter - using VectorPixelType = itk::Vector< float, Dimension >; - - using DisplacementFieldType = itk::Image< VectorPixelType, Dimension >; - - using RegistrationFilterType = itk::SymmetricForcesDemonsRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType>; - - RegistrationFilterType::Pointer filter = RegistrationFilterType::New(); - - filter->SetStandardDeviations( 1.0 ); - - // - // Create the Command observer and register it with the registration filter. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - filter->AddObserver( itk::IterationEvent(), observer ); - - - // use multiresolution scheme - using MultiResRegistrationFilterType = itk::MultiResolutionPDEDeformableRegistration< - InternalImageType, - InternalImageType, - DisplacementFieldType >; - - MultiResRegistrationFilterType::Pointer multires = - MultiResRegistrationFilterType::New(); - - multires->SetRegistrationFilter( filter ); - multires->SetNumberOfLevels( 4 ); - multires->SetFixedImage( targetImageCaster->GetOutput() ); - multires->SetMovingImage( matcher->GetOutput() ); - unsigned int nIterations[4] = {40, 40, 32, 32 }; - multires->SetNumberOfIterations( nIterations ); - - // - // Create the Command observer and register it with the registration filter. - // - CommandResolutionLevelUpdate::Pointer levelobserver = CommandResolutionLevelUpdate::New(); - multires->AddObserver( itk::IterationEvent(), levelobserver ); - - // apply the registration filter - try - { - multires->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - // compute the output (warped) image - using WarperType = itk::WarpImageFilter< ImageType, ImageType, DisplacementFieldType >; - using InterpolatorType = itk::LinearInterpolateImageFunction< ImageType, double >; - - WarperType::Pointer warper = WarperType::New(); - - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - - ImageType::Pointer targetImage = targetReader->GetOutput(); - warper->SetInput( sourceReader->GetOutput() ); - warper->SetInterpolator( interpolator ); - warper->SetOutputSpacing( targetImage->GetSpacing() ); - warper->SetOutputOrigin( targetImage->GetOrigin() ); - warper->SetOutputDirection( targetImage->GetDirection() ); - warper->SetDisplacementField( multires->GetOutput() ); - - using WriterType = itk::ImageFileWriter< ImageType >; - WriterType::Pointer writer = WriterType::New(); - writer->SetFileName( argv[3] ); - writer->SetInput( warper->GetOutput() ); - - try - { - writer->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - // write the deformation field - using DeformationWriterType = itk::ImageFileWriter< DisplacementFieldType >; - DeformationWriterType::Pointer defwriter = DeformationWriterType::New(); - defwriter->SetFileName( argv[4] ); - defwriter->SetInput( multires->GetOutput() ); - - try - { - defwriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration2.cxx b/Examples/RegistrationITKv3/DeformableRegistration2.cxx deleted file mode 100644 index fdce3f7f0f2..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration2.cxx +++ /dev/null @@ -1,506 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginCommandLineArgs -// INPUTS: RatLungSlice1.mha -// INPUTS: RatLungSlice2.mha -// ARGUMENTS: DeformableRegistration2Output.mha -// ARGUMENTS: DeformableRegistration2Field.mha -// Software Guide : EndCommandLineArgs - - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkImageRegionIterator.h" - -// Software Guide : BeginLatex -// -// This example demonstrates how to use the ``demons'' algorithm to deformably -// register two images. The first step is to include the header files. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkDemonsRegistrationFilter.h" -#include "itkHistogramMatchingImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkWarpImageFilter.h" -// Software Guide : EndCodeSnippet - - -// The following section of code implements a Command observer -// that will monitor the evolution of the registration process. -// - class CommandIterationUpdate : public itk::Command - { - public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( CommandIterationUpdate ); - protected: - CommandIterationUpdate() {}; - - using InternalImageType = itk::Image< float, 2 >; - using VectorPixelType = itk::Vector< float, 2 >; - using DisplacementFieldType = itk::Image< VectorPixelType, 2 >; - - using RegistrationFilterType = itk::DemonsRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType>; - - public: - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - const RegistrationFilterType * filter = static_cast< const RegistrationFilterType * >( object ); - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - std::cout << filter->GetMetric() << std::endl; - } - }; - - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImageFile " << std::endl; - std::cerr << " [outputDisplacementFieldFile] " << std::endl; - return EXIT_FAILURE; - } - - // Software Guide : BeginLatex - // - // Second, we declare the types of the images. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - constexpr unsigned int Dimension = 2; - using PixelType = unsigned short; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : EndCodeSnippet - - // Set up the file readers - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - - // Software Guide : BeginLatex - // - // Image file readers are set up in a similar fashion to previous examples. - // To support the re-mapping of the moving image intensity, we declare an - // internal image type with a floating point pixel type and cast the input - // images to the internal image type. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using InternalPixelType = float; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - using FixedImageCasterType = itk::CastImageFilter< FixedImageType, - InternalImageType >; - using MovingImageCasterType = itk::CastImageFilter< MovingImageType, - InternalImageType >; - - FixedImageCasterType::Pointer fixedImageCaster = FixedImageCasterType::New(); - MovingImageCasterType::Pointer movingImageCaster - = MovingImageCasterType::New(); - - fixedImageCaster->SetInput( fixedImageReader->GetOutput() ); - movingImageCaster->SetInput( movingImageReader->GetOutput() ); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The demons algorithm relies on the assumption that pixels representing the - // same homologous point on an object have the same intensity on both the - // fixed and moving images to be registered. In this example, we will - // preprocess the moving image to match the intensity between the images - // using the \doxygen{HistogramMatchingImageFilter}. - // - // \index{itk::HistogramMatchingImageFilter} - // - // The basic idea is to match the histograms of the two images at a - // user-specified number of quantile values. For robustness, the histograms - // are matched so that the background pixels are excluded from both - // histograms. For MR images, a simple procedure is to exclude all gray - // values that are smaller than the mean gray value of the image. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using MatchingFilterType = itk::HistogramMatchingImageFilter< - InternalImageType, - InternalImageType >; - MatchingFilterType::Pointer matcher = MatchingFilterType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // For this example, we set the moving image as the source or input image and - // the fixed image as the reference image. - // - // \index{itk::HistogramMatchingImageFilter!SetInput()} - // \index{itk::HistogramMatchingImageFilter!SetSourceImage()} - // \index{itk::HistogramMatchingImageFilter!SetReferenceImage()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - matcher->SetInput( movingImageCaster->GetOutput() ); - matcher->SetReferenceImage( fixedImageCaster->GetOutput() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // We then select the number of bins to represent the histograms and the - // number of points or quantile values where the histogram is to be - // matched. - // - // \index{itk::HistogramMatchingImageFilter!SetNumberOfHistogramLevels()} - // \index{itk::HistogramMatchingImageFilter!SetNumberOfMatchPoints()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - matcher->SetNumberOfHistogramLevels( 1024 ); - matcher->SetNumberOfMatchPoints( 7 ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Simple background extraction is done by thresholding at the mean - // intensity. - // - // \index{itk::HistogramMatchingImageFilter!ThresholdAtMeanIntensityOn()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - matcher->ThresholdAtMeanIntensityOn(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // In the \doxygen{DemonsRegistrationFilter}, the deformation field is - // represented as an image whose pixels are floating point vectors. - // - // \index{itk::DemonsRegistrationFilter} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using VectorPixelType = itk::Vector< float, Dimension >; - using DisplacementFieldType = itk::Image< VectorPixelType, Dimension >; - using RegistrationFilterType = itk::DemonsRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType>; - RegistrationFilterType::Pointer filter = RegistrationFilterType::New(); - // Software Guide : EndCodeSnippet - - - // Create the Command observer and register it with the registration filter. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - filter->AddObserver( itk::IterationEvent(), observer ); - - - // Software Guide : BeginLatex - // - // The input fixed image is simply the output of the fixed image casting - // filter. The input moving image is the output of the histogram matching - // filter. - // - // \index{itk::DemonsRegistrationFilter!SetFixedImage()} - // \index{itk::DemonsRegistrationFilter!SetMovingImage()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->SetFixedImage( fixedImageCaster->GetOutput() ); - filter->SetMovingImage( matcher->GetOutput() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The demons registration filter has two parameters: the number of - // iterations to be performed and the standard deviation of the Gaussian - // smoothing kernel to be applied to the deformation field after each - // iteration. - // \index{itk::DemonsRegistrationFilter!SetNumberOfIterations()} - // \index{itk::DemonsRegistrationFilter!SetStandardDeviations()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->SetNumberOfIterations( 50 ); - filter->SetStandardDeviations( 1.0 ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The registration algorithm is triggered by updating the filter. The - // filter output is the computed deformation field. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->Update(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The \doxygen{WarpImageFilter} can be used to warp the moving image with - // the output deformation field. Like the \doxygen{ResampleImageFilter}, - // the WarpImageFilter requires the specification of the input image to be - // resampled, an input image interpolator, and the output image spacing and - // origin. - // - // \index{itk::WarpImageFilter} - // \index{itk::WarpImageFilter!SetInput()} - // \index{itk::WarpImageFilter!SetInterpolator()} - // \index{itk::WarpImageFilter!SetOutputSpacing()} - // \index{itk::WarpImageFilter!SetOutputOrigin()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using WarperType = itk::WarpImageFilter< - MovingImageType, - MovingImageType, - DisplacementFieldType >; - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, - double >; - WarperType::Pointer warper = WarperType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - warper->SetInput( movingImageReader->GetOutput() ); - warper->SetInterpolator( interpolator ); - warper->SetOutputSpacing( fixedImage->GetSpacing() ); - warper->SetOutputOrigin( fixedImage->GetOrigin() ); - warper->SetOutputDirection( fixedImage->GetDirection() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Unlike the ResampleImageFilter, the WarpImageFilter - // warps or transform the input image with respect to the deformation field - // represented by an image of vectors. The resulting warped or resampled - // image is written to file as per previous examples. - // - // \index{itk::WarpImageFilter!SetDisplacementField()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - warper->SetDisplacementField( filter->GetOutput() ); - // Software Guide : EndCodeSnippet - - - // Write warped image out to file - using OutputPixelType = unsigned char; - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - using CastFilterType = itk::CastImageFilter< - MovingImageType, - OutputImageType >; - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - writer->SetFileName( argv[3] ); - - caster->SetInput( warper->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - - // Software Guide : BeginLatex - // - // Let's execute this example using the rat lung data from the previous example. - // The associated data files can be found in \code{Examples/Data}: - // - // \begin{itemize} - // \item \code{RatLungSlice1.mha} - // \item \code{RatLungSlice2.mha} - // \end{itemize} - // - // \begin{figure} \center - // \includegraphics[width=0.44\textwidth]{DeformableRegistration2CheckerboardBefore} - // \includegraphics[width=0.44\textwidth]{DeformableRegistration2CheckerboardAfter} - // \itkcaption[Demon's deformable registration output]{Checkerboard comparisons - // before and after demons-based deformable registration.} - // \label{fig:DeformableRegistration2Output} - // \end{figure} - // - // The result of the demons-based deformable registration is presented in - // Figure \ref{fig:DeformableRegistration2Output}. The checkerboard - // comparison shows that the algorithm was able to recover the misalignment - // due to expiration. - // - // Software Guide : EndLatex - - - // Software Guide : BeginLatex - // - // It may be also desirable to write the deformation field as an image of - // vectors. This can be done with the following code. - // - // Software Guide : EndLatex - - if( argc > 4 ) // if a fourth line argument has been provided... - { - - // Software Guide : BeginCodeSnippet - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - fieldWriter->SetFileName( argv[4] ); - fieldWriter->SetInput( filter->GetOutput() ); - - fieldWriter->Update(); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Note that the file format used for writing the deformation field must be - // capable of representing multiple components per pixel. This is the case - // for the MetaImage and VTK file formats for example. - // - // Software Guide : EndLatex - - } - - - if( argc > 5 ) // if a fifth line argument has been provided... - { - - using VectorImage2DType = DisplacementFieldType; - using Vector2DType = DisplacementFieldType::PixelType; - - VectorImage2DType::ConstPointer vectorImage2D = filter->GetOutput(); - - VectorImage2DType::RegionType region2D = vectorImage2D->GetBufferedRegion(); - VectorImage2DType::IndexType index2D = region2D.GetIndex(); - VectorImage2DType::SizeType size2D = region2D.GetSize(); - - - using Vector3DType = itk::Vector< float, 3 >; - using VectorImage3DType = itk::Image< Vector3DType, 3 >; - - using VectorImage3DWriterType = itk::ImageFileWriter< VectorImage3DType >; - - VectorImage3DWriterType::Pointer writer3D = VectorImage3DWriterType::New(); - - VectorImage3DType::Pointer vectorImage3D = VectorImage3DType::New(); - - VectorImage3DType::RegionType region3D; - VectorImage3DType::IndexType index3D; - VectorImage3DType::SizeType size3D; - - index3D[0] = index2D[0]; - index3D[1] = index2D[1]; - index3D[2] = 0; - - size3D[0] = size2D[0]; - size3D[1] = size2D[1]; - size3D[2] = 1; - - region3D.SetSize( size3D ); - region3D.SetIndex( index3D ); - - vectorImage3D->SetRegions( region3D ); - vectorImage3D->Allocate(); - - using Iterator2DType = itk::ImageRegionConstIterator< VectorImage2DType >; - - using Iterator3DType = itk::ImageRegionIterator< VectorImage3DType >; - - Iterator2DType it2( vectorImage2D, region2D ); - Iterator3DType it3( vectorImage3D, region3D ); - - it2.GoToBegin(); - it3.GoToBegin(); - - Vector2DType vector2D; - Vector3DType vector3D; - - vector3D[2] = 0; // set Z component to zero. - - while( !it2.IsAtEnd() ) - { - vector2D = it2.Get(); - vector3D[0] = vector2D[0]; - vector3D[1] = vector2D[1]; - it3.Set( vector3D ); - ++it2; - ++it3; - } - - - writer3D->SetInput( vectorImage3D ); - - writer3D->SetFileName( argv[5] ); - - try - { - writer3D->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration3.cxx b/Examples/RegistrationITKv3/DeformableRegistration3.cxx deleted file mode 100644 index 2f70f84cfe2..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration3.cxx +++ /dev/null @@ -1,418 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - - -// Software Guide : BeginLatex -// -// This example demonstrates how to use a variant of the ``demons'' algorithm to -// deformably register two images. This variant uses a different formulation -// for computing the forces to be applied to the image in order to compute the -// deformation fields. The variant uses both the gradient of the fixed image -// and the gradient of the deformed moving image in order to compute the -// forces. This mechanism for computing the forces introduces a symmetry with -// respect to the choice of the fixed and moving images. This symmetry only -// holds during the computation of one iteration of the PDE updates. It is -// unlikely that total symmetry may be achieved by this mechanism for the -// entire registration process. -// -// The first step for using this filter is to include the following header files. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkSymmetricForcesDemonsRegistrationFilter.h" -#include "itkHistogramMatchingImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkWarpImageFilter.h" -// Software Guide : EndCodeSnippet - -// The following section of code implements a Command observer -// that will monitor the evolution of the registration process. -// - class CommandIterationUpdate : public itk::Command - { - public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( CommandIterationUpdate ); - protected: - CommandIterationUpdate() {}; - - using InternalImageType = itk::Image< float, 2 >; - using VectorPixelType = itk::Vector< float, 2 >; - using DisplacementFieldType = itk::Image< VectorPixelType, 2 >; - - using RegistrationFilterType = itk::SymmetricForcesDemonsRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType>; - - public: - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - const RegistrationFilterType * filter = static_cast< const RegistrationFilterType * >( object ); - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - std::cout << filter->GetMetric() << std::endl; - } - }; - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImageFile " << std::endl; - return EXIT_FAILURE; - } - - // Software Guide : BeginLatex - // - // Second, we declare the types of the images. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - constexpr unsigned int Dimension = 2; - using PixelType = unsigned short; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : EndCodeSnippet - - // Set up the file readers - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - - // Software Guide : BeginLatex - // - // Image file readers are set up in a similar fashion to previous examples. - // To support the re-mapping of the moving image intensity, we declare an - // internal image type with a floating point pixel type and cast the input - // images to the internal image type. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using InternalPixelType = float; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - using FixedImageCasterType = itk::CastImageFilter< FixedImageType, - InternalImageType >; - using MovingImageCasterType = itk::CastImageFilter< MovingImageType, - InternalImageType >; - - FixedImageCasterType::Pointer fixedImageCaster = FixedImageCasterType::New(); - MovingImageCasterType::Pointer movingImageCaster - = MovingImageCasterType::New(); - - fixedImageCaster->SetInput( fixedImageReader->GetOutput() ); - movingImageCaster->SetInput( movingImageReader->GetOutput() ); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The demons algorithm relies on the assumption that pixels representing the - // same homologous point on an object have the same intensity on both the - // fixed and moving images to be registered. In this example, we will - // preprocess the moving image to match the intensity between the images - // using the \doxygen{HistogramMatchingImageFilter}. - // - // \index{itk::Histogram\-Matching\-Image\-Filter} - // - // The basic idea is to match the histograms of the two images at a user-specified number of quantile values. For robustness, the histograms are - // matched so that the background pixels are excluded from both histograms. - // For MR images, a simple procedure is to exclude all gray values that are - // smaller than the mean gray value of the image. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using MatchingFilterType = itk::HistogramMatchingImageFilter< - InternalImageType, - InternalImageType >; - MatchingFilterType::Pointer matcher = MatchingFilterType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // For this example, we set the moving image as the source or input image and - // the fixed image as the reference image. - // - // \index{itk::Histogram\-Matching\-Image\-Filter!SetInput()} - // \index{itk::Histogram\-Matching\-Image\-Filter!SetSourceImage()} - // \index{itk::Histogram\-Matching\-Image\-Filter!SetReferenceImage()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - matcher->SetInput( movingImageCaster->GetOutput() ); - matcher->SetReferenceImage( fixedImageCaster->GetOutput() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // We then select the number of bins to represent the histograms and the - // number of points or quantile values where the histogram is to be - // matched. - // - // \index{itk::Histogram\-Matching\-Image\-Filter!Set\-Number\-Of\-Histogram\-Levels()} - // \index{itk::Histogram\-Matching\-Image\-Filter!Set\-Number\-Of\-Match\-Points()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - matcher->SetNumberOfHistogramLevels( 1024 ); - matcher->SetNumberOfMatchPoints( 7 ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Simple background extraction is done by thresholding at the mean - // intensity. - // - // \index{itk::Histogram\-Matching\-Image\-Filter!Threshold\-At\-Mean\-Intensity\-On()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - matcher->ThresholdAtMeanIntensityOn(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // In the \doxygen{SymmetricForcesDemonsRegistrationFilter}, the deformation field is - // represented as an image whose pixels are floating point vectors. - // - // \index{itk::Symmetric\-Forces\-Demons\-Registration\-Filter} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using VectorPixelType = itk::Vector< float, Dimension >; - using DisplacementFieldType = itk::Image< VectorPixelType, Dimension >; - using RegistrationFilterType = itk::SymmetricForcesDemonsRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType>; - RegistrationFilterType::Pointer filter = RegistrationFilterType::New(); - // Software Guide : EndCodeSnippet - - // Create the Command observer and register it with the registration filter. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - filter->AddObserver( itk::IterationEvent(), observer ); - - // Software Guide : BeginLatex - // - // The input fixed image is simply the output of the fixed image casting - // filter. The input moving image is the output of the histogram matching - // filter. - // - // \index{itk::Symmetric\-Forces\-Demons\-Registration\-Filter!SetFixedImage()} - // \index{itk::Symmetric\-Forces\-Demons\-Registration\-Filter!SetMovingImage()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->SetFixedImage( fixedImageCaster->GetOutput() ); - filter->SetMovingImage( matcher->GetOutput() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The demons registration filter has two parameters: the number of - // iterations to be performed and the standard deviation of the Gaussian - // smoothing kernel to be applied to the deformation field after each - // iteration. - // \index{itk::Symmetric\-Forces\-Demons\-Registration\-Filter!SetNumberOfIterations()} - // \index{itk::Symmetric\-Forces\-Demons\-Registration\-Filter!SetStandardDeviations()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->SetNumberOfIterations( 50 ); - filter->SetStandardDeviations( 1.0 ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The registration algorithm is triggered by updating the filter. The - // filter output is the computed deformation field. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->Update(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The \doxygen{WarpImageFilter} can be used to warp the moving image with - // the output deformation field. Like the \doxygen{ResampleImageFilter}, - // the WarpImageFilter requires the specification of the input image to be - // resampled, an input image interpolator, and the output image spacing and - // origin. - // - // \index{itk::WarpImageFilter} - // \index{itk::WarpImageFilter!SetInput()} - // \index{itk::WarpImageFilter!SetInterpolator()} - // \index{itk::WarpImageFilter!SetOutputSpacing()} - // \index{itk::WarpImageFilter!SetOutputOrigin()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using WarperType = itk::WarpImageFilter< - MovingImageType, - MovingImageType, - DisplacementFieldType >; - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, - double >; - WarperType::Pointer warper = WarperType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - warper->SetInput( movingImageReader->GetOutput() ); - warper->SetInterpolator( interpolator ); - warper->SetOutputSpacing( fixedImage->GetSpacing() ); - warper->SetOutputOrigin( fixedImage->GetOrigin() ); - warper->SetOutputDirection( fixedImage->GetDirection() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Unlike the ResampleImageFilter, the WarpImageFilter - // warps or transform the input image with respect to the deformation field - // represented by an image of vectors. The resulting warped or resampled - // image is written to file as per previous examples. - // - // \index{itk::WarpImageFilter!SetDisplacementField()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - warper->SetDisplacementField( filter->GetOutput() ); - // Software Guide : EndCodeSnippet - - - // Write warped image out to file - using OutputPixelType = unsigned char; - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - using CastFilterType = itk::CastImageFilter< - MovingImageType, - OutputImageType >; - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - writer->SetFileName( argv[3] ); - - caster->SetInput( warper->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - - // Software Guide : BeginLatex - // - // Let's execute this example using the rat lung data from the previous example. - // The associated data files can be found in \code{Examples/Data}: - // - // \begin{itemize} - // \item \code{RatLungSlice1.mha} - // \item \code{RatLungSlice2.mha} - // \end{itemize} - // - // \begin{figure} \center - // \includegraphics[width=0.44\textwidth]{DeformableRegistration2CheckerboardBefore} - // \includegraphics[width=0.44\textwidth]{DeformableRegistration2CheckerboardAfter} - // \itkcaption[Demon's deformable registration output]{Checkerboard comparisons - // before and after demons-based deformable registration.} - // \label{fig:DeformableRegistration3Output} - // \end{figure} - // - // The result of the demons-based deformable registration is presented in - // Figure \ref{fig:DeformableRegistration3Output}. The checkerboard - // comparison shows that the algorithm was able to recover the misalignment - // due to expiration. - // - // Software Guide : EndLatex - - - // Software Guide : BeginLatex - // - // It may be also desirable to write the deformation field as an image of - // vectors. This can be done with the following code. - // - // Software Guide : EndLatex - - if( argc > 4 ) // if a fourth line argument has been provided... - { - - // Software Guide : BeginCodeSnippet - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - fieldWriter->SetFileName( argv[4] ); - fieldWriter->SetInput( filter->GetOutput() ); - - fieldWriter->Update(); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Note that the file format used for writing the deformation field must be - // capable of representing multiple components per pixel. This is the case - // for the MetaImage and VTK file formats for example. - // - // Software Guide : EndLatex - - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration5.cxx b/Examples/RegistrationITKv3/DeformableRegistration5.cxx deleted file mode 100644 index 2745206e213..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration5.cxx +++ /dev/null @@ -1,503 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkImageRegionIterator.h" - -// Software Guide : BeginLatex -// -// This example demonstrates how to use the level set motion to deformably -// register two images. The first step is to include the header files. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkLevelSetMotionRegistrationFilter.h" -#include "itkHistogramMatchingImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkWarpImageFilter.h" -// Software Guide : EndCodeSnippet - -// The following section of code implements a Command observer -// that will monitor the evolution of the registration process. -// - class CommandIterationUpdate : public itk::Command - { - public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( CommandIterationUpdate ); - protected: - CommandIterationUpdate() {}; - - using InternalImageType = itk::Image< float, 2 >; - using VectorPixelType = itk::Vector< float, 2 >; - using DisplacementFieldType = itk::Image< VectorPixelType, 2 >; - - using RegistrationFilterType = itk::LevelSetMotionRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType>; - - public: - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - const RegistrationFilterType * filter = static_cast< const RegistrationFilterType * >( object ); - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - std::cout << filter->GetMetric() << std::endl; - } - }; - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImageFile " << std::endl; - std::cerr << " [outputDisplacementFieldFile] " << std::endl; - return EXIT_FAILURE; - } - - // Software Guide : BeginLatex - // - // Second, we declare the types of the images. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - constexpr unsigned int Dimension = 2; - using PixelType = unsigned short; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : EndCodeSnippet - - // Set up the file readers - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - - // Software Guide : BeginLatex - // - // Image file readers are set up in a similar fashion to previous examples. - // To support the re-mapping of the moving image intensity, we declare an - // internal image type with a floating point pixel type and cast the input - // images to the internal image type. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using InternalPixelType = float; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - using FixedImageCasterType = itk::CastImageFilter< FixedImageType, - InternalImageType >; - using MovingImageCasterType = itk::CastImageFilter< MovingImageType, - InternalImageType >; - - FixedImageCasterType::Pointer fixedImageCaster = FixedImageCasterType::New(); - MovingImageCasterType::Pointer movingImageCaster - = MovingImageCasterType::New(); - - fixedImageCaster->SetInput( fixedImageReader->GetOutput() ); - movingImageCaster->SetInput( movingImageReader->GetOutput() ); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The level set motion algorithm relies on the assumption that - // pixels representing the same homologous point on an object have - // the same intensity on both the fixed and moving images to be - // registered. In this example, we will preprocess the moving image - // to match the intensity between the images using the - // \doxygen{HistogramMatchingImageFilter}. - // - // \index{itk::HistogramMatchingImageFilter} - // - // The basic idea is to match the histograms of the two images at a user-specified number of quantile values. For robustness, the histograms are - // matched so that the background pixels are excluded from both histograms. - // For MR images, a simple procedure is to exclude all gray values that are - // smaller than the mean gray value of the image. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using MatchingFilterType = itk::HistogramMatchingImageFilter< - InternalImageType, - InternalImageType >; - MatchingFilterType::Pointer matcher = MatchingFilterType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // For this example, we set the moving image as the source or input image and - // the fixed image as the reference image. - // - // \index{itk::HistogramMatchingImageFilter!SetInput()} - // \index{itk::HistogramMatchingImageFilter!SetSourceImage()} - // \index{itk::HistogramMatchingImageFilter!SetReferenceImage()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - matcher->SetInput( movingImageCaster->GetOutput() ); - matcher->SetReferenceImage( fixedImageCaster->GetOutput() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // We then select the number of bins to represent the histograms and the - // number of points or quantile values where the histogram is to be - // matched. - // - // \index{itk::HistogramMatchingImageFilter!SetNumberOfHistogramLevels()} - // \index{itk::HistogramMatchingImageFilter!SetNumberOfMatchPoints()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - matcher->SetNumberOfHistogramLevels( 1024 ); - matcher->SetNumberOfMatchPoints( 7 ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Simple background extraction is done by thresholding at the mean - // intensity. - // - // \index{itk::HistogramMatchingImageFilter!ThresholdAtMeanIntensityOn()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - matcher->ThresholdAtMeanIntensityOn(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // In the \doxygen{LevelSetMotionRegistrationFilter}, the - // deformation field is represented as an image whose pixels are - // floating point vectors. - // - // \index{itk::LevelSetMotionRegistrationFilter} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using VectorPixelType = itk::Vector< float, Dimension >; - using DisplacementFieldType = itk::Image< VectorPixelType, Dimension >; - using RegistrationFilterType = itk::LevelSetMotionRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType>; - RegistrationFilterType::Pointer filter = RegistrationFilterType::New(); - // Software Guide : EndCodeSnippet - - // Create the Command observer and register it with the registration filter. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - filter->AddObserver( itk::IterationEvent(), observer ); - - // Software Guide : BeginLatex - // - // The input fixed image is simply the output of the fixed image casting - // filter. The input moving image is the output of the histogram matching - // filter. - // - // \index{itk::LevelSetMotionRegistrationFilter!SetFixedImage()} - // \index{itk::LevelSetMotionRegistrationFilter!SetMovingImage()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->SetFixedImage( fixedImageCaster->GetOutput() ); - filter->SetMovingImage( matcher->GetOutput() ); - - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The level set motion registration filter has two parameters: the - // number of iterations to be performed and the standard deviation - // of the Gaussian smoothing kernel to be applied to the image prior - // to calculating gradients. - // \index{itk::LevelSetMotionRegistrationFilter!SetNumberOfIterations()} - // \index{itk::LevelSetMotionRegistrationFilter!SetStandardDeviations()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->SetNumberOfIterations( 50 ); - filter->SetGradientSmoothingStandardDeviations(4); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The registration algorithm is triggered by updating the filter. The - // filter output is the computed deformation field. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - filter->Update(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The \doxygen{WarpImageFilter} can be used to warp the moving image with - // the output deformation field. Like the \doxygen{ResampleImageFilter}, - // the WarpImageFilter requires the specification of the input image to be - // resampled, an input image interpolator, and the output image spacing and - // origin. - // - // \index{itk::WarpImageFilter} - // \index{itk::WarpImageFilter!SetInput()} - // \index{itk::WarpImageFilter!SetInterpolator()} - // \index{itk::WarpImageFilter!SetOutputSpacing()} - // \index{itk::WarpImageFilter!SetOutputOrigin()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using WarperType = itk::WarpImageFilter< - MovingImageType, - MovingImageType, - DisplacementFieldType >; - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, - double >; - WarperType::Pointer warper = WarperType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - warper->SetInput( movingImageReader->GetOutput() ); - warper->SetInterpolator( interpolator ); - warper->SetOutputSpacing( fixedImage->GetSpacing() ); - warper->SetOutputOrigin( fixedImage->GetOrigin() ); - warper->SetOutputDirection( fixedImage->GetDirection() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Unlike the ResampleImageFilter, the WarpImageFilter - // warps or transform the input image with respect to the deformation field - // represented by an image of vectors. The resulting warped or resampled - // image is written to file as per previous examples. - // - // \index{itk::WarpImageFilter!SetDisplacementField()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - warper->SetDisplacementField( filter->GetOutput() ); - // Software Guide : EndCodeSnippet - - - // Write warped image out to file - using OutputPixelType = unsigned char; - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - using CastFilterType = itk::CastImageFilter< - MovingImageType, - OutputImageType >; - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - writer->SetFileName( argv[3] ); - - caster->SetInput( warper->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - - // Software Guide : BeginLatex - // - // Let's execute this example using the rat lung data from the previous example. - // The associated data files can be found in \code{Examples/Data}: - // - // \begin{itemize} - // \item \code{RatLungSlice1.mha} - // \item \code{RatLungSlice2.mha} - // \end{itemize} - // - // \begin{figure} \center - // \includegraphics[width=0.44\textwidth]{DeformableRegistration2CheckerboardBefore} - // \includegraphics[width=0.44\textwidth]{DeformableRegistration2CheckerboardAfter} - // \itkcaption[Demon's deformable registration output]{Checkerboard comparisons - // before and after demons-based deformable registration.} - // \label{fig:DeformableRegistration5Output} - // \end{figure} - // - // The result of the demons-based deformable registration is presented in - // Figure \ref{fig:DeformableRegistration5Output}. The checkerboard - // comparison shows that the algorithm was able to recover the misalignment - // due to expiration. - // - // Software Guide : EndLatex - - // Software Guide : BeginLatex - // - // It may be also desirable to write the deformation field as an image of - // vectors. This can be done with the following code. - // - // Software Guide : EndLatex - - if( argc > 4 ) // if a fourth line argument has been provided... - { - - // Software Guide : BeginCodeSnippet - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - fieldWriter->SetFileName( argv[4] ); - fieldWriter->SetInput( filter->GetOutput() ); - - fieldWriter->Update(); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Note that the file format used for writing the deformation field must be - // capable of representing multiple components per pixel. This is the case - // for the MetaImage and VTK file formats for example. - // - // Software Guide : EndLatex - - } - - - if( argc > 5 ) // if a fifth line argument has been provided... - { - - using VectorImage2DType = DisplacementFieldType; - using Vector2DType = DisplacementFieldType::PixelType; - - VectorImage2DType::ConstPointer vectorImage2D = filter->GetOutput(); - - VectorImage2DType::RegionType region2D = vectorImage2D->GetBufferedRegion(); - VectorImage2DType::IndexType index2D = region2D.GetIndex(); - VectorImage2DType::SizeType size2D = region2D.GetSize(); - - - using Vector3DType = itk::Vector< float, 3 >; - using VectorImage3DType = itk::Image< Vector3DType, 3 >; - - using VectorImage3DWriterType = itk::ImageFileWriter< VectorImage3DType >; - - VectorImage3DWriterType::Pointer writer3D = VectorImage3DWriterType::New(); - - VectorImage3DType::Pointer vectorImage3D = VectorImage3DType::New(); - - VectorImage3DType::RegionType region3D; - VectorImage3DType::IndexType index3D; - VectorImage3DType::SizeType size3D; - - index3D[0] = index2D[0]; - index3D[1] = index2D[1]; - index3D[2] = 0; - - size3D[0] = size2D[0]; - size3D[1] = size2D[1]; - size3D[2] = 1; - - region3D.SetSize( size3D ); - region3D.SetIndex( index3D ); - - VectorImage2DType::SpacingType spacing2D = vectorImage2D->GetSpacing(); - VectorImage3DType::SpacingType spacing3D; - - spacing3D[0] = spacing2D[0]; - spacing3D[1] = spacing2D[1]; - spacing3D[2] = 1.0; - - vectorImage3D->SetSpacing( spacing3D ); - - vectorImage3D->SetRegions( region3D ); - vectorImage3D->Allocate(); - - using Iterator2DType = itk::ImageRegionConstIterator< VectorImage2DType >; - - using Iterator3DType = itk::ImageRegionIterator< VectorImage3DType >; - - Iterator2DType it2( vectorImage2D, region2D ); - Iterator3DType it3( vectorImage3D, region3D ); - - it2.GoToBegin(); - it3.GoToBegin(); - - Vector2DType vector2D; - Vector3DType vector3D; - - vector3D[2] = 0; // set Z component to zero. - - while( !it2.IsAtEnd() ) - { - vector2D = it2.Get(); - vector3D[0] = vector2D[0]; - vector3D[1] = vector2D[1]; - it3.Set( vector3D ); - ++it2; - ++it3; - } - - writer3D->SetInput( vectorImage3D ); - - writer3D->SetFileName( argv[5] ); - - try - { - writer3D->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DeformableRegistration9.cxx b/Examples/RegistrationITKv3/DeformableRegistration9.cxx deleted file mode 100644 index 125be5ea861..00000000000 --- a/Examples/RegistrationITKv3/DeformableRegistration9.cxx +++ /dev/null @@ -1,212 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -#include "itkConfigure.h" - - -#ifndef ITK_USE_FFTWD -#error "This program needs single precision FFTWD to work." -#endif - - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkCurvatureRegistrationFilter.h" -#include "itkFastSymmetricForcesDemonsRegistrationFunction.h" - -#include "itkHistogramMatchingImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkLinearInterpolateImageFunction.h" - -constexpr unsigned int Dimension = 2; - -// The following section of code implements a Command observer -// that will monitor the evolution of the registration process. -// - class CommandIterationUpdate : public itk::Command - { - public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( CommandIterationUpdate ); - protected: - CommandIterationUpdate() {}; - - using InternalImageType = itk::Image< float, Dimension >; - using VectorPixelType = itk::Vector< float, Dimension >; - using DisplacementFieldType = itk::Image< VectorPixelType, Dimension >; - - using RegistrationFilterType = itk::CurvatureRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType, - itk::FastSymmetricForcesDemonsRegistrationFunction< - InternalImageType,InternalImageType, - DisplacementFieldType> >; - - public: - - void Execute(itk::Object *caller, const itk::EventObject & event) - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) - { - const RegistrationFilterType * filter = static_cast< const RegistrationFilterType * >( object ); - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - std::cout << filter->GetMetric() << std::endl; - } - }; - - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImageFile " << std::endl; - return EXIT_FAILURE; - } - - using PixelType = short; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = - FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = - MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - using InternalPixelType = float; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - using FixedImageCasterType = itk::CastImageFilter< FixedImageType, - InternalImageType >; - using MovingImageCasterType = itk::CastImageFilter< MovingImageType, - InternalImageType >; - - FixedImageCasterType::Pointer fixedImageCaster = - FixedImageCasterType::New(); - MovingImageCasterType::Pointer movingImageCaster = - MovingImageCasterType::New(); - - fixedImageCaster->SetInput( fixedImageReader->GetOutput() ); - movingImageCaster->SetInput( movingImageReader->GetOutput() ); - - using MatchingFilterType = itk::HistogramMatchingImageFilter< - InternalImageType, - InternalImageType >; - MatchingFilterType::Pointer matcher = MatchingFilterType::New(); - - matcher->SetInput( movingImageCaster->GetOutput() ); - matcher->SetReferenceImage( fixedImageCaster->GetOutput() ); - matcher->SetNumberOfHistogramLevels( 1024 ); - matcher->SetNumberOfMatchPoints( 7 ); - matcher->ThresholdAtMeanIntensityOn(); - - using VectorPixelType = itk::Vector< float, Dimension >; - using DisplacementFieldType = itk::Image< VectorPixelType, Dimension >; - using RegistrationFilterType = itk::CurvatureRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType, - itk::FastSymmetricForcesDemonsRegistrationFunction< - InternalImageType,InternalImageType, - DisplacementFieldType> >; - RegistrationFilterType::Pointer filter = RegistrationFilterType::New(); - - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - filter->AddObserver( itk::IterationEvent(), observer ); - - filter->SetFixedImage( fixedImageCaster->GetOutput() ); - filter->SetMovingImage( matcher->GetOutput() ); - filter->SetNumberOfIterations( 150 ); - filter->SetTimeStep( 1 ); - filter->SetConstraintWeight( 1 ); - filter->Update(); - - using WarperType = itk::WarpImageFilter< - MovingImageType, - MovingImageType, - DisplacementFieldType >; - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, - double >; - WarperType::Pointer warper = WarperType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - warper->SetInput( movingImageReader->GetOutput() ); - warper->SetInterpolator( interpolator ); - warper->SetOutputSpacing( fixedImage->GetSpacing() ); - warper->SetOutputOrigin( fixedImage->GetOrigin() ); - warper->SetOutputDirection( fixedImage->GetDirection() ); - warper->SetDisplacementField( filter->GetOutput() ); - - // Write warped image out to file - using OutputPixelType = unsigned short; - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - using CastFilterType = itk::CastImageFilter< - MovingImageType, - OutputImageType >; - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - writer->SetFileName( argv[3] ); - - caster->SetInput( warper->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - if( argc > 4 ) // if a fourth line argument has been provided... - { - - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - fieldWriter->SetFileName( argv[4] ); - fieldWriter->SetInput( filter->GetOutput() ); - - try - { - fieldWriter->Update(); - } - catch ( itk::ExceptionObject & e ) - { - e.Print( std::cerr ); - } - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/DisplacementFieldInitialization.cxx b/Examples/RegistrationITKv3/DisplacementFieldInitialization.cxx deleted file mode 100644 index 7900505e48a..00000000000 --- a/Examples/RegistrationITKv3/DisplacementFieldInitialization.cxx +++ /dev/null @@ -1,162 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// In order to initialize deformable registration algorithm it is often -// convenient to generate a displacemnt field from a set of feature -// correspondances provided by the user. The following example illustrates how -// to use the \doxygen{itkLandmarkDisplacementFieldSource} class in order to generate a -// displacement field from the specification of two sets of landmarks. -// Landmarks from one set are associated one-to-one to the landmarks in the -// other set. Each landmark pair defines one displacement vector. This class -// interpolates the values of all other displacement vectors using -// \doxygen{KernelBasedTransform} -// -// -// \index{Registration!Finite Element-Based} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkImage.h" -#include "itkVector.h" -#include "itkLandmarkDisplacementFieldSource.h" -#include "itkImageFileWriter.h" - -#include - - -int main( int argc, char * argv[] ) -{ - - if( argc < 3 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " landmarksFile fixedImage outputDisplacementField" - << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - using VectorComponentType = float; - - using VectorType = itk::Vector< VectorComponentType, Dimension >; - - using DisplacementFieldType = itk::Image< VectorType, Dimension >; - - - using PixelType = unsigned char; - using FixedImageType = itk::Image< PixelType, Dimension >; - - using FixedReaderType = itk::ImageFileReader< FixedImageType >; - - - FixedReaderType::Pointer fixedReader = FixedReaderType::New(); - - fixedReader->SetFileName( argv[2] ); - - try - { - fixedReader->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - FixedImageType::ConstPointer fixedImage = fixedReader->GetOutput(); - - using FilterType = itk::LandmarkDisplacementFieldSource< DisplacementFieldType >; - - FilterType::Pointer filter = FilterType::New(); - - filter->SetOutputSpacing( fixedImage->GetSpacing() ); - filter->SetOutputOrigin( fixedImage->GetOrigin() ); - filter->SetOutputRegion( fixedImage->GetLargestPossibleRegion() ); - filter->SetOutputDirection( fixedImage->GetDirection() ); - - // Create source and target landmarks. - // - using LandmarkContainerType = FilterType::LandmarkContainer; - using LandmarkPointType = FilterType::LandmarkPointType; - - LandmarkContainerType::Pointer sourceLandmarks - = LandmarkContainerType::New(); - LandmarkContainerType::Pointer targetLandmarks - = LandmarkContainerType::New(); - std::ifstream pointsFile; - pointsFile.open( argv[1] ); - - LandmarkPointType sourcePoint; - pointsFile >> sourcePoint; - LandmarkPointType targetPoint; - pointsFile >> targetPoint; - - unsigned int pointId = 0; - while( !pointsFile.fail() ) - { - sourceLandmarks->InsertElement( pointId, sourcePoint ); - targetLandmarks->InsertElement( pointId, targetPoint ); - pointId++; - - pointsFile >> sourcePoint; - pointsFile >> targetPoint; - } - pointsFile.close(); - filter->SetSourceLandmarks( sourceLandmarks ); - filter->SetTargetLandmarks( targetLandmarks ); - - try - { - filter->UpdateLargestPossibleRegion(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - // Write an image for regression testing - using WriterType = itk::ImageFileWriter< DisplacementFieldType >; - - WriterType::Pointer writer = WriterType::New(); - writer->SetInput ( filter->GetOutput() ); - writer->SetFileName( argv[3] ); - filter->Print( std::cout ); - try - { - writer->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown by writer" << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -// Software Guide : EndLatex -} diff --git a/Examples/RegistrationITKv3/ImageRegistration10.cxx b/Examples/RegistrationITKv3/ImageRegistration10.cxx deleted file mode 100644 index 4bfc958b7d6..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration10.cxx +++ /dev/null @@ -1,522 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates the use of the image registration framework in -// Insight to align two label maps. Common structures are assumed to -// use the same label. The registration metric simply counts the -// number of corresponding pixels that have the same label. -// -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet -#include "itkImageRegistrationMethod.h" -#include "itkTranslationTransform.h" -#include "itkMatchCardinalityImageToImageMetric.h" -#include "itkNearestNeighborInterpolateImageFunction.h" -#include "itkAmoebaOptimizer.h" -// Software Guide : EndCodeSnippet - - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkSquaredDifferenceImageFilter.h" -#include "itkFileOutputWindow.h" - -// -// The following piece of code implements an observer -// that will monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - using OptimizerType = itk::AmoebaOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( ! itk::IterationEvent().CheckEvent( &event ) ) - { - return; - } - std::cout << optimizer->GetCachedValue() << " "; - std::cout << optimizer->GetCachedCurrentPosition() << std::endl; - } -}; - - -int main( int argc, char *argv[] ) -{ - if( argc < 3 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImagefile [differenceImage]" << std::endl; - std::cerr << " [initialTx] [initialTy]" << std::endl; - return EXIT_FAILURE; - } - - itk::FileOutputWindow::Pointer fow = itk::FileOutputWindow::New(); - fow->SetInstance( fow ); - - // The types of each one of the components in the registration methods should - // be instantiated. First, we select the image dimension and the type for - // representing image pixels. - // - constexpr unsigned int Dimension = 2; - using PixelType = float; - - - // The types of the input images are instantiated by the following lines. - // - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - // Software Guide : BeginLatex - // The transform that will map one image space into the other is defined - // below. - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - using TransformType = itk::TranslationTransform< double, Dimension >; - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // An optimizer is required to explore the parameter space of the transform - // in search of optimal values of the metric. The metric selected - // does not require analytical derivatives of its cost function. - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - using OptimizerType = itk::AmoebaOptimizer; - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // The metric will compare how well the two images match each - // other. Metric types are usually parameterized by the image types - // as can be seen in the following type declaration. The metric - // selected here is suitable for comparing two label maps where the - // labels are consistent between the two maps. This metric - // measures the percentage of pixels that exactly match or - // mismatch. - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - using MetricType = itk::MatchCardinalityImageToImageMetric< - FixedImageType, - MovingImageType >; - // Software Guide : EndCodeSnippet - - // Finally, the type of the interpolator is declared. The - // interpolator will evaluate the moving image at non-grid - // positions. - // Software Guide : BeginLatex - // Since we are registering label maps, we use a - // NearestNeighborInterpolateImageFunction to ensure subpixel - // values are not interpolated (to labels that do not exist). - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - using InterpolatorType = itk:: NearestNeighborInterpolateImageFunction< - MovingImageType, - double >; - // Software Guide : EndCodeSnippet - - // The registration method type is instantiated using the types of the - // fixed and moving images. This class is responsible for interconnecting - // all the components we have described so far. - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - // Each one of the registration components is created using its - // \code{New()} method and is assigned to its respective - // \doxygen{SmartPointer}. - // - // Software Guide : BeginCodeSnippet - MetricType::Pointer metric = MetricType::New(); - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // We are using a MatchCardinalityImageToImageMetric to compare two - // label maps. This metric simple counts the percentage of - // corresponding pixels that have the same label. This metric does - // not provide analytical derivatives, so we will use an - // AmoebaOptimizer to drive the registration. The AmoebaOptimizer - // can only minimize a cost function, so we set the metric to count - // the percentages of mismatches. - // Software Guide : BeginLatex - // Software Guide : BeginCodeSnippet - metric->MeasureMatchesOff(); - // Software Guide : EndCodeSnippet - - - // Each component is now connected to the instance of the registration method. - // \index{itk::RegistrationMethod!SetMetric()} - // \index{itk::RegistrationMethod!SetOptimizer()} - // \index{itk::RegistrationMethod!SetTransform()} - // \index{itk::RegistrationMethod!SetFixedImage()} - // \index{itk::RegistrationMethod!SetMovingImage()} - // \index{itk::RegistrationMethod!SetInterpolator()} - // - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - FixedImageReaderType::Pointer - fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer - movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - - // In this example, the fixed and moving images are read from files. This - // requires the \doxygen{ImageRegistrationMethod} to acquire its inputs to - // the output of the readers. - // - registration->SetFixedImage( fixedImageReader->GetOutput() ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - // The registration can be restricted to consider only a particular region - // of the fixed image as input to the metric computation. This region is - // defined by the \code{SetFixedImageRegion()} method. You could use this - // feature to reduce the computational time of the registration or to avoid - // unwanted objects present in the image affecting the registration outcome. - // In this example we use the full available content of the image. This - // region is identified by the \code{BufferedRegion} of the fixed image. - // Note that for this region to be valid the reader must first invoke its - // \code{Update()} method. - // - // \index{itk::ImageRegistrationMethod!SetFixedImageRegion()} - // \index{itk::Image!GetBufferedRegion()} - // - fixedImageReader->Update(); - movingImageReader->Update(); - - registration->SetFixedImageRegion( - fixedImageReader->GetOutput()->GetBufferedRegion() ); - - - // The parameters of the transform are initialized by passing them in an - // array. This can be used to setup an initial known correction of the - // misalignment. In this particular case, a translation transform is - // being used for the registration. The array of parameters for this - // transform is simply composed of the translation values along each - // dimension. Setting the values of the parameters to zero - // initializes the transform as an \emph{identity} transform. Note that the - // array constructor requires the number of elements as an argument. - // - // \index{itk::TranslationTransform!GetNumberOfParameters()} - // \index{itk::RegistrationMethod!SetInitialTransformParameters()} - // - using ParametersType = RegistrationType::ParametersType; - ParametersType initialParameters( transform->GetNumberOfParameters() ); - - double tx = 0.0; - double ty = 0.0; - - if( argc > 6 ) - { - tx = std::stod( argv[5] ); - ty = std::stod( argv[6] ); - } - - initialParameters[0] = tx; // Initial offset in mm along X - initialParameters[1] = ty; // Initial offset in mm along Y - - registration->SetInitialTransformParameters( initialParameters ); - - // At this point the registration method is ready for execution. The - // optimizer is the component that drives the execution of the - // registration. However, the ImageRegistrationMethod class - // orchestrates the ensemble to make sure that everything is in place - // before control is passed to the optimizer. - // - - // Software Guide : BeginLatex - // It is usually desirable to fine tune the parameters of the optimizer. - // Each optimizer has particular parameters that must be interpreted in the - // context of the optimization strategy it implements. - // - // The AmoebaOptimizer moves a simplex around the cost surface. - // Here we set the initial size of the simplex (5 units in each of - // the parameters) - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - OptimizerType::ParametersType - simplexDelta( transform->GetNumberOfParameters() ); - simplexDelta.Fill( 5.0 ); - - optimizer->AutomaticInitialSimplexOff(); - optimizer->SetInitialSimplexDelta( simplexDelta ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // We also adjust the tolerances on the optimizer to define - // convergence. Here, we used a tolerance on the parameters of - // 0.25 (which will be a quarter of image unit, in this case - // pixels). We also set the tolerance on the cost function value to - // define convergence. The metric we are using returns the - // percentage of pixels that mismatch. So we set the function - // convergence to be 0.1% - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - optimizer->SetParametersConvergenceTolerance( 0.25 ); // quarter pixel - optimizer->SetFunctionConvergenceTolerance(0.001); // 0.1% - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // In the case where the optimizer never succeeds in reaching the desired - // precision tolerance, it is prudent to establish a limit on the number of - // iterations to be performed. This maximum number is defined with the - // method \code{SetMaximumNumberOfIterations()}. - // - // \index{itk::Amoeba\-Optimizer!SetMaximumNumberOfIterations()} - // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - optimizer->SetMaximumNumberOfIterations( 200 ); - // Software Guide : EndCodeSnippet - - // - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - - // The registration process is triggered by an invocation of the - // \code{Update()} method. If something goes wrong during the - // initialization or execution of the registration an exception will be - // thrown. We should therefore place the \code{Update()} method - // in a \code{try/catch} block as illustrated in the following lines. - // - try - { - // print out the initial metric value. need to initialize the - // registration method to force all the connections to be established. - registration->Initialize(); - std::cout << "Initial Metric value = " - << metric->GetValue( initialParameters ) - << std::endl; - - // run the registration - registration->Update(); - std::cout << "Optimizer stop condition = " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - // In a real application, you may attempt to recover from the error in the - // catch block. Here we are simply printing out a message and then - // terminating the execution of the program. - // - - // - // The result of the registration process is an array of parameters that - // defines the spatial transformation in an unique way. This final result is - // obtained using the \code{GetLastTransformParameters()} method. - // - // \index{itk::RegistrationMethod!GetLastTransformParameters()} - // - ParametersType finalParameters = registration->GetLastTransformParameters(); - - // In the case of the \doxygen{TranslationTransform}, there is a - // straightforward interpretation of the parameters. Each element of the - // array corresponds to a translation along one spatial dimension. - // - const double TranslationAlongX = finalParameters[0]; - const double TranslationAlongY = finalParameters[1]; - - // The optimizer can be queried for the actual number of iterations - // performed to reach convergence. - // - const unsigned int numberOfIterations - = optimizer->GetOptimizer()->get_num_evaluations(); - - // The value of the image metric corresponding to the last set of parameters - // can be obtained with the \code{GetValue()} method of the - // optimizer. Since the AmoebaOptimizer does not yet support a call - // to GetValue(), we will simply re-evaluate the metric at the - // final parameters. - // - const double bestValue = metric->GetValue(finalParameters); - - // Print out results - // - std::cout << "Result = " << std::endl; - std::cout << " Translation X = " << TranslationAlongX << std::endl; - std::cout << " Translation Y = " << TranslationAlongY << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - - // It is common, as the last step of a registration task, to use the - // resulting transform to map the moving image into the fixed image space. - // This is easily done with the \doxygen{ResampleImageFilter}. Please - // refer to Section~\ref{sec:ResampleImageFilter} for details on the use - // of this filter. First, a ResampleImageFilter type is instantiated - // using the image types. It is convenient to use the fixed image type as - // the output type since it is likely that the transformed moving image - // will be compared with the fixed image. - // - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - // A transform of the same type used in the registration process should be - // created and initialized with the parameters resulting from the - // registration process. - // - // \index{itk::ImageRegistrationMethod!Resampling image} - // - TransformType::Pointer finalTransform = TransformType::New(); - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - // Then a resampling filter is created and the corresponding transform and - // moving image connected as inputs. - // - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - - // As described in Section \ref{sec:ResampleImageFilter}, the - // ResampleImageFilter requires additional parameters to be - // specified, in particular, the spacing, origin and size of the output - // image. The default pixel value is also set to the standard label - // for "unknown" or background. Finally, we need to set the - // interpolator to be the same type of interpolator as the - // registration method used (nearest neighbor). - // - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( 0 ); - resample->SetInterpolator( interpolator ); - - // The output of the filter is passed to a writer that will store the - // image in a file. An \doxygen{CastImageFilter} is used to convert the - // pixel type of the resampled image to the final type used by the - // writer. The cast and writer filters are instantiated below. - // - using OutputPixelType = unsigned short; - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - using WriterType = itk::ImageFileWriter< OutputImageType >; - - // The filters are created by invoking their \code{New()} - // method. - // - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - - writer->SetFileName( argv[3] ); - - - // The \code{Update()} method of the writer is invoked in order to trigger - // the execution of the pipeline. - // - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - - // - // The fixed image and the transformed moving image can easily be compared - // using the \code{SquaredDifferenceImageFilter}. This pixel-wise - // filter computes the squared value of the difference between homologous - // pixels of its input images. - // - using DifferenceFilterType = itk::SquaredDifferenceImageFilter< - FixedImageType, - FixedImageType, - OutputImageType >; - - DifferenceFilterType::Pointer difference = DifferenceFilterType::New(); - difference->SetInput1( fixedImageReader->GetOutput() ); - difference->SetInput2( resample->GetOutput() ); - - // Its output can be passed to another writer. - // - WriterType::Pointer writer2 = WriterType::New(); - writer2->SetInput( difference->GetOutput() ); - - if( argc > 4 ) - { - writer2->SetFileName( argv[4] ); - writer2->Update(); - } - - - return EXIT_SUCCESS; -} - -// SoftwareGuide : BeginLatex -// The example was run on two binary images. The first binary image was generated by running the -// confidence connected image filter (section \ref{sec:ConfidenceConnected}) on -// the MRI slice of the brain. The second was generated similarly after -// shifting the slice by 13 pixels horizontally and 17 pixels -// vertically. The Amoeba optimizer converged after 34 iterations -// and produced the following results: -// -// \begin{verbatim} -// Translation X = 12.5 -// Translation Y = 16.77 -// \end{verbatim} -// These results are a close match to the true misalignment. -// SoftwareGuide : EndLatex diff --git a/Examples/RegistrationITKv3/ImageRegistration15.cxx b/Examples/RegistrationITKv3/ImageRegistration15.cxx deleted file mode 100644 index dc72afa5a59..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration15.cxx +++ /dev/null @@ -1,286 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to do registration with a 2D Translation Transform, -// the Normalized Mutual Information metric and the One+One evolutionary optimizer. -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet -#include "itkImageRegistrationMethod.h" - -#include "itkTranslationTransform.h" -#include "itkNormalizedMutualInformationHistogramImageToImageMetric.h" -#include "itkOnePlusOneEvolutionaryOptimizer.h" -#include "itkNormalVariateGenerator.h" - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" - - -// The following section of code implements a Command observer -// used to monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {m_LastMetricValue = 0;} - -public: - using OptimizerType = itk::OnePlusOneEvolutionaryOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( ! itk::IterationEvent().CheckEvent( &event ) ) - { - return; - } - double currentValue = optimizer->GetValue(); - // Only print out when the Metric value changes - if( std::fabs( m_LastMetricValue - currentValue ) > 1e-7 ) - { - std::cout << optimizer->GetCurrentIteration() << " "; - std::cout << currentValue << " "; - std::cout << optimizer->GetFrobeniusNorm() << " "; - std::cout << optimizer->GetCurrentPosition() << std::endl; - m_LastMetricValue = currentValue; - } - } - -private: - double m_LastMetricValue; -}; - - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << "outputImagefile [numberOfHistogramBins] "; - std::cerr << "[initialRadius] [epsilon] [initialTx] [initialTy]" - << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - using PixelType = unsigned char; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - using TransformType = itk::TranslationTransform< double, Dimension >; - - using OptimizerType = itk::OnePlusOneEvolutionaryOptimizer; - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, - double >; - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - - using MetricType = itk::NormalizedMutualInformationHistogramImageToImageMetric< - FixedImageType, - MovingImageType >; - - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - - - MetricType::Pointer metric = MetricType::New(); - registration->SetMetric( metric ); - - - unsigned int numberOfHistogramBins = 32; - if( argc > 4 ) - { - numberOfHistogramBins = std::stoi( argv[4] ); - std::cout << "Using " << numberOfHistogramBins << " Histogram bins" - << std::endl; - } - MetricType::HistogramType::SizeType histogramSize; - histogramSize.SetSize(2); - histogramSize[0] = numberOfHistogramBins; - histogramSize[1] = numberOfHistogramBins; - metric->SetHistogramSize( histogramSize ); - - - const unsigned int numberOfParameters = transform->GetNumberOfParameters(); - - using ScalesType = MetricType::ScalesType; - ScalesType scales( numberOfParameters ); - - scales.Fill( 1.0 ); - - metric->SetDerivativeStepLengthScales(scales); - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader - = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - registration->SetFixedImage( fixedImageReader->GetOutput() ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - fixedImageReader->Update(); - movingImageReader->Update(); - - FixedImageType::ConstPointer fixedImage = fixedImageReader->GetOutput(); - registration->SetFixedImageRegion( fixedImage->GetBufferedRegion() ); - - transform->SetIdentity(); - using ParametersType = RegistrationType::ParametersType; - ParametersType initialParameters = transform->GetParameters(); - initialParameters[0] = 0.0; - initialParameters[1] = 0.0; - - if( argc > 8 ) - { - initialParameters[0] = std::stod( argv[7] ); - initialParameters[1] = std::stod( argv[8] ); - } - registration->SetInitialTransformParameters( initialParameters ); - - std::cout << "Initial transform parameters = "; - std::cout << initialParameters << std::endl; - - using OptimizerScalesType = OptimizerType::ScalesType; - OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() ); - - FixedImageType::RegionType region = fixedImage->GetLargestPossibleRegion(); - FixedImageType::SizeType size = region.GetSize(); - FixedImageType::SpacingType spacing = fixedImage->GetSpacing(); - - optimizerScales[0] = 1.0 / ( 0.1 * size[0] * spacing[0] ); - optimizerScales[1] = 1.0 / ( 0.1 * size[1] * spacing[1] ); - optimizer->SetScales( optimizerScales ); - - using GeneratorType = itk::Statistics::NormalVariateGenerator; - GeneratorType::Pointer generator = GeneratorType::New(); - generator->Initialize(12345); - - optimizer->MaximizeOn(); - optimizer->SetNormalVariateGenerator( generator ); - double initialRadius = 0.01; - if( argc > 5 ) - { - initialRadius = std::stod( argv[5] ); - std::cout << "Using initial radius = " << initialRadius << std::endl; - } - optimizer->Initialize( initialRadius ); - double epsilon = 0.001; - if( argc > 6 ) - { - epsilon = std::stod( argv[6] ); - std::cout << "Using epsilon = " << epsilon << std::endl; - } - optimizer->SetEpsilon( epsilon ); - optimizer->SetMaximumIteration( 2000 ); - - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - ParametersType finalParameters = registration->GetLastTransformParameters(); - const double finalTranslationX = finalParameters[0]; - const double finalTranslationY = finalParameters[1]; - unsigned int numberOfIterations = optimizer->GetCurrentIteration(); - const double bestValue = optimizer->GetValue(); - - // Print out results - std::cout << "Result = " << std::endl; - std::cout << " Translation X = " << finalTranslationX << std::endl; - std::cout << " Translation Y = " << finalTranslationY << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, FixedImageType >; - - TransformType::Pointer finalTransform = TransformType::New(); - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( 100 ); - - using OutputImageType = itk::Image< PixelType, Dimension >; - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - writer->SetFileName( argv[3] ); - writer->SetInput( resample->GetOutput() ); - writer->Update(); - // Software Guide : EndCodeSnippet - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/ImageRegistration16.cxx b/Examples/RegistrationITKv3/ImageRegistration16.cxx deleted file mode 100644 index aa4beceee8c..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration16.cxx +++ /dev/null @@ -1,335 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to do registration with a 2D Translation Transform, -// the Normalized Mutual Information metric and the Amoeba optimizer. -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet -#include "itkImageRegistrationMethod.h" - -#include "itkTranslationTransform.h" -#include "itkMattesMutualInformationImageToImageMetric.h" -#include "itkAmoebaOptimizer.h" -#include "itkMersenneTwisterRandomVariateGenerator.h" - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" - - -// The following section of code implements a Command observer -// used to monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() - { - m_IterationNumber=0; - } - -public: - using OptimizerType = itk::AmoebaOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( ! itk::IterationEvent().CheckEvent( &event ) ) - { - return; - } - std::cout << m_IterationNumber++ << " "; - std::cout << optimizer->GetCachedValue() << " "; - std::cout << optimizer->GetCachedCurrentPosition() << std::endl; - } - -private: - unsigned long m_IterationNumber; -}; - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImagefile "; - std::cerr << " [initialTx] [initialTy]"; - std::cerr << "[useExplicitPDFderivatives ] " << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - using PixelType = unsigned char; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - using TransformType = itk::TranslationTransform< double, Dimension >; - - using OptimizerType = itk::AmoebaOptimizer; - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, - double >; - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - - using MetricType = itk::MattesMutualInformationImageToImageMetric< - FixedImageType, - MovingImageType >; - - - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - - - MetricType::Pointer metric = MetricType::New(); - registration->SetMetric( metric ); - - - // Software Guide : BeginLatex - // - // The metric requires two parameters to be selected: the number - // of bins used to compute the entropy and the number of spatial samples - // used to compute the density estimates. In typical application, 50 - // histogram bins are sufficient and the metric is relatively insensitive - // to changes in the number of bins. The number of spatial samples - // to be used depends on the content of the image. If the images are - // smooth and do not contain much detail, then using approximately - // $1$ percent of the pixels will do. On the other hand, if the images - // are detailed, it may be necessary to use a much higher proportion, - // such as $20$ percent. - // - // \index{itk::Mattes\-Mutual\-Information\-Image\-To\-Image\-Metric!SetNumberOfHistogramBins()} - // \index{itk::Mattes\-Mutual\-Information\-Image\-To\-Image\-Metric!SetNumberOfSpatialSamples()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - metric->SetNumberOfHistogramBins( 20 ); - metric->SetNumberOfSpatialSamples( 10000 ); - // Software Guide : EndCodeSnippet - - // For consistent results when regression testing. - metric->ReinitializeSeed( 121213 ); - - if( argc > 6 ) - { - // Define whether to calculate the metric derivative by explicitly - // computing the derivatives of the joint PDF with respect to the Transform - // parameters, or doing it by progressively accumulating contributions from - // each bin in the joint PDF. - metric->SetUseExplicitPDFDerivatives( std::stoi( argv[6] ) ); - } - - - const unsigned int numberOfParameters = transform->GetNumberOfParameters(); - - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - registration->SetFixedImage( fixedImageReader->GetOutput() ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - fixedImageReader->Update(); - movingImageReader->Update(); - - FixedImageType::ConstPointer fixedImage = fixedImageReader->GetOutput(); - - registration->SetFixedImageRegion( fixedImage->GetBufferedRegion() ); - - - transform->SetIdentity(); - - using ParametersType = RegistrationType::ParametersType; - - ParametersType initialParameters = transform->GetParameters(); - - initialParameters[0] = 0.0; - initialParameters[1] = 0.0; - - if( argc > 5 ) - { - initialParameters[0] = std::stod( argv[4] ); - initialParameters[1] = std::stod( argv[5] ); - } - - registration->SetInitialTransformParameters( initialParameters ); - - std::cout << "Initial transform parameters = "; - std::cout << initialParameters << std::endl; - - - // Software Guide : BeginLatex - // - // The AmoebaOptimizer moves a simplex around the cost surface. Here we set - // the initial size of the simplex (5 units in each of the parameters) - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - OptimizerType::ParametersType simplexDelta( numberOfParameters ); - simplexDelta.Fill( 5.0 ); - - optimizer->AutomaticInitialSimplexOff(); - optimizer->SetInitialSimplexDelta( simplexDelta ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // We also adjust the tolerances on the optimizer to define convergence. - // Here, we used a tolerance on the parameters of 0.1 (which will be one - // tenth of image unit, in this case pixels). We also set the tolerance on - // the cost function value to define convergence. The metric we are using - // returns the value of Mutual Information. So we set the function - // convergence to be 0.001 bits (bits are the appropriate units for - // measuring Information). - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->SetParametersConvergenceTolerance( 0.1 ); // 1/10th pixel - optimizer->SetFunctionConvergenceTolerance(0.001); // 0.001 bits - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // In the case where the optimizer never succeeds in reaching the desired - // precision tolerance, it is prudent to establish a limit on the number of - // iterations to be performed. This maximum number is defined with the - // method \code{SetMaximumNumberOfIterations()}. - // - // \index{itk::Amoeba\-Optimizer!SetMaximumNumberOfIterations()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->SetMaximumNumberOfIterations( 200 ); - // Software Guide : EndCodeSnippet - - - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - - ParametersType finalParameters = registration->GetLastTransformParameters(); - - const double finalTranslationX = finalParameters[0]; - const double finalTranslationY = finalParameters[1]; - - double bestValue = optimizer->GetValue(); - - - // Print out results - // - std::cout << "Result = " << std::endl; - std::cout << " Translation X = " << finalTranslationX << std::endl; - std::cout << " Translation Y = " << finalTranslationY << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - TransformType::Pointer finalTransform = TransformType::New(); - - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( 100 ); - - - using OutputImageType = itk::Image< PixelType, Dimension >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - - writer->SetFileName( argv[3] ); - - writer->SetInput( resample->GetOutput() ); - writer->Update(); - - // Software Guide : EndCodeSnippet - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/ImageRegistration17.cxx b/Examples/RegistrationITKv3/ImageRegistration17.cxx deleted file mode 100644 index 1fa03ea841c..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration17.cxx +++ /dev/null @@ -1,327 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to do registration with a 2D Translation Transform, -// the Mutual Information Histogram metric and the Amoeba optimizer. -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet -#include "itkImageRegistrationMethod.h" - -#include "itkTranslationTransform.h" -#include "itkMutualInformationHistogramImageToImageMetric.h" -#include "itkAmoebaOptimizer.h" - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" - - -// The following section of code implements a Command observer -// used to monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() - { - m_IterationNumber=0; - } - -public: - using OptimizerType = itk::AmoebaOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( ! itk::IterationEvent().CheckEvent( &event ) ) - { - return; - } - std::cout << m_IterationNumber++ << " "; - std::cout << optimizer->GetCachedValue() << " "; - std::cout << optimizer->GetCachedCurrentPosition() << std::endl; - } - -private: - unsigned long m_IterationNumber; -}; - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImagefile "; - std::cerr << " [initialTx] [initialTy]" << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - using PixelType = unsigned char; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - using TransformType = itk::TranslationTransform< double, Dimension >; - - using OptimizerType = itk::AmoebaOptimizer; - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, - double >; - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - - using MetricType = itk::MutualInformationHistogramImageToImageMetric< - FixedImageType, - MovingImageType >; - - - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - - - MetricType::Pointer metric = MetricType::New(); - registration->SetMetric( metric ); - - - // Software Guide : BeginCodeSnippet - using HistogramSizeType = MetricType::HistogramSizeType; - - HistogramSizeType histogramSize; - - histogramSize.SetSize(2); - - histogramSize[0] = 256; - histogramSize[1] = 256; - - metric->SetHistogramSize( histogramSize ); - - // The Amoeba optimizer doesn't need the cost function to compute derivatives - metric->ComputeGradientOff(); - // Software Guide : EndCodeSnippet - - - const unsigned int numberOfParameters = transform->GetNumberOfParameters(); - - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - registration->SetFixedImage( fixedImageReader->GetOutput() ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - fixedImageReader->Update(); - movingImageReader->Update(); - - FixedImageType::ConstPointer fixedImage = fixedImageReader->GetOutput(); - - registration->SetFixedImageRegion( fixedImage->GetBufferedRegion() ); - - - transform->SetIdentity(); - - using ParametersType = RegistrationType::ParametersType; - - ParametersType initialParameters = transform->GetParameters(); - - initialParameters[0] = 0.0; - initialParameters[1] = 0.0; - - if( argc > 5 ) - { - initialParameters[0] = std::stod( argv[4] ); - initialParameters[1] = std::stod( argv[5] ); - } - - registration->SetInitialTransformParameters( initialParameters ); - - std::cout << "Initial transform parameters = "; - std::cout << initialParameters << std::endl; - - - // Software Guide : BeginLatex - // - // The AmoebaOptimizer moves a simplex around the cost surface. Here we set - // the initial size of the simplex (5 units in each of the parameters) - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - OptimizerType::ParametersType simplexDelta( numberOfParameters ); - simplexDelta.Fill( 5.0 ); - - optimizer->AutomaticInitialSimplexOff(); - optimizer->SetInitialSimplexDelta( simplexDelta ); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The AmoebaOptimizer performs minimization by default. In this case - // however, the MutualInformation metric must be maximized. We should - // therefore invoke the \code{MaximizeOn()} method on the optimizer in order - // to set it up for maximization. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->MaximizeOn(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // We also adjust the tolerances on the optimizer to define convergence. - // Here, we used a tolerance on the parameters of 0.1 (which will be one - // tenth of image unit, in this case pixels). We also set the tolerance on - // the cost function value to define convergence. The metric we are using - // returns the value of Mutual Information. So we set the function - // convergence to be 0.001 bits (bits are the appropriate units for - // measuring Information). - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->SetParametersConvergenceTolerance( 0.1 ); // 1/10th pixel - optimizer->SetFunctionConvergenceTolerance(0.001); // 0.001 bits - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // In the case where the optimizer never succeeds in reaching the desired - // precision tolerance, it is prudent to establish a limit on the number of - // iterations to be performed. This maximum number is defined with the - // method \code{SetMaximumNumberOfIterations()}. - // - // \index{itk::Amoeba\-Optimizer!SetMaximumNumberOfIterations()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->SetMaximumNumberOfIterations( 200 ); - // Software Guide : EndCodeSnippet - - - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - - ParametersType finalParameters = registration->GetLastTransformParameters(); - - const double finalTranslationX = finalParameters[0]; - const double finalTranslationY = finalParameters[1]; - - double bestValue = optimizer->GetValue(); - - - // Print out results - // - std::cout << "Result = " << std::endl; - std::cout << " Translation X = " << finalTranslationX << std::endl; - std::cout << " Translation Y = " << finalTranslationY << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - TransformType::Pointer finalTransform = TransformType::New(); - - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( 100 ); - - - using OutputImageType = itk::Image< PixelType, Dimension >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - - writer->SetFileName( argv[3] ); - - writer->SetInput( resample->GetOutput() ); - writer->Update(); - - // Software Guide : EndCodeSnippet - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/ImageRegistration18.cxx b/Examples/RegistrationITKv3/ImageRegistration18.cxx deleted file mode 100644 index 0af4d138ae2..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration18.cxx +++ /dev/null @@ -1,260 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to use the -// \doxygen{GradientDifferenceImageToImageMetric}. -// -// This metric is particularly useful for registration scenarios where fitting -// the edges of both images is the most relevant criteria for registration -// success. -// -// \index{itk::ImageRegistrationMethod!Monitoring} -// -// -// Software Guide : EndLatex - - -#include "itkImageRegistrationMethod.h" -#include "itkTranslationTransform.h" -#include "itkGradientDifferenceImageToImageMetric.h" -#include "itkRegularStepGradientDescentOptimizer.h" - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkCommand.h" - -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( ! itk::IterationEvent().CheckEvent( &event ) ) - { - return; - } - std::cout << optimizer->GetCurrentIteration() << " = "; - std::cout << optimizer->GetValue() << " : "; - std::cout << optimizer->GetCurrentPosition() << std::endl; - } - -}; - - -int main( int argc, char *argv[] ) -{ - if( argc < 3 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << "outputImagefile" << std::endl; - std::cerr << "[initialTx] [initialTy]" << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - using PixelType = unsigned short; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - using TransformType = itk::TranslationTransform< double, Dimension >; - - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, - double >; - - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - using MetricType = itk::GradientDifferenceImageToImageMetric< - FixedImageType, - MovingImageType >; - - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - - MetricType::Pointer metric = MetricType::New(); - - metric->SetDerivativeDelta( 0.5 ); - - registration->SetMetric( metric ); - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - registration->SetFixedImage( fixedImageReader->GetOutput() ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - fixedImageReader->Update(); // This is needed to make the BufferedRegion below valid. - - registration->SetFixedImageRegion( - fixedImageReader->GetOutput()->GetBufferedRegion() ); - - using ParametersType = RegistrationType::ParametersType; - ParametersType initialParameters( transform->GetNumberOfParameters() ); - - initialParameters[0] = 0.0; // Initial offset in mm along X - initialParameters[1] = 0.0; // Initial offset in mm along Y - - if( argc > 4 ) - { - initialParameters[0] = std::stod( argv[4] ); - } - - if( argc > 5 ) - { - initialParameters[1] = std::stod( argv[5] ); - } - - std::cout << "Initial parameters = " << initialParameters << std::endl; - - registration->SetInitialTransformParameters( initialParameters ); - - optimizer->SetMaximumStepLength( 4.00 ); - optimizer->SetMinimumStepLength( 0.01 ); - optimizer->SetNumberOfIterations( 200 ); - optimizer->SetGradientMagnitudeTolerance( 1e-40 ); - - optimizer->MaximizeOn(); - - - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - - ParametersType finalParameters = registration->GetLastTransformParameters(); - - const double TranslationAlongX = finalParameters[0]; - const double TranslationAlongY = finalParameters[1]; - - const unsigned int numberOfIterations = optimizer->GetCurrentIteration(); - - const double bestValue = optimizer->GetValue(); - - std::cout << "Registration done !" << std::endl; - std::cout << "Optimizer stop condition = " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - std::cout << "Number of iterations = " << numberOfIterations << std::endl; - std::cout << "Translation along X = " << TranslationAlongX << std::endl; - std::cout << "Translation along Y = " << TranslationAlongY << std::endl; - std::cout << "Optimal metric value = " << bestValue << std::endl; - - - // Prepare the resampling filter in order to map the moving image. - // - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - TransformType::Pointer finalTransform = TransformType::New(); - - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( 100 ); - - - // Prepare a writer and caster filters to send the resampled moving image to - // a file - // - using OutputPixelType = unsigned char; - - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - - writer->SetFileName( argv[3] ); - - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/ImageRegistration19.cxx b/Examples/RegistrationITKv3/ImageRegistration19.cxx deleted file mode 100644 index 36f13979fb3..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration19.cxx +++ /dev/null @@ -1,459 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -#include "itkImageRegistrationMethod.h" -#include "itkAffineTransform.h" -#include "itkMatchCardinalityImageToImageMetric.h" -#include "itkNearestNeighborInterpolateImageFunction.h" -#include "itkAmoebaOptimizer.h" -#include "itkCenteredTransformInitializer.h" - - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkSquaredDifferenceImageFilter.h" -#include "itkFileOutputWindow.h" - -// -// The following piece of code implements an observer -// that will monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate19 : public itk::Command -{ -public: - using Self = CommandIterationUpdate19; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate19() {}; - -public: - using OptimizerType = itk::AmoebaOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( ! itk::IterationEvent().CheckEvent( &event ) ) - { - return; - } - std::cout << optimizer->GetCachedValue() << " "; - std::cout << optimizer->GetCachedCurrentPosition() << std::endl; - } -}; - - -int main( int argc, char *argv[] ) -{ - if( argc < 3 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImagefile [differenceImage]" << std::endl; - std::cerr << " [initialTx] [initialTy]" << std::endl; - return EXIT_FAILURE; - } - - itk::FileOutputWindow::Pointer fow = itk::FileOutputWindow::New(); - fow->SetInstance( fow ); - - // The types of each one of the components in the registration methods should - // be instantiated. First, we select the image dimension and the type for - // representing image pixels. - // - constexpr unsigned int Dimension = 2; - using PixelType = float; - - - // The types of the input images are instantiated by the following lines. - // - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - using TransformType = itk::AffineTransform< double, Dimension >; - - using OptimizerType = itk::AmoebaOptimizer; - - using MetricType = itk::MatchCardinalityImageToImageMetric< - FixedImageType, - MovingImageType >; - - // Finally, the type of the interpolator is declared. The - // interpolator will evaluate the moving image at non-grid - // positions. - using InterpolatorType = itk:: NearestNeighborInterpolateImageFunction< - MovingImageType, - double >; - - // The registration method type is instantiated using the types of the - // fixed and moving images. This class is responsible for interconnecting - // all the components we have described so far. - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - // Each one of the registration components is created using its - // \code{New()} method and is assigned to its respective - // \doxygen{SmartPointer}. - // - MetricType::Pointer metric = MetricType::New(); - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - metric->MeasureMatchesOff(); - - - // Each component is now connected to the instance of the registration method. - // \index{itk::RegistrationMethod!SetMetric()} - // \index{itk::RegistrationMethod!SetOptimizer()} - // \index{itk::RegistrationMethod!SetTransform()} - // \index{itk::RegistrationMethod!SetFixedImage()} - // \index{itk::RegistrationMethod!SetMovingImage()} - // \index{itk::RegistrationMethod!SetInterpolator()} - // - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer - fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer - movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - - // In this example, the fixed and moving images are read from files. This - // requires the \doxygen{ImageRegistrationMethod} to acquire its inputs to - // the output of the readers. - // - registration->SetFixedImage( fixedImageReader->GetOutput() ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - - // The registration can be restricted to consider only a particular region - // of the fixed image as input to the metric computation. This region is - // defined by the \code{SetFixedImageRegion()} method. You could use this - // feature to reduce the computational time of the registration or to avoid - // unwanted objects present in the image affecting the registration outcome. - // In this example we use the full available content of the image. This - // region is identified by the \code{BufferedRegion} of the fixed image. - // Note that for this region to be valid the reader must first invoke its - // \code{Update()} method. - // - // \index{itk::ImageRegistrationMethod!SetFixedImageRegion()} - // \index{itk::Image!GetBufferedRegion()} - // - fixedImageReader->Update(); - movingImageReader->Update(); - - registration->SetFixedImageRegion( - fixedImageReader->GetOutput()->GetBufferedRegion() ); - - - // - // Here we initialize the transform to make sure that the center of - // rotation is set to the center of mass of the object in the fixed image. - // - using TransformInitializerType = itk::CenteredTransformInitializer< TransformType, - FixedImageType, MovingImageType >; - - TransformInitializerType::Pointer initializer = - TransformInitializerType::New(); - - initializer->SetTransform( transform ); - initializer->SetFixedImage( fixedImageReader->GetOutput() ); - initializer->SetMovingImage( movingImageReader->GetOutput() ); - - initializer->MomentsOn(); - initializer->InitializeTransform(); - - - // The parameters of the transform are initialized by passing them in an - // array. This can be used to setup an initial known correction of the - // misalignment. In this particular case, a translation transform is - // being used for the registration. The array of parameters for this - // transform is simply composed of the rotation matrix and the translation - // values along each dimension. - // - // \index{itk::AffineTransform!GetNumberOfParameters()} - // \index{itk::RegistrationMethod!SetInitialTransformParameters()} - // - using ParametersType = RegistrationType::ParametersType; - ParametersType initialParameters = transform->GetParameters(); - - double tx = 0.0; - double ty = 0.0; - - if( argc > 6 ) - { - tx = std::stod( argv[5] ); - ty = std::stod( argv[6] ); - } - - initialParameters[4] = tx; // Initial offset in mm along X - initialParameters[5] = ty; // Initial offset in mm along Y - - registration->SetInitialTransformParameters( initialParameters ); - - // At this point the registration method is ready for execution. The - // optimizer is the component that drives the execution of the - // registration. However, the ImageRegistrationMethod class - // orchestrates the ensemble to make sure that everything is in place - // before control is passed to the optimizer. - // - - const unsigned int numberOfParameters = transform->GetNumberOfParameters(); - - OptimizerType::ParametersType simplexDelta( numberOfParameters ); - - // This parameter is tightly coupled to the translationScale below - constexpr double stepInParametricSpace = 0.01; - - simplexDelta.Fill( stepInParametricSpace ); - - optimizer->AutomaticInitialSimplexOff(); - optimizer->SetInitialSimplexDelta( simplexDelta ); - - - optimizer->SetParametersConvergenceTolerance( 1e-4 ); // about 0.005 degrees - optimizer->SetFunctionConvergenceTolerance( 1e-6 ); // variation in metric value - - optimizer->SetMaximumNumberOfIterations( 200 ); - - - // This parameter is tightly coupled to the stepInParametricSpace above. - double translationScale = 1.0 / 1000.0; - - using OptimizerScalesType = OptimizerType::ScalesType; - OptimizerScalesType optimizerScales( numberOfParameters ); - - optimizerScales[0] = 1.0; - optimizerScales[1] = 1.0; - optimizerScales[2] = 1.0; - optimizerScales[3] = 1.0; - optimizerScales[4] = translationScale; - optimizerScales[5] = translationScale; - - optimizer->SetScales( optimizerScales ); - - - // - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate19::Pointer observer = CommandIterationUpdate19::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - - // The registration process is triggered by an invocation of the - // \code{Update()} method. If something goes wrong during the - // initialization or execution of the registration an exception will be - // thrown. We should therefore place the \code{Update()} method - // in a \code{try/catch} block as illustrated in the following lines. - // - try - { - // print out the initial metric value. need to initialize the - // registration method to force all the connections to be established. - registration->Initialize(); - std::cout << "Initial Metric value = " - << metric->GetValue( initialParameters ) - << std::endl; - - // run the registration - registration->Update(); - std::cout << "Optimizer stop condition = " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - // In a real application, you may attempt to recover from the error in the - // catch block. Here we are simply printing out a message and then - // terminating the execution of the program. - // - - // - // The result of the registration process is an array of parameters that - // defines the spatial transformation in an unique way. This final result is - // obtained using the \code{GetLastTransformParameters()} method. - // - // \index{itk::RegistrationMethod!GetLastTransformParameters()} - // - ParametersType finalParameters = registration->GetLastTransformParameters(); - - // In the case of the \doxygen{AffineTransform}, there is a straightforward - // interpretation of the parameters. The last two elements of the array - // corresponds to a translation along one spatial dimension. - // - const double TranslationAlongX = finalParameters[4]; - const double TranslationAlongY = finalParameters[5]; - - // The optimizer can be queried for the actual number of iterations - // performed to reach convergence. - // - const unsigned int numberOfIterations - = optimizer->GetOptimizer()->get_num_evaluations(); - - // The value of the image metric corresponding to the last set of parameters - // can be obtained with the \code{GetValue()} method of the optimizer. Since - // the AmoebaOptimizer does not yet support a call to GetValue(), we will - // simply re-evaluate the metric at the final parameters. - // - const double bestValue = metric->GetValue(finalParameters); - - // Print out results - // - std::cout << "Result = " << std::endl; - std::cout << " Translation X = " << TranslationAlongX << std::endl; - std::cout << " Translation Y = " << TranslationAlongY << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - - // It is common, as the last step of a registration task, to use the - // resulting transform to map the moving image into the fixed image space. - // This is easily done with the \doxygen{ResampleImageFilter}. Please - // refer to Section~\ref{sec:ResampleImageFilter} for details on the use - // of this filter. First, a ResampleImageFilter type is instantiated - // using the image types. It is convenient to use the fixed image type as - // the output type since it is likely that the transformed moving image - // will be compared with the fixed image. - // - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - // A transform of the same type used in the registration process should be - // created and initialized with the parameters resulting from the - // registration process. - // - // \index{itk::ImageRegistrationMethod!Resampling image} - // - TransformType::Pointer finalTransform = TransformType::New(); - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - std::cout << "Final Transform " << std::endl; - finalTransform->Print( std::cout ); - - // Then a resampling filter is created and the corresponding transform and - // moving image connected as inputs. - // - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - - // As described in Section \ref{sec:ResampleImageFilter}, the - // ResampleImageFilter requires additional parameters to be - // specified, in particular, the spacing, origin and size of the output - // image. The default pixel value is also set to the standard label - // for "unknown" or background. Finally, we need to set the - // interpolator to be the same type of interpolator as the - // registration method used (nearest neighbor). - // - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( 0 ); - resample->SetInterpolator( interpolator ); - - // The output of the filter is passed to a writer that will store the - // image in a file. An \doxygen{CastImageFilter} is used to convert the - // pixel type of the resampled image to the final type used by the - // writer. The cast and writer filters are instantiated below. - // - using OutputPixelType = unsigned short; - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - using WriterType = itk::ImageFileWriter< OutputImageType >; - - // The filters are created by invoking their \code{New()} - // method. - // - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - - writer->SetFileName( argv[3] ); - - - // The \code{Update()} method of the writer is invoked in order to trigger - // the execution of the pipeline. - // - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - - // - // The fixed image and the transformed moving image can easily be compared - // using the \code{SquaredDifferenceImageFilter}. This pixel-wise - // filter computes the squared value of the difference between homologous - // pixels of its input images. - // - using DifferenceFilterType = itk::SquaredDifferenceImageFilter< - FixedImageType, - FixedImageType, - OutputImageType >; - - DifferenceFilterType::Pointer difference = DifferenceFilterType::New(); - difference->SetInput1( fixedImageReader->GetOutput() ); - difference->SetInput2( resample->GetOutput() ); - - // Its output can be passed to another writer. - // - WriterType::Pointer writer2 = WriterType::New(); - writer2->SetInput( difference->GetOutput() ); - - if( argc > 4 ) - { - writer2->SetFileName( argv[4] ); - writer2->Update(); - } - - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/ImageRegistration2.cxx b/Examples/RegistrationITKv3/ImageRegistration2.cxx deleted file mode 100644 index ec69391c7bd..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration2.cxx +++ /dev/null @@ -1,691 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginCommandLineArgs -// INPUTS: {BrainT1SliceBorder20.png} -// INPUTS: {BrainProtonDensitySliceShifted13x17y.png} -// OUTPUTS: {ImageRegistration2Output.png} -// OUTPUTS: {ImageRegistration2CheckerboardBefore.png} -// OUTPUTS: {ImageRegistration2CheckerboardAfter.png} -// Software Guide : EndCommandLineArgs - -// Software Guide : BeginLatex -// -// The following simple example illustrates how multiple imaging modalities can -// be registered using the ITK registration framework. The first difference -// between this and previous examples is the use of the -// \doxygen{MutualInformationImageToImageMetric} as the cost-function to be -// optimized. The second difference is the use of the -// \doxygen{GradientDescentOptimizer}. Due to the stochastic nature of the -// metric computation, the values are too noisy to work successfully with the -// \doxygen{RegularStepGradientDescentOptimizer}. Therefore, we will use the -// simpler GradientDescentOptimizer with a user defined learning rate. The -// following headers declare the basic components of this registration method. -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet -#include "itkImageRegistrationMethod.h" -#include "itkTranslationTransform.h" -#include "itkMutualInformationImageToImageMetric.h" -#include "itkGradientDescentOptimizer.h" -// Software Guide : EndCodeSnippet - -#include "itkMersenneTwisterRandomVariateGenerator.h" - - -// Software Guide : BeginLatex -// -// One way to simplify the computation of the mutual information is -// to normalize the statistical distribution of the two input images. The -// \doxygen{NormalizeImageFilter} is the perfect tool for this task. -// It rescales the intensities of the input images in order to produce an -// output image with zero mean and unit variance. This filter has been -// discussed in Section \ref{sec:CastingImageFilters}. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkNormalizeImageFilter.h" -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Additionally, low-pass filtering of the images to be registered will also -// increase robustness against noise. In this example, we will use the -// \doxygen{DiscreteGaussianImageFilter} for that purpose. The -// characteristics of this filter have been discussed in Section -// \ref{sec:BlurringFilters}. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkDiscreteGaussianImageFilter.h" -// Software Guide : EndCodeSnippet - - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkCheckerBoardImageFilter.h" - - -// The following section of code implements a Command observer -// that will monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - using OptimizerType = itk::GradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( ! itk::IterationEvent().CheckEvent( &event ) ) - { - return; - } - std::cout << optimizer->GetCurrentIteration() << " "; - std::cout << optimizer->GetValue() << " "; - std::cout << optimizer->GetCurrentPosition() << std::endl; - } -}; - - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << "outputImagefile "; - std::cerr << "[checkerBoardBefore] [checkerBoardAfter]" << std::endl; - return EXIT_FAILURE; - } - - // Software Guide : BeginLatex - // - // The moving and fixed images types should be instantiated first. - // - // Software Guide : EndLatex - // - // Software Guide : BeginCodeSnippet - constexpr unsigned int Dimension = 2; - using PixelType = unsigned short; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // It is convenient to work with an internal image type because mutual - // information will perform better on images with a normalized statistical - // distribution. The fixed and moving images will be normalized and - // converted to this internal type. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using InternalPixelType = float; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The rest of the image registration components are instantiated as - // illustrated in Section \ref{sec:IntroductionImageRegistration} with - // the use of the \code{InternalImageType}. - // - // Software Guide : EndLatex - - - // Software Guide : BeginCodeSnippet - using TransformType = itk::TranslationTransform< double, Dimension >; - using OptimizerType = itk::GradientDescentOptimizer; - using InterpolatorType = itk::LinearInterpolateImageFunction< - InternalImageType, - double >; - using RegistrationType = itk::ImageRegistrationMethod< - InternalImageType, - InternalImageType >; - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The mutual information metric type is instantiated using the image - // types. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using MetricType = itk::MutualInformationImageToImageMetric< - InternalImageType, - InternalImageType >; - // Software Guide : EndCodeSnippet - - - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - - - // Software Guide : BeginLatex - // - // The metric is created using the \code{New()} method and then - // connected to the registration object. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - MetricType::Pointer metric = MetricType::New(); - registration->SetMetric( metric ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The metric requires a number of parameters to be selected, including - // the standard deviation of the Gaussian kernel for the fixed image - // density estimate, the standard deviation of the kernel for the moving - // image density and the number of samples use to compute the densities - // and entropy values. Details on the concepts behind the computation of - // the metric can be found in Section - // \ref{sec:MutualInformationMetric}. Experience has - // shown that a kernel standard deviation of $0.4$ works well for images - // which have been normalized to a mean of zero and unit variance. We - // will follow this empirical rule in this example. - // - // \index{itk::Mutual\-Information\-Image\-To\-Image\-Metric!SetFixedImageStandardDeviation()} - // \index{itk::Mutual\-Information\-Image\-To\-Image\-Metric!SetMovingImageStandardDeviation()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - metric->SetFixedImageStandardDeviation( 0.4 ); - metric->SetMovingImageStandardDeviation( 0.4 ); - // Software Guide : EndCodeSnippet - - // For consistent results when regression testing. - metric->ReinitializeSeed( 121212 ); - - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - - // Software Guide : BeginLatex - // - // The normalization filters are instantiated using the fixed and moving - // image types as input and the internal image type as output. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using FixedNormalizeFilterType = itk::NormalizeImageFilter< - FixedImageType, InternalImageType >; - - using MovingNormalizeFilterType = itk::NormalizeImageFilter< - MovingImageType, InternalImageType >; - - FixedNormalizeFilterType::Pointer fixedNormalizer = - FixedNormalizeFilterType::New(); - - MovingNormalizeFilterType::Pointer movingNormalizer = - MovingNormalizeFilterType::New(); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The blurring filters are declared using the internal image type as both - // the input and output types. In this example, we will set the variance - // for both blurring filters to $2.0$. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using GaussianFilterType = itk::DiscreteGaussianImageFilter< - InternalImageType, InternalImageType>; - - GaussianFilterType::Pointer fixedSmoother = GaussianFilterType::New(); - GaussianFilterType::Pointer movingSmoother = GaussianFilterType::New(); - - fixedSmoother->SetVariance( 2.0 ); - movingSmoother->SetVariance( 2.0 ); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The output of the readers becomes the input to the normalization - // filters. The output of the normalization filters is connected as - // input to the blurring filters. The input to the registration method - // is taken from the blurring filters. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - fixedNormalizer->SetInput( fixedImageReader->GetOutput() ); - movingNormalizer->SetInput( movingImageReader->GetOutput() ); - - fixedSmoother->SetInput( fixedNormalizer->GetOutput() ); - movingSmoother->SetInput( movingNormalizer->GetOutput() ); - - registration->SetFixedImage( fixedSmoother->GetOutput() ); - registration->SetMovingImage( movingSmoother->GetOutput() ); - // Software Guide : EndCodeSnippet - - - fixedNormalizer->Update(); - FixedImageType::RegionType fixedImageRegion = - fixedNormalizer->GetOutput()->GetBufferedRegion(); - registration->SetFixedImageRegion( fixedImageRegion ); - - using ParametersType = RegistrationType::ParametersType; - ParametersType initialParameters( transform->GetNumberOfParameters() ); - - initialParameters[0] = 0.0; // Initial offset in mm along X - initialParameters[1] = 0.0; // Initial offset in mm along Y - - registration->SetInitialTransformParameters( initialParameters ); - - // Software Guide : BeginLatex - // - // We should now define the number of spatial samples to be considered in - // the metric computation. Note that we were forced to postpone this setting - // until we had done the preprocessing of the images because the number of - // samples is usually defined as a fraction of the total number of pixels in - // the fixed image. - // - // The number of spatial samples can usually be as low as $1\%$ of the total - // number of pixels in the fixed image. Increasing the number of samples - // improves the smoothness of the metric from one iteration to another and - // therefore helps when this metric is used in conjunction with optimizers - // that rely of the continuity of the metric values. The trade-off, of - // course, is that a larger number of samples result in longer computation - // times per every evaluation of the metric. - // - // It has been demonstrated empirically that the number of samples is not a - // critical parameter for the registration process. When you start fine - // tuning your own registration process, you should start using high values - // of number of samples, for example in the range of $20\%$ to $50\%$ of the - // number of pixels in the fixed image. Once you have succeeded to register - // your images you can then reduce the number of samples progressively until - // you find a good compromise on the time it takes to compute one evaluation - // of the Metric. Note that it is not useful to have very fast evaluations - // of the Metric if the noise in their values results in more iterations - // being required by the optimizer to converge. You must then study the - // behavior of the metric values as the iterations progress, just as - // illustrated in section~\ref{sec:MonitoringImageRegistration}. - // - // \index{itk::Mutual\-Information\-Image\-To\-Image\-Metric!SetNumberOfSpatialSamples()} - // \index{itk::Mutual\-Information\-Image\-To\-Image\-Metric!Trade-offs} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - const unsigned int numberOfPixels = fixedImageRegion.GetNumberOfPixels(); - - const unsigned int numberOfSamples = - static_cast< unsigned int >( numberOfPixels * 0.01 ); - - metric->SetNumberOfSpatialSamples( numberOfSamples ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Since larger values of mutual information indicate better matches than - // smaller values, we need to maximize the cost function in this example. - // By default the GradientDescentOptimizer class is set to minimize the - // value of the cost-function. It is therefore necessary to modify its - // default behavior by invoking the \code{MaximizeOn()} method. - // Additionally, we need to define the optimizer's step size using the - // \code{SetLearningRate()} method. - // - // \index{itk::Gradient\-Descent\-Optimizer!MaximizeOn()} - // \index{itk::Image\-Registration\-Method!Maximize vs Minimize} - // - // Software Guide : EndLatex - - - // Software Guide : BeginCodeSnippet - optimizer->SetLearningRate( 15.0 ); - optimizer->SetNumberOfIterations( 200 ); - optimizer->MaximizeOn(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Note that large values of the learning rate will make the optimizer - // unstable. Small values, on the other hand, may result in the optimizer - // needing too many iterations in order to walk to the extrema of the cost - // function. The easy way of fine tuning this parameter is to start with - // small values, probably in the range of $\{5.0,10.0\}$. Once the other - // registration parameters have been tuned for producing convergence, you - // may want to revisit the learning rate and start increasing its value until - // you observe that the optimization becomes unstable. The ideal value for - // this parameter is the one that results in a minimum number of iterations - // while still keeping a stable path on the parametric space of the - // optimization. Keep in mind that this parameter is a multiplicative factor - // applied on the gradient of the Metric. Therefore, its effect on the - // optimizer step length is proportional to the Metric values themselves. - // Metrics with large values will require you to use smaller values for the - // learning rate in order to maintain a similar optimizer behavior. - // - // Software Guide : EndLatex - - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - ParametersType finalParameters = registration->GetLastTransformParameters(); - - double TranslationAlongX = finalParameters[0]; - double TranslationAlongY = finalParameters[1]; - - unsigned int numberOfIterations = optimizer->GetCurrentIteration(); - - double bestValue = optimizer->GetValue(); - - - // Print out results - // - std::cout << std::endl; - std::cout << "Result = " << std::endl; - std::cout << " Translation X = " << TranslationAlongX << std::endl; - std::cout << " Translation Y = " << TranslationAlongY << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - std::cout << " Numb. Samples = " << numberOfSamples << std::endl; - - - // Software Guide : BeginLatex - // - // Let's execute this example over two of the images provided in - // \code{Examples/Data}: - // - // \begin{itemize} - // \item \code{BrainT1SliceBorder20.png} - // \item \code{BrainProtonDensitySliceShifted13x17y.png} - // \end{itemize} - // - // \begin{figure} - // \center - // \includegraphics[width=0.44\textwidth]{BrainT1SliceBorder20} - // \includegraphics[width=0.44\textwidth]{BrainProtonDensitySliceShifted13x17y} - // \itkcaption[Multi-Modality Registration Inputs]{A T1 MRI (fixed image) and a proton - // density MRI (moving image) are provided as input to the registration method.} - // \label{fig:FixedMovingImageRegistration2} - // \end{figure} - // - // The second image is the result of intentionally translating the image - // \code{Brain\-Proton\-Density\-Slice\-Border20.png} by $(13,17)$ - // millimeters. Both images have unit-spacing and are shown in Figure - // \ref{fig:FixedMovingImageRegistration2}. The registration is stopped at - // 200 iterations and produces as result the parameters: - // - // \begin{verbatim} - // Translation X = 12.9147 - // Translation Y = 17.0871 - // \end{verbatim} - // These values are approximately within one tenth of a pixel from the true - // misalignment introduced in the moving image. - // - // Software Guide : EndLatex - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - TransformType::Pointer finalTransform = TransformType::New(); - - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( 100 ); - - - using OutputPixelType = unsigned char; - - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - - writer->SetFileName( argv[3] ); - - - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - - // Generate checkerboards before and after registration - // - using CheckerBoardFilterType = itk::CheckerBoardImageFilter< FixedImageType >; - - CheckerBoardFilterType::Pointer checker = CheckerBoardFilterType::New(); - - checker->SetInput1( fixedImage ); - checker->SetInput2( resample->GetOutput() ); - - caster->SetInput( checker->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - - // Before registration - TransformType::Pointer identityTransform = TransformType::New(); - identityTransform->SetIdentity(); - resample->SetTransform( identityTransform ); - - if( argc > 4 ) - { - writer->SetFileName( argv[4] ); - writer->Update(); - } - - - // After registration - resample->SetTransform( finalTransform ); - if( argc > 5 ) - { - writer->SetFileName( argv[5] ); - writer->Update(); - } - - - // Software Guide : BeginLatex - // - // \begin{figure} - // \center - // \includegraphics[width=0.32\textwidth]{ImageRegistration2Output} - // \includegraphics[width=0.32\textwidth]{ImageRegistration2CheckerboardBefore} - // \includegraphics[width=0.32\textwidth]{ImageRegistration2CheckerboardAfter} - // \itkcaption[Multi-Modality Registration outputs]{Mapped moving image (left) - // and composition of fixed and moving images before (center) and after - // (right) registration.} - // \label{fig:ImageRegistration2Output} - // \end{figure} - // - // The moving image after resampling is presented on the left - // side of Figure \ref{fig:ImageRegistration2Output}. The center and right - // figures present a checkerboard composite of the fixed and - // moving images before and after registration. - // - // Software Guide : EndLatex - - // Software Guide : BeginLatex - // - // \begin{figure} - // \center - // \includegraphics[width=0.44\textwidth]{ImageRegistration2TraceTranslations} - // \includegraphics[width=0.44\textwidth]{ImageRegistration2TraceTranslations2} - // \itkcaption[Multi-Modality Registration plot of translations]{Sequence of - // translations during the registration process. On the left are iterations 0 to - // 200. On the right are iterations 150 to 200.} - // \label{fig:ImageRegistration2TraceTranslations} - // \end{figure} - // - // Figure \ref{fig:ImageRegistration2TraceTranslations} shows the sequence - // of translations followed by the optimizer as it searched the parameter - // space. The left plot shows iterations $0$ to $200$ while the right - // figure zooms into iterations $150$ to $200$. The area covered by the - // right figure has been highlighted by a rectangle in the left image. It - // can be seen that after a certain number of iterations the optimizer - // oscillates within one or two pixels of the true solution. At this - // point it is clear that more iterations will not help. Instead it is - // time to modify some of the parameters of the registration process, for - // example, reducing the learning rate of the optimizer and continuing the - // registration so that smaller steps are taken. - // - // \begin{figure} - // \center - // \includegraphics[width=0.44\textwidth]{ImageRegistration2TraceMetric} - // \includegraphics[width=0.44\textwidth]{ImageRegistration2TraceMetric2} - // \itkcaption[Multi-Modality Registration plot of metrics]{The sequence of metric - // values produced during the registration process. On the left are - // iterations 0 to 200. On the right are iterations 150 to 200.} - // \label{fig:ImageRegistration2TraceMetric} - // \end{figure} - // - // Figure \ref{fig:ImageRegistration2TraceMetric} shows the sequence of - // metric values computed as the optimizer searched the parameter space. - // The left plot shows values when iterations are extended from $0$ to - // $200$ while the right figure zooms into iterations $150$ to $200$. The - // fluctuations in the metric value are due to the stochastic nature in - // which the measure is computed. At each call of \code{GetValue()}, two - // new sets of intensity samples are randomly taken from the image to - // compute the density and entropy estimates. Even with the fluctuations, - // the measure initially increases overall with the number of iterations. - // After about 150 iterations, the metric value merely oscillates without further - // noticeable convergence. The trace plots in Figure - // \ref{fig:ImageRegistration2TraceMetric} highlight one of the - // difficulties associated with this particular metric: the stochastic - // oscillations make it difficult to determine convergence and limit the - // use of more sophisticated optimization methods. As explained above, - // the reduction of the learning rate as the registration progresses is - // very important in order to get precise results. - // - // This example shows the importance of tracking the evolution of the - // registration method in order to obtain insight into the characteristics - // of the particular problem at hand and the components being used. The - // behavior revealed by these plots usually helps to identify possible - // improvements in the setup of the registration parameters. - // - // The plots in Figures~\ref{fig:ImageRegistration2TraceTranslations} - // and~\ref{fig:ImageRegistration2TraceMetric} were generated using - // Gnuplot\footnote{\url{http://www.gnuplot.info/}}. The scripts used for - // this purpose are available in the \code{ITKSoftwareGuide} Git repository - // under the directory - // - // ~\code{ITKSoftwareGuide/SoftwareGuide/Art}. - // - // Data for the plots was taken directly from the output that the - // Command/Observer in this example prints out to the console. The output - // was processed with the UNIX editor - // \code{sed}\footnote{\url{http://www.gnu.org/software/sed/sed.html}} in - // order to remove commas and brackets that were confusing for Gnuplot's - // parser. Both the shell script for running \code{sed} and for running - // {Gnuplot} are available in the directory indicated above. You may find - // useful to run them in order to verify the results presented here, and to - // eventually modify them for profiling your own registrations. - // - // \index{Open Science} - // - // Open Science is not just an abstract concept. Open Science is something - // to be practiced every day with the simple gesture of sharing information - // with your peers, and by providing all the tools that they need for - // replicating the results that you are reporting. In Open Science, the only - // bad results are those that can not be - // replicated\footnote{\url{http://science.creativecommons.org/}}. Science - // is dead when people blindly trust authorities~\footnote{For example: - // Reviewers of Scientific Journals.} instead of verifying their statements - // by performing their own experiments ~\cite{Popper1971,Popper2002}. - // - // Software Guide : EndLatex - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/ImageRegistration20.cxx b/Examples/RegistrationITKv3/ImageRegistration20.cxx deleted file mode 100644 index 65948bc40db..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration20.cxx +++ /dev/null @@ -1,468 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginCommandLineArgs -// INPUTS: {brainweb1e1a10f20.mha} -// INPUTS: {brainweb1e1a10f20Rot10Tx15.mha} -// ARGUMENTS: ImageRegistration20Output.mhd -// Software Guide : EndCommandLineArgs - -// Software Guide : BeginLatex -// -// This example illustrates the use of the \doxygen{AffineTransform} -// for performing registration in $3D$. -// -// \index{itk::AffineTransform} -// -// Software Guide : EndLatex - -#include "itkImageRegistrationMethod.h" -#include "itkMeanSquaresImageToImageMetric.h" -#include "itkRegularStepGradientDescentOptimizer.h" -#include "itkCenteredTransformInitializer.h" - -// Software Guide : BeginLatex -// -// Let's start by including the header file of the AffineTransform. -// -// \index{itk::AffineTransform!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkAffineTransform.h" -// Software Guide : EndCodeSnippet - - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkSubtractImageFilter.h" -#include "itkRescaleIntensityImageFilter.h" - - -// -// The following piece of code implements an observer -// that will monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( ! itk::IterationEvent().CheckEvent( &event ) ) - { - return; - } - std::cout << optimizer->GetCurrentIteration() << " "; - std::cout << optimizer->GetValue() << " "; - std::cout << optimizer->GetCurrentPosition() << std::endl; - } -}; - - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile " << std::endl; - std::cerr << " outputImagefile [differenceBeforeRegistration] " << std::endl; - std::cerr << " [differenceAfterRegistration] " << std::endl; - std::cerr << " [stepLength] [maxNumberOfIterations] "<< std::endl; - return EXIT_FAILURE; - } - - - // Software Guide : BeginLatex - // - // We define then the types of the images to be registered. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - constexpr unsigned int Dimension = 3; - using PixelType = float; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The transform type is instantiated using the code below. The template - // parameters of this class are the representation type of the space - // coordinates and the space dimension. - // - // \index{itk::AffineTransform!Instantiation} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using TransformType = itk::AffineTransform< - double, - Dimension >; - // Software Guide : EndCodeSnippet - - - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using MetricType = itk::MeanSquaresImageToImageMetric< - FixedImageType, - MovingImageType >; - using InterpolatorType = itk:: LinearInterpolateImageFunction< - MovingImageType, - double >; - using RegistrationType = itk::ImageRegistrationMethod< - FixedImageType, - MovingImageType >; - - MetricType::Pointer metric = MetricType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetInterpolator( interpolator ); - - - // Software Guide : BeginLatex - // - // The transform object is constructed below and passed to the registration - // method. - // - // \index{itk::AffineTransform!New()} - // \index{itk::AffineTransform!Pointer} - // \index{itk::RegistrationMethod!SetTransform()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - TransformType::Pointer transform = TransformType::New(); - registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet - - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - - registration->SetFixedImage( fixedImageReader->GetOutput() ); - registration->SetMovingImage( movingImageReader->GetOutput() ); - fixedImageReader->Update(); - - registration->SetFixedImageRegion( - fixedImageReader->GetOutput()->GetBufferedRegion() ); - - - // Software Guide : BeginLatex - // - // In this example, we again use the - // \doxygen{CenteredTransformInitializer} helper class in order to compute - // a reasonable value for the initial center of rotation and the - // translation. The initializer is set to use the center of mass of each - // image as the initial correspondence correction. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using TransformInitializerType = itk::CenteredTransformInitializer< - TransformType, FixedImageType, - MovingImageType >; - TransformInitializerType::Pointer initializer - = TransformInitializerType::New(); - initializer->SetTransform( transform ); - initializer->SetFixedImage( fixedImageReader->GetOutput() ); - initializer->SetMovingImage( movingImageReader->GetOutput() ); - initializer->MomentsOn(); - initializer->InitializeTransform(); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Now we pass the parameters of the current transform as the initial - // parameters to be used when the registration process starts. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - registration->SetInitialTransformParameters( - transform->GetParameters() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Keeping in mind that the scale of units in scaling, rotation and - // translation are quite different, we take advantage of the scaling - // functionality provided by the optimizers. We know that the first $N - // \times N$ elements of the parameters array correspond to the rotation - // matrix factor, and the last $N$ are the components of the translation to - // be applied after multiplication with the matrix is performed. - // - // Software Guide : EndLatex - - double translationScale = 1.0 / 1000.0; - if( argc > 8 ) - { - translationScale = std::stod( argv[8] ); - } - - // Software Guide : BeginCodeSnippet - using OptimizerScalesType = OptimizerType::ScalesType; - OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() ); - optimizerScales[0] = 1.0; - optimizerScales[1] = 1.0; - optimizerScales[2] = 1.0; - optimizerScales[3] = 1.0; - optimizerScales[4] = 1.0; - optimizerScales[5] = 1.0; - optimizerScales[6] = 1.0; - optimizerScales[7] = 1.0; - optimizerScales[8] = 1.0; - optimizerScales[9] = translationScale; - optimizerScales[10] = translationScale; - optimizerScales[11] = translationScale; - optimizer->SetScales( optimizerScales ); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // We also set the usual parameters of the optimization method. In this - // case we are using an - // \doxygen{RegularStepGradientDescentOptimizer}. Below, we define the - // optimization parameters like initial step length, minimal step length - // and number of iterations. These last two act as stopping criteria for - // the optimization. - // - // Software Guide : EndLatex - - double steplength = 0.1; - if( argc > 6 ) - { - steplength = std::stod( argv[6] ); - } - unsigned int maxNumberOfIterations = 300; - if( argc > 7 ) - { - maxNumberOfIterations = std::stoi( argv[7] ); - } - // Software Guide : BeginCodeSnippet - optimizer->SetMaximumStepLength( steplength ); - optimizer->SetMinimumStepLength( 0.0001 ); - optimizer->SetNumberOfIterations( maxNumberOfIterations ); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // We also set the optimizer to do minimization by calling the - // \code{MinimizeOn()} method. - // - // \index{itk::Regular\-Step\-Gradient\-Descent\-Optimizer!MinimizeOn()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->MinimizeOn(); - // Software Guide : EndCodeSnippet - - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - // Software Guide : BeginLatex - // - // Finally we trigger the execution of the registration method by calling - // the \code{Update()} method. The call is placed in a \code{try/catch} - // block in case any exceptions are thrown. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Once the optimization converges, we recover the parameters from the - // registration method. This is done with the - // \code{GetLastTransformParameters()} method. We can also recover the - // final value of the metric with the \code{GetValue()} method and the - // final number of iterations with the \code{GetCurrentIteration()} - // method. - // - // \index{itk::RegistrationMethod!GetValue()} - // \index{itk::RegistrationMethod!GetCurrentIteration()} - // \index{itk::RegistrationMethod!GetLastTransformParameters()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - OptimizerType::ParametersType finalParameters = - registration->GetLastTransformParameters(); - - const unsigned int numberOfIterations = optimizer->GetCurrentIteration(); - const double bestValue = optimizer->GetValue(); - // Software Guide : EndCodeSnippet - - - // Print out results - // - std::cout << "Result = " << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - - - // The following code is used to dump output images to files. - // They illustrate the final results of the registration. - // We will resample the moving image and write out the difference image - // before and after registration. We will also rescale the intensities of the - // difference images, so that they look better! - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - TransformType::Pointer finalTransform = TransformType::New(); - - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - ResampleFilterType::Pointer resampler = ResampleFilterType::New(); - - resampler->SetTransform( finalTransform ); - resampler->SetInput( movingImageReader->GetOutput() ); - - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - resampler->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resampler->SetOutputOrigin( fixedImage->GetOrigin() ); - resampler->SetOutputSpacing( fixedImage->GetSpacing() ); - resampler->SetOutputDirection( fixedImage->GetDirection() ); - resampler->SetDefaultPixelValue( 100 ); - - using OutputPixelType = unsigned char; - - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - - writer->SetFileName( argv[3] ); - - - caster->SetInput( resampler->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - - using DifferenceFilterType = itk::SubtractImageFilter< - FixedImageType, - FixedImageType, - FixedImageType >; - - DifferenceFilterType::Pointer difference = DifferenceFilterType::New(); - - difference->SetInput1( fixedImageReader->GetOutput() ); - difference->SetInput2( resampler->GetOutput() ); - - WriterType::Pointer writer2 = WriterType::New(); - - using RescalerType = itk::RescaleIntensityImageFilter< - FixedImageType, - OutputImageType >; - - RescalerType::Pointer intensityRescaler = RescalerType::New(); - - intensityRescaler->SetInput( difference->GetOutput() ); - intensityRescaler->SetOutputMinimum( 0 ); - intensityRescaler->SetOutputMaximum( 255 ); - - writer2->SetInput( intensityRescaler->GetOutput() ); - resampler->SetDefaultPixelValue( 1 ); - - // Compute the difference image between the - // fixed and resampled moving image. - if( argc > 5 ) - { - writer2->SetFileName( argv[5] ); - writer2->Update(); - } - - - using IdentityTransformType = itk::IdentityTransform< double, Dimension >; - IdentityTransformType::Pointer identity = IdentityTransformType::New(); - - // Compute the difference image between the - // fixed and moving image before registration. - if( argc > 4 ) - { - resampler->SetTransform( identity ); - writer2->SetFileName( argv[4] ); - writer2->Update(); - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/ImageRegistration3.py b/Examples/RegistrationITKv3/ImageRegistration3.py deleted file mode 100644 index da0e9237465..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration3.py +++ /dev/null @@ -1,153 +0,0 @@ -#========================================================================== -# -# Copyright Insight Software Consortium -# -# 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. -# -#==========================================================================*/ - -import itk -from sys import argv - - -# -# Check input parameters -# INPUTS(fixedImage): {BrainProtonDensitySliceBorder20.png} -# INPUTS(movingImage): {BrainProtonDensitySliceShifted13x17y.png} -# -if len(argv) < 4: - print 'Missing Parameters' - print 'Usage: ImageRegistration3.py fixedImageFile movingImageFile outputImagefile' - exit() - - -# -# Define data types -# -FixedImageType = itk.Image[itk.F, 2] -MovingImageType = itk.Image[itk.F, 2] -OutputImageType = itk.Image[itk.UC, 2] -TransformType = itk.TranslationTransform[itk.D, 2] - - -# -# Read the fixed and moving images using filenames -# from the command line arguments -# -fixedImageReader = itk.ImageFileReader[FixedImageType].New() -movingImageReader = itk.ImageFileReader[MovingImageType].New() - -fixedImageReader.SetFileName( argv[1] ) -movingImageReader.SetFileName( argv[2] ) - -fixedImageReader.Update() -movingImageReader.Update() - -fixedImage = fixedImageReader.GetOutput() -movingImage = movingImageReader.GetOutput() - - -# -# Instantiate the classes for the registration framework -# -registration = itk.ImageRegistrationMethod[FixedImageType, MovingImageType].New() -imageMetric = itk.MeanSquaresImageToImageMetric[FixedImageType, MovingImageType].New() -transform = TransformType.New() -optimizer = itk.RegularStepGradientDescentOptimizer.New() -interpolator = itk.LinearInterpolateImageFunction[FixedImageType, itk.D].New() - -registration.SetOptimizer( optimizer ) -registration.SetTransform( transform ) -registration.SetInterpolator( interpolator ) -registration.SetMetric( imageMetric ) - -registration.SetFixedImage( fixedImage ) -registration.SetMovingImage( movingImage ) - -registration.SetFixedImageRegion( fixedImage.GetBufferedRegion() ) - -transform.SetIdentity() -initialParameters = transform.GetParameters() - -registration.SetInitialTransformParameters( initialParameters ) - - -# -# Iteration Observer -# -def iterationUpdate(): - currentParameter = transform.GetParameters() - print "M: %f P: %f %f " % ( optimizer.GetValue(), - currentParameter.GetElement(0), - currentParameter.GetElement(1) ) - -iterationCommand = itk.PyCommand.New() -iterationCommand.SetCommandCallable( iterationUpdate ) -optimizer.AddObserver( itk.IterationEvent(), iterationCommand ) - - -# -# Define optimizer parameters -# -optimizer.SetMaximumStepLength( 4.00 ) -optimizer.SetMinimumStepLength( 0.01 ) -optimizer.SetNumberOfIterations( 200 ) - -print "Starting registration" - - -# -# Start the registration process -# -registration.Update() - - -# -# Get the final parameters of the transformation -# -finalParameters = registration.GetLastTransformParameters() - -print "Final Registration Parameters " -print "Translation X = %f" % (finalParameters.GetElement(0),) -print "Translation Y = %f" % (finalParameters.GetElement(1),) - - -# -# Now, we use the final transform for resampling the -# moving image. -# -resampler = itk.ResampleImageFilter[MovingImageType, FixedImageType].New() -resampler.SetTransform( transform ) -resampler.SetInput( movingImage ) - -region = fixedImage.GetLargestPossibleRegion() - -resampler.SetSize( region.GetSize() ) - -resampler.SetOutputSpacing( fixedImage.GetSpacing() ) -resampler.SetOutputOrigin( fixedImage.GetOrigin() ) -resampler.SetOutputDirection( fixedImage.GetDirection() ) -resampler.SetDefaultPixelValue( 100 ) - -outputCast = itk.RescaleIntensityImageFilter[FixedImageType, OutputImageType].New() -outputCast.SetInput(resampler.GetOutput()) - - -# -# Write the resampled image -# -writer = itk.ImageFileWriter[OutputImageType].New() - -writer.SetFileName( argv[3] ) -writer.SetInput( outputCast.GetOutput() ) -writer.Update() diff --git a/Examples/RegistrationITKv3/ImageRegistration4.py b/Examples/RegistrationITKv3/ImageRegistration4.py deleted file mode 100644 index 187ecae5729..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration4.py +++ /dev/null @@ -1,156 +0,0 @@ -#========================================================================== -# -# Copyright Insight Software Consortium -# -# 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. -# -#==========================================================================*/ - -import itk -from sys import argv - - -# -# Check input parameters -# INPUTS(fixedImage): {BrainProtonDensitySliceBorder20.png} -# INPUTS(movingImage): {BrainProtonDensitySliceShifted13x17y.png} -# -if len(argv) < 4: - print 'Missing Parameters' - print 'Usage: ImageRegistration4.py fixedImageFile movingImageFile outputImagefile' - exit() - - -# -# Define data types -# -FixedImageType = itk.Image[itk.F, 2] -MovingImageType = itk.Image[itk.F, 2] -OutputImageType = itk.Image[itk.UC,2] -TransformType = itk.TranslationTransform[itk.D, 2] - - -# -# Read the fixed and moving images using filenames -# from the command line arguments -# -fixedImageReader = itk.ImageFileReader[FixedImageType].New() -movingImageReader = itk.ImageFileReader[MovingImageType].New() - -fixedImageReader.SetFileName( argv[1] ) -movingImageReader.SetFileName( argv[2] ) - -fixedImageReader.Update() -movingImageReader.Update() - -fixedImage = fixedImageReader.GetOutput() -movingImage = movingImageReader.GetOutput() - - -# -# Instantiate the classes for the registration framework -# -registration = itk.ImageRegistrationMethod[FixedImageType, MovingImageType].New() -imageMetric = itk.MattesMutualInformationImageToImageMetric[FixedImageType, MovingImageType].New() -transform = TransformType.New() -optimizer = itk.RegularStepGradientDescentOptimizer.New() -interpolator = itk.LinearInterpolateImageFunction[FixedImageType, itk.D].New() - -imageMetric.SetNumberOfHistogramBins( 20 ); -imageMetric.SetNumberOfSpatialSamples( 10000 ); - -registration.SetOptimizer( optimizer ) -registration.SetTransform( transform ) -registration.SetInterpolator( interpolator ) -registration.SetMetric( imageMetric ) - -registration.SetFixedImage( fixedImage ) -registration.SetMovingImage( movingImage ) - -registration.SetFixedImageRegion( fixedImage.GetBufferedRegion() ) - -transform.SetIdentity() -initialParameters = transform.GetParameters() - -registration.SetInitialTransformParameters( initialParameters ) - - -# -# Iteration Observer -# -def iterationUpdate(): - currentParameter = transform.GetParameters() - print "M: %f P: %f %f " % ( optimizer.GetValue(), - currentParameter.GetElement(0), - currentParameter.GetElement(1) ) - -iterationCommand = itk.PyCommand.New() -iterationCommand.SetCommandCallable( iterationUpdate ) -optimizer.AddObserver( itk.IterationEvent(), iterationCommand ) - - -# -# Define optimizer parameters -# -optimizer.SetMaximumStepLength( 4.00 ) -optimizer.SetMinimumStepLength( 0.01 ) -optimizer.SetNumberOfIterations( 200 ) - -print "Starting registration" - - -# -# Start the registration process -# -registration.Update() - - -# -# Get the final parameters of the transformation -# -finalParameters = registration.GetLastTransformParameters() - -print "Final Registration Parameters " -print "Translation X = %f" % (finalParameters.GetElement(0),) -print "Translation Y = %f" % (finalParameters.GetElement(1),) - - -# -# Now, we use the final transform for resampling the -# moving image. -# -resampler = itk.ResampleImageFilter[MovingImageType, FixedImageType].New() -resampler.SetTransform( transform ) -resampler.SetInput( movingImage ) - -region = fixedImage.GetLargestPossibleRegion() - -resampler.SetSize( region.GetSize() ) - -resampler.SetOutputSpacing( fixedImage.GetSpacing() ) -resampler.SetOutputDirection( fixedImage.GetDirection() ) -resampler.SetOutputOrigin( fixedImage.GetOrigin() ) -resampler.SetDefaultPixelValue( 100 ) - -outputCast = itk.RescaleIntensityImageFilter[FixedImageType, OutputImageType].New() -outputCast.SetInput(resampler.GetOutput()) - - -# -# Write the resampled image -# -writer = itk.ImageFileWriter[OutputImageType].New() - -writer.SetFileName( argv[3] ) -writer.SetInput( outputCast.GetOutput() ) -writer.Update() diff --git a/Examples/RegistrationITKv3/ImageRegistration5.py b/Examples/RegistrationITKv3/ImageRegistration5.py deleted file mode 100644 index a9be86b1d78..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistration5.py +++ /dev/null @@ -1,207 +0,0 @@ -#========================================================================== -# -# Copyright Insight Software Consortium -# -# 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. -# -#==========================================================================*/ - -import itk -from sys import argv - - -# -# Check input parameters -# INPUTS(fixedImage): {BrainProtonDensitySliceBorder20.png} -# INPUTS(movingImage): {BrainProtonDensitySliceRotated10.png} -# -if len(argv) < 4: - print 'Missing Parameters' - print 'Usage: ImageRegistration5.py fixedImageFile movingImageFile outputImagefile' - exit() - - -# -# Define data types -# -FixedImageType = itk.Image[itk.F, 2] -MovingImageType = itk.Image[itk.F, 2] -OutputImageType = itk.Image[itk.UC, 2] -TransformType = itk.CenteredRigid2DTransform - - -# -# Read the fixed and moving images using filenames -# from the command line arguments -# -fixedImageReader = itk.ImageFileReader[FixedImageType].New() -movingImageReader = itk.ImageFileReader[MovingImageType].New() - -fixedImageReader.SetFileName( argv[1] ) -movingImageReader.SetFileName( argv[2] ) - -fixedImageReader.Update() -movingImageReader.Update() - -fixedImage = fixedImageReader.GetOutput() -movingImage = movingImageReader.GetOutput() - - -# -# Instantiate the classes for the registration framework -# -registration = itk.ImageRegistrationMethod[FixedImageType, MovingImageType].New() -imageMetric = itk.MeanSquaresImageToImageMetric[FixedImageType, MovingImageType].New() -transform = TransformType.New() -optimizer = itk.RegularStepGradientDescentOptimizer.New() -interpolator = itk.LinearInterpolateImageFunction[FixedImageType, itk.D].New() - -registration.SetOptimizer( optimizer ) -registration.SetTransform( transform ) -registration.SetInterpolator( interpolator) -registration.SetMetric( imageMetric ) - -registration.SetFixedImage( fixedImage ) -registration.SetMovingImage( movingImage ) - -registration.SetFixedImageRegion( fixedImage.GetBufferedRegion() ) - - -# -# Initial transform parameters -# -transform.SetAngle( 0.0 ); - -# center of the fixed image -fixedSpacing = fixedImage.GetSpacing() -fixedOrigin = fixedImage.GetOrigin() -fixedSize = fixedImage.GetLargestPossibleRegion().GetSize() - -centerFixed = ( fixedOrigin.GetElement(0) + fixedSpacing.GetElement(0) * fixedSize.GetElement(0) / 2.0, - fixedOrigin.GetElement(1) + fixedSpacing.GetElement(1) * fixedSize.GetElement(1) / 2.0 ) - -# center of the moving image -movingSpacing= movingImage.GetSpacing() -movingOrigin = movingImage.GetOrigin() -movingSize = movingImage.GetLargestPossibleRegion().GetSize() - -centerMoving = ( movingOrigin.GetElement(0) + movingSpacing.GetElement(0) * movingSize.GetElement(0) / 2.0, - movingOrigin.GetElement(1) + movingSpacing.GetElement(1) * movingSize.GetElement(1) / 2.0 ) - -# transform center -center = transform.GetCenter() -center.SetElement( 0, centerFixed[0] ) -center.SetElement( 1, centerFixed[1] ) - -# transform translation -translation = transform.GetTranslation() -translation.SetElement( 0, centerMoving[0] - centerFixed[0] ) -translation.SetElement( 1, centerMoving[1] - centerFixed[1] ) - -initialParameters = transform.GetParameters() - -print "Initial Parameters: " -print "Angle: %f" % (initialParameters.GetElement(0), ) -print "Center: %f, %f" % ( initialParameters.GetElement(1), initialParameters.GetElement(2) ) -print "Translation: %f, %f" % (initialParameters.GetElement(3), initialParameters.GetElement(4)) - -registration.SetInitialTransformParameters( initialParameters ) - - -# -# Define optimizer parameters -# - -# optimizer scale -translationScale = 1.0 / 1000.0 - -optimizerScales = itk.Array[itk.D](transform.GetNumberOfParameters()) -optimizerScales.SetElement(0, 1.0) -optimizerScales.SetElement(1, translationScale) -optimizerScales.SetElement(2, translationScale) -optimizerScales.SetElement(3, translationScale) -optimizerScales.SetElement(4, translationScale) - -optimizer.SetScales( optimizerScales ) -optimizer.SetMaximumStepLength( 0.1 ) -optimizer.SetMinimumStepLength( 0.001 ) -optimizer.SetNumberOfIterations( 200 ) - - -# -# Iteration Observer -# -def iterationUpdate(): - currentParameter = transform.GetParameters() - print "M: %f P: %f %f %f %f %f " % ( optimizer.GetValue(), - currentParameter.GetElement(0), - currentParameter.GetElement(1), - currentParameter.GetElement(2), - currentParameter.GetElement(3), - currentParameter.GetElement(4) ) - -iterationCommand = itk.PyCommand.New() -iterationCommand.SetCommandCallable( iterationUpdate ) -optimizer.AddObserver( itk.IterationEvent(), iterationCommand ) - -print "Starting registration" - - -# -# Start the registration process -# -registration.Update() - - -# -# Get the final parameters of the transformation -# -finalParameters = registration.GetLastTransformParameters() - -print "Final Registration Parameters " -print "Angle in radians = %f" % finalParameters.GetElement(0) -print "Rotation Center X = %f" % finalParameters.GetElement(1) -print "Rotation Center Y = %f" % finalParameters.GetElement(2) -print "Translation in X = %f" % finalParameters.GetElement(3) -print "Translation in Y = %f" % finalParameters.GetElement(4) - -# Now, we use the final transform for resampling the moving image. -resampler = itk.ResampleImageFilter[MovingImageType, FixedImageType].New() -resampler.SetTransform( transform ) -resampler.SetInput( movingImage ) - -region = fixedImage.GetLargestPossibleRegion() - -resampler.SetSize( region.GetSize() ) - -resampler.SetOutputSpacing( fixedImage.GetSpacing() ) -resampler.SetOutputOrigin( fixedImage.GetOrigin() ) -resampler.SetOutputDirection( fixedImage.GetDirection() ) -resampler.SetDefaultPixelValue( 100 ) - - -# -# Cast for output -# -outputCast = itk.RescaleIntensityImageFilter[FixedImageType, OutputImageType].New() -outputCast.SetInput(resampler.GetOutput()) - - -# -# Write the resampled image -# -writer = itk.ImageFileWriter[OutputImageType].New() - -writer.SetFileName( argv[3] ) -writer.SetInput( outputCast.GetOutput() ) -writer.Update() diff --git a/Examples/RegistrationITKv3/ImageRegistrationHistogramPlotter.cxx b/Examples/RegistrationITKv3/ImageRegistrationHistogramPlotter.cxx deleted file mode 100644 index 4c47c7cdfde..00000000000 --- a/Examples/RegistrationITKv3/ImageRegistrationHistogramPlotter.cxx +++ /dev/null @@ -1,762 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : Begin TODO HACK FIXME CommandLineArgs -// INPUTS: {BrainT1SliceBorder20.png} -// INPUTS: {BrainProtonDensitySliceShifted13x17y.png} -// ARGUMENTS: RegisteredImage.png 0 -// OUTPUTS: {JointEntropyHistogramPriorToRegistration.png} -// OUTPUTS: {JointEntropyHistogramAfterRegistration.png} -// ARGUMENTS: 128 -// Software Guide : End TODO HACK FIXME CommandLineArgs - -// Software Guide : BeginLatex -// -// When fine tuning the parameters of an image registration process it is not -// always clear what factor are having a larger impact on the behavior of the -// registration. Even plotting the values of the metric and the transform -// parameters may not provide a clear indication on the best way to modify the -// optimizer and metric parameters in order to improve the convergence rate -// and stability. In such circumstances it is useful to take a closer look at -// the internals of the components involved in computing the registration. One -// of the critical components is, of course, the image metric. This section -// illustrates a mechanism that can be used for monitoring the behavior of the -// Mutual Information metric by continuously looking at the joint histogram at -// regular intervals during the iterations of the optimizer. -// -// This particular example shows how to use the -// \doxygen{HistogramToEntropyImageFilter} class in order to get access to the -// joint histogram that is internally computed by the metric. This class -// represents the joint histogram as a $2D$ image and therefore can take -// advantage of the IO functionalities described in chapter~\ref{sec:IO}. The -// example registers two images using the gradient descent optimizer. The -// transform used here is a simple translation transform. The metric is a -// \doxygen{MutualInformationHistogramImageToImageMetric}. -// -// In the code below we create a helper class called the -// \code{HistogramWriter}. Its purpose is to save the joint histogram into a -// file using any of the file formats supported by ITK. This object is invoked -// after every iteration of the optimizer. The writer here saves the joint -// histogram into files with names: \code{JointHistogramXXX.mhd} where -// \code{XXX} is replaced with the iteration number. The output image contains -// the joint entropy histogram given by -// \begin{equation} -// f_{ij} = -p_{ij} \log_2 ( p_{ij} ) -// \end{equation} -// -// where the indices $i$ and $j$ identify the location of a bin in the Joint -// Histogram of the two images and are in the ranges $i \in [0:N-1]$ and $j -// \in [0:M-1]$. The image $f$ representing the joint histogram has $N x M$ -// pixels because the intensities of the Fixed image are quantized into $N$ -// histogram bins and the intensities of the Moving image are quantized into -// $M$ histogram bins. The probability value $p_{ij}$ is computed from the -// frequency count of the histogram bins. -// \begin{equation} -// p_{ij} = \frac{q_{ij}}{\sum_{i=0}^{N-1} \sum_{j=0}^{M-1} q_{ij}} -// \end{equation} -// The value $q_{ij}$ is the frequency of a bin in the histogram and it is -// computed as the number of pixels where the Fixed image has intensities in -// the range of bin $i$ and the Moving image has intensities on the range of -// bin $j$. The value $p_{ij}$ is therefore the probability of the occurrence -// of the measurement vector centered in the bin ${ij}$. The filter produces -// an output image of pixel type \code{double}. For details on the use of -// Histograms in ITK please refer to section~\ref{sec:Histogram}. -// -// Depending on whether you want to see the joint histogram frequencies -// directly, or the joint probabilities, or log of joint probabilities, you -// may want to instantiate respectively any of the following classes -// -// \begin{itemize} -// \item \doxygen{HistogramToIntensityImageFilter} -// \item \doxygen{HistogramToProbabilityImageFilter} -// \item \doxygen{HistogramToLogProbabilityImageFilter} -// \end{itemize} -// -// \index{Histogram\-To\-Log\-Probability\-ImageFilter} -// \index{Histogram\-To\-Intensity\-Image\-Filter} -// \index{Histogram\-To\-Probability\-Image\-Filter} -// -// The use of all of these classes is very similar. Note that the log of the -// probability is equivalent to units of information, also known as -// \textbf{bits}, more details on this concept can be found in -// section~\ref{sec:ComputingImageEntropy} -// -// Software Guide : EndLatex - - -#include "itkImageRegistrationMethod.h" -#include "itkTranslationTransform.h" -#include "itkRegularStepGradientDescentOptimizer.h" -#include "itkNormalizeImageFilter.h" -#include "itkDiscreteGaussianImageFilter.h" -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" - -#include - -// Software Guide : BeginLatex -// -// The header files of the classes featured in this example are included as a -// first step. -// -// \index{Histogram\-To\-Probability\-Image\-Filter!Header} -// \index{Mutual\-Information\-Histogram\-Image\-To\-Image\-Metric!Header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkHistogramToEntropyImageFilter.h" -#include "itkMutualInformationHistogramImageToImageMetric.h" -// Software Guide : EndCodeSnippet - -#include "itkCommand.h" - -#include - -// Functor to rescale plot the histogram on a log scale and invert it. -template< class TInput > -class RescaleDynamicRangeFunctor -{ -public: - using OutputPixelType = unsigned char; - RescaleDynamicRangeFunctor() {}; - ~RescaleDynamicRangeFunctor() {}; - inline OutputPixelType operator()( const TInput &A ) - { - if( (A > 0.0) ) - { - if( -(30.0 * std::log(A)) > 255 ) - { - return static_cast( 255 ); - } - else - { - return itk::Math::Round( -(30.0 * std::log(A)) ); - } - } - else - { - return static_cast(255); - } - } -}; - -// Class to write the joint histograms. -// Software : BeginLatex -// -// Here we will create a simple class to write the joint histograms. This -// class, that we arbitrarily name as \code{HistogramWriter}, uses internally -// the \doxygen{HistogramToEntropyImageFilter} class among others. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -namespace -{ -class HistogramWriter -{ -public: - using InternalPixelType = float; - static constexpr unsigned int Dimension = 2; - - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - - using MetricType = itk::MutualInformationHistogramImageToImageMetric< - InternalImageType, - InternalImageType >; - // Software Guide : EndCodeSnippet - - using MetricPointer = MetricType::Pointer; - - // Software Guide : BeginCodeSnippet - using HistogramType = MetricType::HistogramType; - - using HistogramToEntropyImageFilterType = - itk::HistogramToEntropyImageFilter< HistogramType, InternalImageType>; - - using HistogramToImageFilterPointer = - HistogramToEntropyImageFilterType::Pointer; - - using OutputImageType = HistogramToEntropyImageFilterType::OutputImageType; - - using HistogramFileWriterType = itk::ImageFileWriter< OutputImageType >; - using HistogramFileWriterPointer = HistogramFileWriterType::Pointer; - // Software Guide : EndCodeSnippet - - using OutputPixelType = HistogramToEntropyImageFilterType::OutputPixelType; - - HistogramWriter(): - m_Metric(0) - { - - // Software Guide : BeginLatex - // - // The \code{HistogramWriter} has a member variable \code{m\_Filter} of type - // HistogramToEntropyImageFilter. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - this->m_Filter = HistogramToEntropyImageFilterType::New(); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // It also has an ImageFileWriter that has been instantiated using the image - // type that is produced as output from the histogram to image filter. We - // connect the output of the filter as input to the writer. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - this->m_HistogramFileWriter = HistogramFileWriterType::New(); - this->m_HistogramFileWriter->SetInput( this->m_Filter->GetOutput() ); - // Software Guide : EndCodeSnippet - - } - - ~HistogramWriter() { }; - - void SetMetric( MetricPointer metric ) - { - this->m_Metric = metric; - } - - MetricPointer GetMetric() const - { - return this->m_Metric; - } - - void WriteHistogramFile( unsigned int iterationNumber ) - { - std::string outputFileBase = "JointHistogram"; - std::ostringstream outputFilename; - outputFilename << outputFileBase - << "." - << std::setfill('0') << std::setw(3) << iterationNumber - << "." - << "mhd"; - m_HistogramFileWriter->SetFileName( outputFilename.str() ); - this->m_Filter->SetInput( this->GetMetric()->GetHistogram() ); - this->m_Filter->Modified(); - - try - { - m_Filter->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ERROR: ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - } - - try - { - m_HistogramFileWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << excp << std::endl; - } - - std::cout << "Joint Histogram file: "; - std::cout << outputFilename.str() << " written" << std::endl; - - } - - // Software Guide : BeginLatex - // - // The method of this class that is most relevant to our discussion is the - // one that writes the image into a file. In this method we assign the output - // histogram of the metric to the input of the histogram to image filter. In - // this way we construct an ITK $2D$ image where every pixel corresponds to - // one of the Bins of the joint histogram computed by the Metric. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - void WriteHistogramFile( std::string &outputFilename ) - { - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginCodeSnippet - this->m_Filter->SetInput( this->GetMetric()->GetHistogram() ); - this->m_Filter->Modified(); - - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The output of the filter is connected to a filter that will rescale the - // intensities in order to improve the visualization of the values. This is - // done because it is common to find histograms of medical images that have - // a minority of bins that are largely dominant. Visualizing such histogram - // in direct values is challenging because only the dominant bins tend to - // become visible. - // - // Software Guide : EndLatex - - - //Write the joint histogram as outputFilename. Also intensity window - //the image by lower and upper thresholds and rescale the image to - //8 bits. - using RescaledOutputImageType = itk::Image< unsigned char, Dimension >; - - using RescaleDynamicRangeFunctorType = RescaleDynamicRangeFunctor< - OutputPixelType >; - - using RescaleDynamicRangeFilterType = itk::UnaryFunctorImageFilter< - OutputImageType, RescaledOutputImageType, - RescaleDynamicRangeFunctorType >; - - RescaleDynamicRangeFilterType::Pointer rescaler = - RescaleDynamicRangeFilterType::New(); - - rescaler->SetInput( m_Filter->GetOutput() ); - - using RescaledWriterType = itk::ImageFileWriter< RescaledOutputImageType >; - - RescaledWriterType::Pointer rescaledWriter = - RescaledWriterType::New(); - - rescaledWriter->SetInput( rescaler->GetOutput() ); - - rescaledWriter->SetFileName( outputFilename ); - - try - { - m_Filter->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ERROR: ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - } - - try - { - rescaledWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << excp << std::endl; - } - - std::cout << "Joint Histogram file: " << outputFilename << - " written" << std::endl; - } - -// Software Guide : BeginLatex -// -// The following are the member variables of our \code{HistogramWriter} class. -// -// Software Guide : EndLatex - - -// Software Guide : BeginCodeSnippet - -private: - MetricPointer m_Metric; - HistogramToImageFilterPointer m_Filter; - HistogramFileWriterPointer m_HistogramFileWriter; - // Software Guide : EndCodeSnippet - std::string m_OutputFile; -}; - -// Command - observer invoked after every iteration of the optimizer -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkSimpleNewMacro( Self ); - -protected: - CommandIterationUpdate() - { - m_WriteHistogramsAfterEveryIteration = false; - } - -public: - - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( ! itk::IterationEvent().CheckEvent( &event ) || optimizer == nullptr ) - { - return; - } - std::cout << optimizer->GetCurrentIteration() << " "; - std::cout << optimizer->GetValue() << " "; - std::cout << optimizer->GetCurrentPosition() << std::endl; - - // Write the joint histogram as a file JointHistogramXXX.mhd - // where \code{XXX} is the iteration number - - - //Write Joint Entropy Histogram prior to registration. - if( optimizer->GetCurrentIteration() == 0 ) - { - // Software Guide : BeginLatex - // - // We invoke the histogram writer within the Command/Observer of the - // optimizer to write joint histograms after every iteration. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - m_JointHistogramWriter.WriteHistogramFile( m_InitialHistogramFile ); - // Software Guide : EndCodeSnippet - } - if( m_WriteHistogramsAfterEveryIteration ) - { - m_JointHistogramWriter.WriteHistogramFile( - optimizer->GetCurrentIteration() ); - } - } - - void SetWriteHistogramsAfterEveryIteration( bool value ) - { - m_WriteHistogramsAfterEveryIteration = value; - } - - void SetInitialHistogramFile( const char * filename ) - { - m_InitialHistogramFile = filename; - } - - HistogramWriter m_JointHistogramWriter; - -private: - bool m_WriteHistogramsAfterEveryIteration; - std::string m_InitialHistogramFile; - -}; - -} // end anonymous namespace - - -int main( int argc, char *argv[] ) -{ - if( argc < 8 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << "outputImagefile WriteJointHistogramsAfterEveryIteration "; - std::cerr << "JointHistogramPriorToRegistrationFile "; - std::cerr << "JointHistogramAfterRegistrationFile "; - std::cerr << "NumberOfHistogramBinsForWritingTheMutualInformationHistogramMetric"; - std::cerr << std::endl; - return EXIT_FAILURE; - } - - using PixelType = unsigned char; - - constexpr unsigned int Dimension = 2; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - using InternalPixelType = float; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - - using TransformType = itk::TranslationTransform< double, Dimension >; - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using InterpolatorType = itk::LinearInterpolateImageFunction< - InternalImageType, - double >; - using RegistrationType = itk::ImageRegistrationMethod< - InternalImageType, - InternalImageType >; - - using MetricType = itk::MutualInformationHistogramImageToImageMetric< - InternalImageType, - InternalImageType >; - - // Software Guide : BeginLatex - // - // We instantiate an optimizer, interpolator and the registration method as - // shown in previous examples. - // - // Software Guide : EndLatex - - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - MetricType::Pointer metric = MetricType::New(); - - - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - - // Software Guide : BeginLatex - // - // The number of bins in the metric is set with the \code{SetHistogramSize()} - // method. This will determine the number of pixels along each dimension of - // the joint histogram. Note that in this case we arbitrarily decided to use - // the same number of bins for the intensities of the Fixed image and those - // of the Moving image. However, this does not have to be the case, we could - // have selected different numbers of bins for each image. - // - // \index{Mutual\-Information\-Histogram\-Image\-To\-Image\-Metric!SetHistogramSize()} - // \index{SetHistogramSize(),Mutual\-Information\-Histogram\-Image\-To\-Image\-Metric} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - unsigned int numberOfHistogramBins = std::stoi( argv[7] ); - MetricType::HistogramType::SizeType histogramSize; - histogramSize.SetSize(2); - histogramSize[0] = numberOfHistogramBins; - histogramSize[1] = numberOfHistogramBins; - metric->SetHistogramSize( histogramSize ); - // Software Guide : EndCodeSnippet - - const unsigned int numberOfParameters = transform->GetNumberOfParameters(); - using ScalesType = MetricType::ScalesType; - ScalesType scales( numberOfParameters ); - scales.Fill( 1.0 ); - metric->SetDerivativeStepLengthScales(scales); - - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - - // Set the metric for the joint histogram writer - observer->m_JointHistogramWriter.SetMetric( metric ); - - registration->SetMetric( metric ); - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - - using FixedNormalizeFilterType = itk::NormalizeImageFilter< - FixedImageType, - InternalImageType >; - - using MovingNormalizeFilterType = itk::NormalizeImageFilter< - MovingImageType, - InternalImageType >; - - FixedNormalizeFilterType::Pointer fixedNormalizer = - FixedNormalizeFilterType::New(); - - MovingNormalizeFilterType::Pointer movingNormalizer = - MovingNormalizeFilterType::New(); - using GaussianFilterType = itk::DiscreteGaussianImageFilter< - InternalImageType, - InternalImageType >; - - GaussianFilterType::Pointer fixedSmoother = GaussianFilterType::New(); - GaussianFilterType::Pointer movingSmoother = GaussianFilterType::New(); - - fixedSmoother->SetVariance( 2.0 ); - movingSmoother->SetVariance( 2.0 ); - fixedNormalizer->SetInput( fixedImageReader->GetOutput() ); - movingNormalizer->SetInput( movingImageReader->GetOutput() ); - - fixedSmoother->SetInput( fixedNormalizer->GetOutput() ); - movingSmoother->SetInput( movingNormalizer->GetOutput() ); - - registration->SetFixedImage( fixedSmoother->GetOutput() ); - registration->SetMovingImage( movingSmoother->GetOutput() ); - - - try - { - fixedNormalizer->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - registration->SetFixedImageRegion( - fixedNormalizer->GetOutput()->GetBufferedRegion() ); - - using ParametersType = RegistrationType::ParametersType; - ParametersType initialParameters( transform->GetNumberOfParameters() ); - - initialParameters[0] = 0.0; // Initial offset in mm along X - initialParameters[1] = 0.0; // Initial offset in mm along Y - - registration->SetInitialTransformParameters( initialParameters ); - - - optimizer->SetMaximumStepLength( 4.00 ); - optimizer->SetMinimumStepLength( 0.01 ); - optimizer->SetRelaxationFactor( 0.90 ); - optimizer->SetNumberOfIterations( 200 ); - optimizer->MaximizeOn(); - - optimizer->AddObserver( itk::IterationEvent(), observer ); - - - observer->SetInitialHistogramFile( argv[5] ); - - if( std::stoi(argv[4]) ) - { - observer->SetWriteHistogramsAfterEveryIteration( true ); - } - - - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - ParametersType finalParameters = registration->GetLastTransformParameters(); - - double TranslationAlongX = finalParameters[0]; - double TranslationAlongY = finalParameters[1]; - - unsigned int numberOfIterations = optimizer->GetCurrentIteration(); - - double bestValue = optimizer->GetValue(); - - - std::cout << "Result = " << std::endl; - std::cout << " Translation X = " << TranslationAlongX << std::endl; - std::cout << " Translation Y = " << TranslationAlongY << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - - //Write Joint Entropy Histogram after registration. - std::string histogramAfter(argv[6]); - try - { - observer->m_JointHistogramWriter.WriteHistogramFile( histogramAfter ); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ERROR: ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - return EXIT_FAILURE; - } - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - TransformType::Pointer finalTransform = TransformType::New(); - - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( 100 ); - - - using OutputPixelType = unsigned char; - - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - - writer->SetFileName( argv[3] ); - - - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - try - { - writer->Update(); - } - catch( itk::ExceptionObject & err ) - { - std::cerr << "ERROR: ExceptionObject caught !" << std::endl; - std::cerr << err << std::endl; - } - - return EXIT_SUCCESS; - -} - -// Software Guide : BeginLatex -// -// Mutual information attempts to re-group the joint entropy histograms into a -// more ``meaningful'' formation. An optimizer that minimizes the joint entropy -// seeks a transform that produces a small number of high value bins and a -// large majority of almost zero bins. Multi-modality registration seeks such a -// transform while also attempting to maximize the information contribution by -// the fixed and the moving images in the overall region of the metric. -// -// A T1 MRI (fixed image) and a proton density MRI (moving image) as shown in Figure -// \ref{fig:FixedMovingImageRegistration2} -// are provided as input to this example. -// -// Figure \ref{fig:JointEntropyHistograms} shows the joint histograms before and -// after registration. -// \begin{figure} -// \center -// \includegraphics[width=0.44\textwidth]{JointEntropyHistogramPriorToRegistration} -// \includegraphics[width=0.44\textwidth]{JointEntropyHistogramAfterRegistration} -// \itkcaption[Multi-modality joint histograms]{Joint entropy histograms before and -// after registration. The final transform was within half a pixel of true misalignment.} -// \label{fig:JointEntropyHistograms} -// \end{figure} -// Software Guide : EndLatex diff --git a/Examples/RegistrationITKv3/IterativeClosestPoint1.cxx b/Examples/RegistrationITKv3/IterativeClosestPoint1.cxx deleted file mode 100644 index 72ede657959..00000000000 --- a/Examples/RegistrationITKv3/IterativeClosestPoint1.cxx +++ /dev/null @@ -1,264 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to perform Iterative Closest Point (ICP) -// registration in ITK. The main class featured in this section is the -// \doxygen{EuclideanDistancePointMetric}. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkTranslationTransform.h" -#include "itkEuclideanDistancePointMetric.h" -#include "itkLevenbergMarquardtOptimizer.h" -#include "itkPointSetToPointSetRegistrationMethod.h" -// Software Guide : EndCodeSnippet - -#include - -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - - using OptimizerType = itk::LevenbergMarquardtOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - - if( ! itk::IterationEvent().CheckEvent( &event ) ) - { - return; - } - - std::cout << "Value = " << optimizer->GetCachedValue() << std::endl; - std::cout << "Position = " << optimizer->GetCachedCurrentPosition(); - std::cout << std::endl << std::endl; - - } - -}; - - -int main(int argc, char * argv[] ) -{ - - if( argc < 3 ) - { - std::cerr << "Arguments Missing. " << std::endl; - std::cerr - << "Usage: IterativeClosestPoint1 fixedPointsFile movingPointsFile " - << std::endl; - return EXIT_FAILURE; - } - -// Software Guide : BeginCodeSnippet - constexpr unsigned int Dimension = 2; - - using PointSetType = itk::PointSet< float, Dimension >; - - PointSetType::Pointer fixedPointSet = PointSetType::New(); - PointSetType::Pointer movingPointSet = PointSetType::New(); - - using PointType = PointSetType::PointType; - - using PointsContainer = PointSetType::PointsContainer; - - PointsContainer::Pointer fixedPointContainer = PointsContainer::New(); - PointsContainer::Pointer movingPointContainer = PointsContainer::New(); - - PointType fixedPoint; - PointType movingPoint; -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Read the file containing coordinates of fixed points. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - std::ifstream fixedFile; - fixedFile.open( argv[1] ); - if( fixedFile.fail() ) - { - std::cerr << "Error opening points file with name : " << std::endl; - std::cerr << argv[1] << std::endl; - return EXIT_FAILURE; - } - - unsigned int pointId = 0; - fixedFile >> fixedPoint; - while( !fixedFile.eof() ) - { - fixedPointContainer->InsertElement( pointId, fixedPoint ); - fixedFile >> fixedPoint; - pointId++; - } - fixedPointSet->SetPoints( fixedPointContainer ); - std::cout << - "Number of fixed Points = " << - fixedPointSet->GetNumberOfPoints() << std::endl; -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Read the file containing coordinates of moving points. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - std::ifstream movingFile; - movingFile.open( argv[2] ); - if( movingFile.fail() ) - { - std::cerr << "Error opening points file with name : " << std::endl; - std::cerr << argv[2] << std::endl; - return EXIT_FAILURE; - } - - pointId = 0; - movingFile >> movingPoint; - while( !movingFile.eof() ) - { - movingPointContainer->InsertElement( pointId, movingPoint ); - movingFile >> movingPoint; - pointId++; - } - movingPointSet->SetPoints( movingPointContainer ); - std::cout << "Number of moving Points = " - << movingPointSet->GetNumberOfPoints() << std::endl; -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Set up the Metric. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - using MetricType = itk::EuclideanDistancePointMetric< - PointSetType, PointSetType>; - - MetricType::Pointer metric = MetricType::New(); -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Set up a Transform. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - using TransformType = itk::TranslationTransform< double, Dimension >; - - TransformType::Pointer transform = TransformType::New(); -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// Set up a the Optimizer and RegistrationMethod. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - using OptimizerType = itk::LevenbergMarquardtOptimizer; - - OptimizerType::Pointer optimizer = OptimizerType::New(); - optimizer->SetUseCostFunctionGradient(false); - - using RegistrationType = itk::PointSetToPointSetRegistrationMethod< - PointSetType, PointSetType >; - - - RegistrationType::Pointer registration = RegistrationType::New(); - - // Scale the translation components of the Transform in the Optimizer - OptimizerType::ScalesType scales( transform->GetNumberOfParameters() ); - scales.Fill( 0.01 ); - - - unsigned long numberOfIterations = 100; - double gradientTolerance = 1e-5; // convergence criterion - double valueTolerance = 1e-5; // convergence criterion - double epsilonFunction = 1e-6; // convergence criterion - - - optimizer->SetScales( scales ); - optimizer->SetNumberOfIterations( numberOfIterations ); - optimizer->SetValueTolerance( valueTolerance ); - optimizer->SetGradientTolerance( gradientTolerance ); - optimizer->SetEpsilonFunction( epsilonFunction ); - - // Start from an Identity transform (in a normal case, the user - // can probably provide a better guess than the identity... - transform->SetIdentity(); - - registration->SetInitialTransformParameters( transform->GetParameters() ); -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Connect all the components required for Registration -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetFixedPointSet( fixedPointSet ); - registration->SetMovingPointSet( movingPointSet ); - - // Connect an observer - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - try - { - registration->Update(); - } - catch( itk::ExceptionObject & e ) - { - std::cout << e << std::endl; - return EXIT_FAILURE; - } - - std::cout << "Solution = " << transform->GetParameters() << std::endl; -// Software Guide : EndCodeSnippet - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/IterativeClosestPoint2.cxx b/Examples/RegistrationITKv3/IterativeClosestPoint2.cxx deleted file mode 100644 index 1cbe5c3840e..00000000000 --- a/Examples/RegistrationITKv3/IterativeClosestPoint2.cxx +++ /dev/null @@ -1,229 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to perform Iterative Closest Point (ICP) -// registration in ITK using sets of 3D points. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkTranslationTransform.h" -#include "itkEuclideanDistancePointMetric.h" -#include "itkLevenbergMarquardtOptimizer.h" -#include "itkPointSetToPointSetRegistrationMethod.h" -// Software Guide : EndCodeSnippet - -#include - - -int main(int argc, char * argv[] ) -{ - - if( argc < 3 ) - { - std::cerr << "Arguments Missing. " << std::endl; - std::cerr << - "Usage: IterativeClosestPoint2 fixedPointsFile movingPointsFile " - << std::endl; - return EXIT_FAILURE; - } - -// Software Guide : BeginCodeSnippet - constexpr unsigned int Dimension = 3; - - using PointSetType = itk::PointSet< float, Dimension >; - - PointSetType::Pointer fixedPointSet = PointSetType::New(); - PointSetType::Pointer movingPointSet = PointSetType::New(); - - using PointType = PointSetType::PointType; - - using PointsContainer = PointSetType::PointsContainer; - - PointsContainer::Pointer fixedPointContainer = PointsContainer::New(); - PointsContainer::Pointer movingPointContainer = PointsContainer::New(); - - PointType fixedPoint; - PointType movingPoint; -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Read the file containing coordinates of fixed points. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - std::ifstream fixedFile; - fixedFile.open( argv[1] ); - if( fixedFile.fail() ) - { - std::cerr << "Error opening points file with name : " << std::endl; - std::cerr << argv[1] << std::endl; - return EXIT_FAILURE; - } - - unsigned int pointId = 0; - fixedFile >> fixedPoint; - while( !fixedFile.eof() ) - { - fixedPointContainer->InsertElement( pointId, fixedPoint ); - fixedFile >> fixedPoint; - pointId++; - } - fixedPointSet->SetPoints( fixedPointContainer ); - std::cout << - "Number of fixed Points = " << - fixedPointSet->GetNumberOfPoints() << std::endl; -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Read the file containing coordinates of moving points. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - std::ifstream movingFile; - movingFile.open( argv[2] ); - if( movingFile.fail() ) - { - std::cerr << "Error opening points file with name : " << std::endl; - std::cerr << argv[2] << std::endl; - return EXIT_FAILURE; - } - - pointId = 0; - movingFile >> movingPoint; - while( !movingFile.eof() ) - { - movingPointContainer->InsertElement( pointId, movingPoint ); - movingFile >> movingPoint; - pointId++; - } - movingPointSet->SetPoints( movingPointContainer ); - std::cout << "Number of moving Points = " - << movingPointSet->GetNumberOfPoints() << std::endl; -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Set up the Metric. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - using MetricType = itk::EuclideanDistancePointMetric< - PointSetType, PointSetType>; - - MetricType::Pointer metric = MetricType::New(); -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Set up a Transform. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - using TransformType = itk::TranslationTransform< double, Dimension >; - - TransformType::Pointer transform = TransformType::New(); -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// Set up a the Optimizer and RegistrationMethod. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - using OptimizerType = itk::LevenbergMarquardtOptimizer; - - OptimizerType::Pointer optimizer = OptimizerType::New(); - optimizer->SetUseCostFunctionGradient(false); - - using RegistrationType = itk::PointSetToPointSetRegistrationMethod< - PointSetType, PointSetType >; - - RegistrationType::Pointer registration = RegistrationType::New(); - - // Scale the translation components of the Transform in the Optimizer - OptimizerType::ScalesType scales( transform->GetNumberOfParameters() ); - - constexpr double translationScale = 1000.0; // dynamic range of translations - constexpr double rotationScale = 1.0; // dynamic range of rotations - - scales[0] = 1.0 / rotationScale; - scales[1] = 1.0 / rotationScale; - scales[2] = 1.0 / rotationScale; - scales[3] = 1.0 / translationScale; - scales[4] = 1.0 / translationScale; - scales[5] = 1.0 / translationScale; - - unsigned long numberOfIterations = 2000; - double gradientTolerance = 1e-4; // convergence criterion - double valueTolerance = 1e-4; // convergence criterion - double epsilonFunction = 1e-5; // convergence criterion - - - optimizer->SetScales( scales ); - optimizer->SetNumberOfIterations( numberOfIterations ); - optimizer->SetValueTolerance( valueTolerance ); - optimizer->SetGradientTolerance( gradientTolerance ); - optimizer->SetEpsilonFunction( epsilonFunction ); - - // Start from an Identity transform (in a normal case, the user - // can probably provide a better guess than the identity... - transform->SetIdentity(); - - registration->SetInitialTransformParameters( transform->GetParameters() ); -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Connect all the components required for Registration -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetFixedPointSet( fixedPointSet ); - registration->SetMovingPointSet( movingPointSet ); - - - try - { - registration->Update(); - } - catch( itk::ExceptionObject & e ) - { - std::cout << e << std::endl; - return EXIT_FAILURE; - } - - std::cout << "Solution = " << transform->GetParameters() << std::endl; -// Software Guide : EndCodeSnippet - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/IterativeClosestPoint3.cxx b/Examples/RegistrationITKv3/IterativeClosestPoint3.cxx deleted file mode 100644 index cf434d6c052..00000000000 --- a/Examples/RegistrationITKv3/IterativeClosestPoint3.cxx +++ /dev/null @@ -1,247 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to perform Iterative Closest Point (ICP) -// registration in ITK using a DistanceMap in order to increase the performance. -// There is of course a trade-off between the time needed for computing the -// DistanceMap and the time saving obtained by its repeated use during the -// iterative computation of the point to point distances. It is then necessary -// in practice to ponder both factors. -// -// \doxygen{EuclideanDistancePointMetric}. -// -// Software Guide : EndLatex - -#include "itkTranslationTransform.h" -#include "itkEuclideanDistancePointMetric.h" -#include "itkLevenbergMarquardtOptimizer.h" -#include "itkPointSetToPointSetRegistrationMethod.h" -#include "itkDanielssonDistanceMapImageFilter.h" -#include "itkPointSetToImageFilter.h" -#include -#include - -int main(int argc, char * argv[] ) -{ - - if( argc < 3 ) - { - std::cerr << "Arguments Missing. " << std::endl; - std::cerr << - "Usage: IterativeClosestPoint3 fixedPointsFile movingPointsFile " - << std::endl; - return EXIT_FAILURE; - } - -// Software Guide : BeginCodeSnippet - constexpr unsigned int Dimension = 2; - - using PointSetType = itk::PointSet< float, Dimension >; - - PointSetType::Pointer fixedPointSet = PointSetType::New(); - PointSetType::Pointer movingPointSet = PointSetType::New(); - - using PointType = PointSetType::PointType; - - using PointsContainer = PointSetType::PointsContainer; - - PointsContainer::Pointer fixedPointContainer = PointsContainer::New(); - PointsContainer::Pointer movingPointContainer = PointsContainer::New(); - - PointType fixedPoint; - PointType movingPoint; -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// Read the file containing coordinates of fixed points. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - std::ifstream fixedFile; - fixedFile.open( argv[1] ); - if( fixedFile.fail() ) - { - std::cerr << "Error opening points file with name : " << std::endl; - std::cerr << argv[1] << std::endl; - return EXIT_FAILURE; - } - - unsigned int pointId = 0; - fixedFile >> fixedPoint; - while( !fixedFile.eof() ) - { - fixedPointContainer->InsertElement( pointId, fixedPoint ); - fixedFile >> fixedPoint; - pointId++; - } - fixedPointSet->SetPoints( fixedPointContainer ); - std::cout << "Number of fixed Points = " - << fixedPointSet->GetNumberOfPoints() << std::endl; -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// Read the file containing coordinates of moving points. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - std::ifstream movingFile; - movingFile.open( argv[2] ); - if( movingFile.fail() ) - { - std::cerr << "Error opening points file with name : " << std::endl; - std::cerr << argv[2] << std::endl; - return EXIT_FAILURE; - } - - pointId = 0; - movingFile >> movingPoint; - while( !movingFile.eof() ) - { - movingPointContainer->InsertElement( pointId, movingPoint ); - movingFile >> movingPoint; - pointId++; - } - movingPointSet->SetPoints( movingPointContainer ); - std::cout << "Number of moving Points = " - << movingPointSet->GetNumberOfPoints() << std::endl; -// Software Guide : EndCodeSnippet - -// Software Guide : BeginCodeSnippet - using MetricType = itk::EuclideanDistancePointMetric< - PointSetType, PointSetType>; - - MetricType::Pointer metric = MetricType::New(); - - using TransformType = itk::TranslationTransform< double, Dimension >; - - TransformType::Pointer transform = TransformType::New(); - - // Optimizer Type - using OptimizerType = itk::LevenbergMarquardtOptimizer; - - OptimizerType::Pointer optimizer = OptimizerType::New(); - optimizer->SetUseCostFunctionGradient(false); - - // Registration Method - using RegistrationType = itk::PointSetToPointSetRegistrationMethod< - PointSetType, PointSetType >; - - RegistrationType::Pointer registration = RegistrationType::New(); - - // Scale the translation components of the Transform in the Optimizer - OptimizerType::ScalesType scales( transform->GetNumberOfParameters() ); - scales.Fill( 0.01 ); - - constexpr unsigned long numberOfIterations = 100; - const double gradientTolerance = 1e-5; // convergence criterion - const double valueTolerance = 1e-5; // convergence criterion - const double epsilonFunction = 1e-6; // convergence criterion - - optimizer->SetScales( scales ); - optimizer->SetNumberOfIterations( numberOfIterations ); - optimizer->SetValueTolerance( valueTolerance ); - optimizer->SetGradientTolerance( gradientTolerance ); - optimizer->SetEpsilonFunction( epsilonFunction ); -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Start from an Identity transform (in a normal case, the user -// can probably provide a better guess than the identity... -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - transform->SetIdentity(); - - registration->SetInitialTransformParameters( transform->GetParameters() ); - - registration->SetMetric( metric ); - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetFixedPointSet( fixedPointSet ); - registration->SetMovingPointSet( movingPointSet ); -// Software Guide : EndCodeSnippet - -// Software Guide : BeginLatex -// -// Start from an Identity transform (in a normal case, the user -// can probably provide a better guess than the identity... -// Prepare the Distance Map in order to accelerate -// distance computations. -// -// First map the Fixed Points into a binary image. -// This is needed because the DanielssonDistance -// filter expects an image as input. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet - using BinaryImageType = itk::Image< unsigned char, Dimension >; - - using PointsToImageFilterType = itk::PointSetToImageFilter< - PointSetType, - BinaryImageType>; - - PointsToImageFilterType::Pointer - pointsToImageFilter = PointsToImageFilterType::New(); - - pointsToImageFilter->SetInput( fixedPointSet ); - - BinaryImageType::SpacingType spacing; - spacing.Fill( 1.0 ); - - BinaryImageType::PointType origin; - origin.Fill( 0.0 ); - - pointsToImageFilter->SetSpacing( spacing ); - pointsToImageFilter->SetOrigin( origin ); - pointsToImageFilter->Update(); - BinaryImageType::Pointer binaryImage = pointsToImageFilter->GetOutput(); - - using DistanceImageType = itk::Image< unsigned short, Dimension >; - using DistanceFilterType = itk::DanielssonDistanceMapImageFilter< - BinaryImageType, DistanceImageType>; - - DistanceFilterType::Pointer distanceFilter = DistanceFilterType::New(); - distanceFilter->SetInput( binaryImage ); - distanceFilter->Update(); - metric->SetDistanceMap( distanceFilter->GetOutput() ); - try - { - registration->Update(); - } - catch( itk::ExceptionObject & e ) - { - std::cout << e << std::endl; - return EXIT_FAILURE; - } - - std::cout << "Solution = " << transform->GetParameters() << std::endl; -// Software Guide : EndCodeSnippet - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/LandmarkWarping2.cxx b/Examples/RegistrationITKv3/LandmarkWarping2.cxx deleted file mode 100644 index cf6bf0aebdb..00000000000 --- a/Examples/RegistrationITKv3/LandmarkWarping2.cxx +++ /dev/null @@ -1,191 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates how to deform an image using a KernelBase spline -// and two sets of landmarks. -// -// \index{WarpImageFilter} -// \index{LandmarkDisplacementFieldSource} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkVector.h" -#include "itkImage.h" -#include "itkLandmarkDisplacementFieldSource.h" -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" -#include "itkWarpImageFilter.h" -// Software Guide : EndCodeSnippet - -#include - - -int main( int argc, char * argv[] ) -{ - - if( argc < 3 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " landmarksFile fixedImage "; - std::cerr << "movingImage deformedMovingImage" << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - using VectorComponentType = float; - - using VectorType = itk::Vector< VectorComponentType, Dimension >; - - using DisplacementFieldType = itk::Image< VectorType, Dimension >; - - - using PixelType = unsigned char; - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - using FixedReaderType = itk::ImageFileReader< FixedImageType >; - using MovingReaderType = itk::ImageFileReader< MovingImageType >; - - using MovingWriterType = itk::ImageFileWriter< MovingImageType >; - - - FixedReaderType::Pointer fixedReader = FixedReaderType::New(); - fixedReader->SetFileName( argv[2] ); - - try - { - fixedReader->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - MovingReaderType::Pointer movingReader = MovingReaderType::New(); - MovingWriterType::Pointer movingWriter = MovingWriterType::New(); - - movingReader->SetFileName( argv[3] ); - movingWriter->SetFileName( argv[4] ); - - - FixedImageType::ConstPointer fixedImage = fixedReader->GetOutput(); - - - using DisplacementSourceType = itk::LandmarkDisplacementFieldSource< - DisplacementFieldType >; - - DisplacementSourceType::Pointer deformer = DisplacementSourceType::New(); - - deformer->SetOutputSpacing( fixedImage->GetSpacing() ); - deformer->SetOutputOrigin( fixedImage->GetOrigin() ); - deformer->SetOutputRegion( fixedImage->GetLargestPossibleRegion() ); - deformer->SetOutputDirection( fixedImage->GetDirection() ); - - // Create source and target landmarks. - // - using LandmarkContainerType = DisplacementSourceType::LandmarkContainer; - using LandmarkPointType = DisplacementSourceType::LandmarkPointType; - - LandmarkContainerType::Pointer sourceLandmarks = LandmarkContainerType::New(); - LandmarkContainerType::Pointer targetLandmarks = LandmarkContainerType::New(); - - LandmarkPointType sourcePoint; - LandmarkPointType targetPoint; - - std::ifstream pointsFile; - pointsFile.open( argv[1] ); - - unsigned int pointId = 0; - - pointsFile >> sourcePoint; - pointsFile >> targetPoint; - - while( !pointsFile.fail() ) - { - sourceLandmarks->InsertElement( pointId, sourcePoint ); - targetLandmarks->InsertElement( pointId, targetPoint ); - pointId++; - - pointsFile >> sourcePoint; - pointsFile >> targetPoint; - - } - - pointsFile.close(); - - - deformer->SetSourceLandmarks( sourceLandmarks ); - deformer->SetTargetLandmarks( targetLandmarks ); - - try - { - deformer->UpdateLargestPossibleRegion(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - DisplacementFieldType::ConstPointer displacementField = deformer->GetOutput(); - - using FilterType = itk::WarpImageFilter< MovingImageType, - MovingImageType, - DisplacementFieldType >; - - FilterType::Pointer warper = FilterType::New(); - - using InterpolatorType = itk::LinearInterpolateImageFunction< - MovingImageType, double >; - - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - - warper->SetInterpolator( interpolator ); - - - warper->SetOutputSpacing( displacementField->GetSpacing() ); - warper->SetOutputOrigin( displacementField->GetOrigin() ); - - warper->SetDisplacementField( displacementField ); - - warper->SetInput( movingReader->GetOutput() ); - - movingWriter->SetInput( warper->GetOutput() ); - - try - { - movingWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; - -} diff --git a/Examples/RegistrationITKv3/ModelToImageRegistration1.cxx b/Examples/RegistrationITKv3/ModelToImageRegistration1.cxx deleted file mode 100644 index 560d70aa38b..00000000000 --- a/Examples/RegistrationITKv3/ModelToImageRegistration1.cxx +++ /dev/null @@ -1,935 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates the use of the \doxygen{SpatialObject} as a -// component of the registration framework in order to perform model based -// registration. The current example creates a geometrical model composed of -// several ellipses. Then, it uses the model to produce a synthetic binary -// image of the ellipses. Next, it introduces perturbations on the position -// and shape of the model, and finally it uses the perturbed version as the -// input to a registration problem. A metric is defined to evaluate the -// fitness between the geometric model and the image. -// -// Software Guide : EndLatex - - -// Software Guide : BeginLatex -// -// Let's look first at the classes required to support -// SpatialObject. In this example we use the -// \doxygen{EllipseSpatialObject} as the basic shape components and we use the -// \doxygen{GroupSpatialObject} to group them together as a representation of -// a more complex shape. Their respective headers are included below. -// -// \index{itk::EllipseSpatialObject!header} -// \index{itk::GroupSpatialObject!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkEllipseSpatialObject.h" -#include "itkGroupSpatialObject.h" -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// In order to generate the initial synthetic image of the ellipses, we use -// the \doxygen{SpatialObjectToImageFilter} that tests---for every pixel in -// the image---whether the pixel (and hence the spatial object) is -// \emph{inside} or \emph{outside} the geometric model. -// -// \index{itk::Spatial\-Object\-To\-Image\-Filter!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkSpatialObjectToImageFilter.h" -// Software Guide : EndCodeSnippet - - -#include "itkImageToSpatialObjectRegistrationMethod.h" - - -// Software Guide : BeginLatex -// -// A metric is defined to evaluate the fitness between the -// SpatialObject and the Image. The base class for this -// type of metric is the \doxygen{ImageToSpatialObjectMetric}, whose header is -// included below. -// -// \index{itk::Image\-To\-Spatial\-Object\-Metric!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// As in previous registration problems, we have to evaluate the image -// intensity in non-grid positions. The -// \doxygen{LinearInterpolateImageFunction} is used here for this purpose. -// -// \index{itk::Linear\-Interpolate\-Image\-Function!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkLinearInterpolateImageFunction.h" -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// The SpatialObject is mapped from its own space into the image -// space by using a \doxygen{Transform}. In this -// example, we use the \doxygen{Euler2DTransform}. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkEuler2DTransform.h" -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// Registration is fundamentally an optimization problem. Here we include -// the optimizer used to search the parameter space and identify the best -// transformation that will map the shape model on top of the image. The -// optimizer used in this example is the -// \doxygen{OnePlusOneEvolutionaryOptimizer} that implements an -// \href{http://www.aic.nrl.navy.mil/galist/}{evolutionary algorithm}. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkOnePlusOneEvolutionaryOptimizer.h" -// Software Guide : EndCodeSnippet - - -#include "itkDiscreteGaussianImageFilter.h" -#include "itkNormalVariateGenerator.h" -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" -#include "itkCastImageFilter.h" -#include "itkRescaleIntensityImageFilter.h" - - -// Software Guide : BeginLatex -// -// As in previous registration examples, it is important to -// track the evolution of the optimizer as it progresses through the parameter -// space. This is done by using the Command/Observer paradigm. The -// following lines of code implement the \doxygen{Command} observer that -// monitors the progress of the registration. The code is quite -// similar to what we have used in previous registration examples. -// -// \index{Model to Image Registration!Observer} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkCommand.h" -template < class TOptimizer > -class IterationCallback : public itk::Command -{ -public: - using Self = IterationCallback; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - using ConstPointer = itk::SmartPointer; - - itkTypeMacro( IterationCallback, Superclass ); - itkNewMacro( Self ); - - /** Type defining the optimizer. */ - using OptimizerType = TOptimizer; - - /** Method to specify the optimizer. */ - void SetOptimizer( OptimizerType * optimizer ) - { - m_Optimizer = optimizer; - m_Optimizer->AddObserver( itk::IterationEvent(), this ); - } - - /** Execute method will print data at each iteration */ - void Execute(itk::Object *caller, const itk::EventObject & event) - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object *, const itk::EventObject & event) - { - if( typeid( event ) == typeid( itk::StartEvent ) ) - { - std::cout << std::endl << "Position Value"; - std::cout << std::endl << std::endl; - } - else if( typeid( event ) == typeid( itk::IterationEvent ) ) - { - std::cout << m_Optimizer->GetCurrentIteration() << " "; - std::cout << m_Optimizer->GetValue() << " "; - std::cout << m_Optimizer->GetCurrentPosition() << std::endl; - } - else if( typeid( event ) == typeid( itk::EndEvent ) ) - { - std::cout << std::endl << std::endl; - std::cout << "After " << m_Optimizer->GetCurrentIteration(); - std::cout << " iterations " << std::endl; - std::cout << "Solution is = " << m_Optimizer->GetCurrentPosition(); - std::cout << std::endl; - } - } -// Software Guide : EndCodeSnippet - -protected: - IterationCallback() {}; - itk::WeakPointer m_Optimizer; -}; - -// Software Guide : BeginLatex -// -// This command will be invoked at every iteration of the optimizer and will -// print out the current combination of transform parameters. -// -// Software Guide : EndLatex - - -// Software Guide : BeginLatex -// -// Consider now the most critical component of this new registration -// approach: the metric. This component evaluates the match between the -// SpatialObject and the Image. The -// smoothness and regularity of the metric determine the difficulty of the -// task assigned to the optimizer. In this case, we use a very robust -// optimizer that should be able to find its way even in the most -// discontinuous cost functions. The metric to be implemented should derive -// from the ImageToSpatialObjectMetric class. -// -// The following code implements a simple metric that computes the sum of -// the pixels that are inside the spatial object. In fact, the metric -// maximum is obtained when the model and the image are aligned. The metric -// is templated over the type of the SpatialObject and the type of -// the Image. -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -template -class SimpleImageToSpatialObjectMetric : - public itk::ImageToSpatialObjectMetric -{ -// Software Guide : EndCodeSnippet - -public: - /** Standard class type aliases. */ - using Self = SimpleImageToSpatialObjectMetric; - using Superclass = - itk::ImageToSpatialObjectMetric; - using Pointer = itk::SmartPointer; - using ConstPointer = itk::SmartPointer; - - using PointType = itk::Point; - using PointListType = std::list; - using MovingSpatialObjectType = TMovingSpatialObject; - using ParametersType = typename Superclass::ParametersType; - using DerivativeType = typename Superclass::DerivativeType; - using MeasureType = typename Superclass::MeasureType; - - /** Method for creation through the object factory. */ - itkNewMacro(Self); - - /** Run-time type information (and related methods). */ - itkTypeMacro(SimpleImageToSpatialObjectMetric, ImageToSpatialObjectMetric); - - static constexpr unsigned int ParametricSpaceDimension = 3; - - /** Specify the moving spatial object. */ - void SetMovingSpatialObject( const MovingSpatialObjectType * object) - { - if(!this->m_FixedImage) - { - std::cout << "Please set the image before the moving spatial object" << std::endl; - return; - } - this->m_MovingSpatialObject = object; - m_PointList.clear(); - using myIteratorType = itk::ImageRegionConstIteratorWithIndex; - - myIteratorType it(this->m_FixedImage,this->m_FixedImage->GetBufferedRegion()); - - itk::Point point; - - while( !it.IsAtEnd() ) - { - this->m_FixedImage->TransformIndexToPhysicalPoint( it.GetIndex(), point ); - - if(this->m_MovingSpatialObject->IsInside(point,99999)) - { - m_PointList.push_back( point ); - } - ++it; - } - - std::cout << "Number of points in the metric = " << static_cast( m_PointList.size() ) << std::endl; - } - - /** Get the Derivatives of the Match Measure */ - void GetDerivative( const ParametersType &, DerivativeType & ) const - { - return; - } - - // Software Guide : BeginLatex - // - // The fundamental operation of the metric is its \code{GetValue()} method. - // It is in this method that the fitness value is computed. In our current - // example, the fitness is computed over the points of the - // SpatialObject. For each point, its coordinates are mapped - // through the transform into image space. The resulting point is used - // to evaluate the image and the resulting value is accumulated in a sum. - // Since we are not allowing scale changes, the optimal value of the sum - // will result when all the SpatialObject points are mapped on - // the white regions of the image. Note that the argument for the - // \code{GetValue()} method is the array of parameters of the transform. - // - // \index{Image\-To\-Spatial\-Object\-Metric!GetValue()} - // - // Software Guide : EndLatex - - /** Get the value for SingleValue optimizers. */ - // Software Guide : BeginCodeSnippet - MeasureType GetValue( const ParametersType & parameters ) const override - { - double value; - this->m_Transform->SetParameters( parameters ); - - value = 0; - for(PointListType::const_iterator it = m_PointList.begin(); - it != m_PointList.end(); ++it) - { - PointType transformedPoint = this->m_Transform->TransformPoint(*it); - if( this->m_Interpolator->IsInsideBuffer( transformedPoint ) ) - { - value += this->m_Interpolator->Evaluate( transformedPoint ); - } - } - return value; - } - // Software Guide : EndCodeSnippet - - /** Get Value and Derivatives for MultipleValuedOptimizers */ - void GetValueAndDerivative( const ParametersType & parameters, - MeasureType & Value, DerivativeType & Derivative ) const override - { - Value = this->GetValue(parameters); - this->GetDerivative(parameters,Derivative); - } - -private: - PointListType m_PointList; -}; - - -// Software Guide : BeginLatex -// -// Having defined all the registration components we are ready to put the -// pieces together and implement the registration process. -// -// Software Guide : EndLatex - - -int main( int argc, char *argv[] ) -{ - if( argc > 1 ) - { - std::cerr << "Too many parameters " << std::endl; - std::cerr << "Usage: " << argv[0] << std::endl; - } - - // Software Guide : BeginLatex - // - // First we instantiate the GroupSpatialObject and - // EllipseSpatialObject. These two objects are parameterized by - // the dimension of the space. In our current example a $2D$ instantiation - // is created. - // - // \index{Group\-Spatial\-Object!Instantiation} - // \index{Ellipse\-Spatial\-Object!Instantiation} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using GroupType = itk::GroupSpatialObject< 2 >; - using EllipseType = itk::EllipseSpatialObject< 2 >; - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The image is instantiated in the following lines using the pixel - // type and the space dimension. This image uses a \code{float} pixel - // type since we plan to blur it in order to increase the capture radius of - // the optimizer. Images of real pixel type behave better under blurring - // than those of integer pixel type. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using ImageType = itk::Image< float, 2 >; - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Here is where the fun begins! In the following lines we create the - // EllipseSpatialObjects using their \code{New()} methods, and - // assigning the results to SmartPointers. These lines will create - // three ellipses. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - EllipseType::Pointer ellipse1 = EllipseType::New(); - EllipseType::Pointer ellipse2 = EllipseType::New(); - EllipseType::Pointer ellipse3 = EllipseType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Every class deriving from SpatialObject has particular - // parameters enabling the user to tailor its shape. In the case of the - // EllipseSpatialObject, \code{SetRadius()} is used to - // define the ellipse size. An additional \code{SetRadius(Array)} method - // allows the user to define the ellipse axes independently. - // - // \index{itk::EllipseSpatialObject!SetRadius()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - ellipse1->SetRadius( 10.0 ); - ellipse2->SetRadius( 10.0 ); - ellipse3->SetRadius( 10.0 ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The ellipses are created centered in space by default. We use the - // following lines of code to arrange the ellipses in a triangle. - // The spatial transform intrinsically associated with the object is - // accessed by the \code{GetTransform()} method. This transform can define - // a translation in space with the \code{SetOffset()} method. We take - // advantage of this feature to place the ellipses at particular - // points in space. - // - // Software Guide : EndLatex - - // Place each ellipse at the right position to form a triangle - - // Software Guide : BeginCodeSnippet - EllipseType::TransformType::OffsetType offset; - offset[ 0 ] = 100.0; - offset[ 1 ] = 40.0; - - ellipse1->GetObjectToParentTransform()->SetOffset(offset); - ellipse1->Update(); - - offset[ 0 ] = 40.0; - offset[ 1 ] = 150.0; - ellipse2->GetObjectToParentTransform()->SetOffset(offset); - ellipse2->Update(); - - offset[ 0 ] = 150.0; - offset[ 1 ] = 150.0; - ellipse3->GetObjectToParentTransform()->SetOffset(offset); - ellipse3->Update(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Note that after a change has been made in the transform, the - // SpatialObject invokes the method - // \code{ComputeGlobalTransform()} in order to update its global - // transform. The reason for doing this is that SpatialObjects - // can be arranged in hierarchies. It is then possible to change the - // position of a set of spatial objects by moving the parent of the group. - // - // Software Guide : EndLatex - - // Software Guide : BeginLatex - // - // Now we add the three EllipseSpatialObjects to a - // GroupSpatialObject that will be subsequently passed on to the - // registration method. The GroupSpatialObject facilitates the - // management of the three ellipses as a higher level structure - // representing a complex shape. Groups can be nested any number of levels - // in order to represent shapes with higher detail. - // - // \index{itk::GroupSpatialObject!New()} - // \index{itk::GroupSpatialObject!Pointer} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - GroupType::Pointer group = GroupType::New(); - group->AddSpatialObject( ellipse1 ); - group->AddSpatialObject( ellipse2 ); - group->AddSpatialObject( ellipse3 ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Having the geometric model ready, we proceed to generate the binary - // image representing the imprint of the space occupied by the ellipses. - // The SpatialObjectToImageFilter is used to that end. Note that - // this filter is instantiated over the spatial object used and the image - // type to be generated. - // - // - // \index{itk::Spatial\-Object\-To\-Image\-Filter!Instantiation} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using SpatialObjectToImageFilterType = - itk::SpatialObjectToImageFilter< GroupType, ImageType >; - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // With the defined type, we construct a filter using the \code{New()} - // method. The newly created filter is assigned to a SmartPointer. - // - // \index{itk::SpatialObjectToImageFilter!New()} - // \index{itk::SpatialObjectToImageFilter!Pointer} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - SpatialObjectToImageFilterType::Pointer imageFilter = - SpatialObjectToImageFilterType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The GroupSpatialObject is passed as input to the filter. - // - // \index{itk::SpatialObjectToImageFilter!SetInput()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - imageFilter->SetInput( group ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The \doxygen{SpatialObjectToImageFilter} acts as a resampling filter. - // Therefore it requires the user to define the size of the desired output - // image. This is specified with the \code{SetSize()} method. - // - // \index{itk::SpatialObjectToImageFilter!SetSize()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - ImageType::SizeType size; - size[ 0 ] = 200; - size[ 1 ] = 200; - imageFilter->SetSize( size ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Finally we trigger the execution of the filter by calling the - // \code{Update()} method. - // - // \index{itk::SpatialObjectToImageFilter!Update()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - imageFilter->Update(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // In order to obtain a smoother metric, we blur the image using a - // \doxygen{DiscreteGaussianImageFilter}. This extends the capture radius - // of the metric and produce a more continuous cost function to - // optimize. The following lines instantiate the Gaussian filter and - // create one object of this type using the \code{New()} method. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using GaussianFilterType = - itk::DiscreteGaussianImageFilter< ImageType, ImageType >; - GaussianFilterType::Pointer gaussianFilter = GaussianFilterType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The output of the SpatialObjectToImageFilter is connected as - // input to the DiscreteGaussianImageFilter. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - gaussianFilter->SetInput( imageFilter->GetOutput() ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The variance of the filter is defined as a large value in order to - // increase the capture radius. Finally the execution of the filter is - // triggered using the \code{Update()} method. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - constexpr double variance = 20; - gaussianFilter->SetVariance(variance); - gaussianFilter->Update(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Below we instantiate the type of the - // \doxygen{ImageToSpatialObjectRegistrationMethod} method and instantiate a - // registration object with the \code{New()} method. Note that the - // registration type is templated over the Image and the - // SpatialObject types. The spatial object in this case is the - // group of spatial objects. - // - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!Instantiation} - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!New()} - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!Pointer} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using RegistrationType = - itk::ImageToSpatialObjectRegistrationMethod< ImageType, GroupType >; - RegistrationType::Pointer registration = RegistrationType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Now we instantiate the metric that is templated over - // the image type and the spatial object type. As usual, the \code{New()} - // method is used to create an object. - // - // \index{itk::Image\-To\-Spatial\-Object\-Metric!Instantiation} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using MetricType = SimpleImageToSpatialObjectMetric< ImageType, GroupType >; - MetricType::Pointer metric = MetricType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // An interpolator will be needed to evaluate the image at non-grid - // positions. Here we instantiate a linear interpolator type. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using InterpolatorType = - itk::LinearInterpolateImageFunction< ImageType, double >; - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The following lines instantiate the evolutionary optimizer. - // - // \index{itk::One\-Plus\-One\-Evolutionary\-Optimizer!Instantiation} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using OptimizerType = itk::OnePlusOneEvolutionaryOptimizer; - OptimizerType::Pointer optimizer = OptimizerType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Next, we instantiate the transform class. In this case we use the - // Euler2DTransform that implements a rigid transform in $2D$ - // space. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using TransformType = itk::Euler2DTransform<>; - TransformType::Pointer transform = TransformType::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Evolutionary algorithms are based on testing random variations - // of parameters. In order to support the computation of random values, - // ITK provides a family of random number generators. In this example, we - // use the \doxygen{NormalVariateGenerator} which generates values with a - // normal distribution. - // - // \index{itk::NormalVariateGenerator!New()} - // \index{itk::NormalVariateGenerator!Pointer} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - itk::Statistics::NormalVariateGenerator::Pointer generator - = itk::Statistics::NormalVariateGenerator::New(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The random number generator must be initialized with a seed. - // - // \index{itk::NormalVariateGenerator!Initialize()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - generator->Initialize(12345); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The OnePlusOneEvolutionaryOptimizer is initialized by - // specifying the random number generator, the number of samples for the - // initial population and the maximum number of iterations. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->SetNormalVariateGenerator( generator ); - optimizer->Initialize( 10 ); - optimizer->SetMaximumIteration( 400 ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // As in previous registration examples, we take care to normalize the - // dynamic range of the different transform parameters. In particular, the - // we must compensate for the ranges of the angle and translations of the Euler2DTransform. - // In order to achieve this goal, we provide an array - // of scales to the optimizer. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - TransformType::ParametersType parametersScale; - parametersScale.set_size(3); - parametersScale[0] = 1000; // angle scale - - for( unsigned int i=1; i<3; i++ ) - { - parametersScale[i] = 2; // offset scale - } - optimizer->SetScales( parametersScale ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Here we instantiate the Command object that will act as an - // observer of the registration method and print out parameters at each - // iteration. Earlier, we defined this command as a class templated over the - // optimizer type. Once it is created with the \code{New()} method, we - // connect the optimizer to the command. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using IterationCallbackType = IterationCallback< OptimizerType >; - IterationCallbackType::Pointer callback = IterationCallbackType::New(); - callback->SetOptimizer( optimizer ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // All the components are plugged into the - // ImageToSpatialObjectRegistrationMethod object. The typical - // \code{Set()} methods are used here. Note the use of the - // \code{SetMovingSpatialObject()} method for connecting the spatial object. - // We provide the blurred version of the original synthetic binary - // image as the input image. - // - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!SetFixedImage()} - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!SetMovingSpatialObject()} - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!SetTransform()} - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!SetInterpolator()} - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!SetOptimizer()} - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!SetMetric()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - registration->SetFixedImage( gaussianFilter->GetOutput() ); - registration->SetMovingSpatialObject( group ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - registration->SetOptimizer( optimizer ); - registration->SetMetric( metric ); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The initial set of transform parameters is passed to the registration - // method using the \code{SetInitialTransformParameters()} method. Note that - // since our original model is already registered with the synthetic image, - // we introduce an artificial mis-registration in order to initialize - // the optimization at some point away from the optimal value. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - TransformType::ParametersType initialParameters( - transform->GetNumberOfParameters() ); - - initialParameters[0] = 0.2; // Angle - initialParameters[1] = 7.0; // Offset X - initialParameters[2] = 6.0; // Offset Y - registration->SetInitialTransformParameters(initialParameters); - // Software Guide : EndCodeSnippet - - std::cout << "Initial Parameters : " << initialParameters << std::endl; - - // Software Guide : BeginLatex - // - // Due to the character of the metric used to evaluate the fitness - // between the spatial object and the image, we must tell the optimizer that - // we are interested in finding the maximum value of the metric. Some - // metrics associate low numeric values with good matching, while others associate - // high numeric values with good matching. The \code{MaximizeOn()} and - // \code{MaximizeOff()} methods allow the user to deal with both types of - // metrics. - // - // \index{itk::Optimizer!MaximizeOn()} - // \index{itk::Optimizer!MaximizeOff()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->MaximizeOn(); - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Finally, we trigger the execution of the registration process with the - // \code{Update()} method. We place this call in a - // \code{try/catch} block in case any exception is thrown during the - // process. - // - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!Update()} - // - // Software Guide : EndLatex - - - // Software Guide : BeginCodeSnippet - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & exp ) - { - std::cerr << "Exception caught ! " << std::endl; - std::cerr << exp << std::endl; - } - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // The set of transform parameters resulting from the registration can be - // recovered with the \code{GetLastTransformParameters()} method. This - // method returns the array of transform parameters that should be - // interpreted according to the implementation of each transform. In our - // current example, the Euler2DTransform has three parameters: - // the rotation angle, the translation in $x$ and the translation in $y$. - // - // \index{itk::Image\-To\-Spatial\-Object\-Registration\-Method!Update()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - RegistrationType::ParametersType finalParameters - = registration->GetLastTransformParameters(); - - std::cout << "Final Solution is : " << finalParameters << std::endl; - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // \begin{figure} - // \center - // \includegraphics[height=0.44\textwidth]{ModelToImageRegistrationTraceAngle} - // \includegraphics[height=0.44\textwidth]{ModelToImageRegistrationTraceTranslations} - // \itkcaption[SpatialObject to Image Registration results]{Plots of the - // angle and translation parameters for a registration process between an - // spatial object and an image.} - // \label{fig:ModelToImageRegistrationPlots} - // \end{figure} - // - // The results are presented in - // Figure~\ref{fig:ModelToImageRegistrationPlots}. The left side shows the - // evolution of the angle parameter as a function of iteration - // numbers, while the right side shows the $(x,y)$ translation. - // - // Software Guide : EndLatex - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/ModelToImageRegistration2.cxx b/Examples/RegistrationITKv3/ModelToImageRegistration2.cxx deleted file mode 100644 index 5eab1afd2e9..00000000000 --- a/Examples/RegistrationITKv3/ModelToImageRegistration2.cxx +++ /dev/null @@ -1,372 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginLatex -// -// This example illustrates the use of the \doxygen{SpatialObject} as a -// component of the registration framework in order to perform model based -// registration. In this case, a SpatialObject is used for generating a -// \doxygen{PointSet} whose points are located in a narrow band around the -// edges of the SpatialObject. This PointSet is then used in order to perform -// PointSet to Image registration. -// -// Software Guide : EndLatex - - -// Software Guide : BeginLatex -// -// In this example we use the \doxygen{BoxSpatialObject}, that is one of the -// simplest SpatialObjects in ITK. -// -// \index{itk::BoxSpatialObject!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkBoxSpatialObject.h" -// Software Guide : EndCodeSnippet - - -// Software Guide : BeginLatex -// -// The generation of the PointSet is done in two stages. First the -// SpatialObject is rasterized in order to generate an image containing a -// binary mask that represents the inside and outside of the SpatialObject. -// Second, this mask is used for computing a distance map, and the points -// close to the boundary of the mask are taken as elements of the final -// PointSet. The pixel values associated to the point in the PointSet are the -// values of distance from each point to the binary mask. The first stage is -// performed by the \doxygen{SpatialObjectToImageFilter}, while the second -// stage is performed witht eh \doxygen{BinaryMaskToNarrowBandPointSetFilter} -// -// \index{itk::Spatial\-Object\-To\-Image\-Filter!header} -// \index{itk::Binary\-Mask\-To\-Narrow\-Band\-Point\-Set\-Filter!header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkSpatialObjectToImageFilter.h" -#include "itkBinaryMaskToNarrowBandPointSetFilter.h" -// Software Guide : EndCodeSnippet - -#include "itkBinaryMaskToNarrowBandPointSetFilter.h" - -#include "itkPointSet.h" -#include "itkPointSetToImageRegistrationMethod.h" -#include "itkNormalizedCorrelationPointSetToImageMetric.h" -#include "itkNearestNeighborInterpolateImageFunction.h" -#include "itkRigid2DTransform.h" -#include "itkRegularStepGradientDescentOptimizer.h" -#include "itkResampleImageFilter.h" - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -// -// Observer to the optimizer -// -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( typeid( event ) != typeid( itk::IterationEvent ) ) - { - return; - } - - OptimizerType::DerivativeType gradient = optimizer->GetGradient(); - OptimizerType::ScalesType scales = optimizer->GetScales(); - - double magnitude2 = 0.0; - - for(unsigned int i=0; iGetCurrentIteration() << " "; - std::cout << optimizer->GetValue() << " "; - std::cout << gradientMagnitude << " "; - std::cout << optimizer->GetCurrentPosition() << std::endl; - } -}; - -int main( int argc, char * argv [] ) -{ - - if( argc < 2 ) - { - std::cerr << "Missing argument" << std::endl; - std::cerr << "Usage: " << std::endl; - std::cerr << argv[0] << " movingImageFileName [initialX initialY] " << std::endl; - std::cerr << "[rasterizedObjectFileName] [BoxSizeX BoxSizeY]" << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - - using MaskPixelType = unsigned char; - - using MaskImageType = itk::Image< MaskPixelType, Dimension >; - - - using SpatialObjectType = itk::BoxSpatialObject< Dimension >; - - using SpatialObjectToImageFilterType = itk::SpatialObjectToImageFilter< - SpatialObjectType, MaskImageType >; - - using FixedPointSetType = itk::PointSet< float, Dimension >; - - - using NarrowBandFilterType = itk::BinaryMaskToNarrowBandPointSetFilter< - MaskImageType, FixedPointSetType >; - - using PixelType = signed short; - - using ImageType = itk::Image< PixelType, Dimension >; - - using MaskPixelType = unsigned char; - - using MaskImageType = itk::Image< MaskPixelType, Dimension >; - - - using TransformType = itk::Rigid2DTransform< double >; - - using ParametersType = TransformType::ParametersType; - - - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - - using LinearInterpolatorType = itk::LinearInterpolateImageFunction< - ImageType, - double >; - - - using MetricType = itk::NormalizedCorrelationPointSetToImageMetric< - FixedPointSetType, - ImageType >; - - - using OptimizerScalesType = OptimizerType::ScalesType; - - - using RegistrationType = itk::PointSetToImageRegistrationMethod< - FixedPointSetType, - ImageType >; - - - using IterationObserverType = CommandIterationUpdate; - - using ImageReaderType = itk::ImageFileReader< ImageType >; - - SpatialObjectType::Pointer spatialObject; - TransformType::Pointer transform; - OptimizerType::Pointer optimizer; - IterationObserverType::Pointer iterationObserver; - LinearInterpolatorType::Pointer linearInterpolator; - MetricType::Pointer metric; - RegistrationType::Pointer registrationMethod; - ImageReaderType::Pointer movingImageReader; - FixedPointSetType::Pointer fixedPointSet; - ImageType::ConstPointer movingImage; - - SpatialObjectToImageFilterType::Pointer rasterizationFilter; - NarrowBandFilterType::Pointer narrowBandPointSetFilter; - - - metric = MetricType::New(); - transform = TransformType::New(); - optimizer = OptimizerType::New(); - linearInterpolator = LinearInterpolatorType::New(); - registrationMethod = RegistrationType::New(); - iterationObserver = IterationObserverType::New(); - - spatialObject = SpatialObjectType::New(); - rasterizationFilter = SpatialObjectToImageFilterType::New(); - narrowBandPointSetFilter = NarrowBandFilterType::New(); - - movingImageReader = ImageReaderType::New(); - - movingImageReader->SetFileName( argv[1] ); - - try - { - movingImageReader->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Problem reading Moving image from = " << std::endl; - std::cerr << argv[1] << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - movingImage = movingImageReader->GetOutput(); - - SpatialObjectType::SizeType boxSize; - boxSize[0] = 60.0; // mm - boxSize[1] = 60.0; // mm - - if( argc > 6 ) - { - boxSize[0] = std::stod( argv[5] ); - boxSize[1] = std::stod( argv[6] ); - } - - // - // The geometry of the BoxSpatialObject is such that one of - // its corners is located at the origin of coordinates. - // - spatialObject->SetSize( boxSize ); - - ImageType::RegionType region = - movingImage->GetLargestPossibleRegion(); - - ImageType::SizeType imageSize = region.GetSize(); - - ImageType::SpacingType spacing = movingImage->GetSpacing(); - ImageType::PointType origin; - origin[0] = ( boxSize[0] - imageSize[0] * spacing[0] ) / 2.0; - origin[1] = ( boxSize[1] - imageSize[1] * spacing[1] ) / 2.0; - - rasterizationFilter->SetInput( spatialObject ); - rasterizationFilter->SetSize( imageSize ); - rasterizationFilter->SetSpacing( spacing ); - rasterizationFilter->SetOrigin( origin ); - - - narrowBandPointSetFilter->SetBandWidth( 5.0 ); - - narrowBandPointSetFilter->SetInput( - rasterizationFilter->GetOutput() ); - - narrowBandPointSetFilter->Update(); - - if( argc > 4 ) - { - using MaskWriterType = itk::ImageFileWriter< MaskImageType >; - MaskWriterType::Pointer maskWriter = MaskWriterType::New(); - maskWriter->SetInput( rasterizationFilter->GetOutput() ); - maskWriter->SetFileName( argv[4] ); - maskWriter->Update(); - } - - fixedPointSet = narrowBandPointSetFilter->GetOutput(); - - fixedPointSet->Print( std::cout ); - - registrationMethod->SetOptimizer( optimizer ); - registrationMethod->SetInterpolator( linearInterpolator ); - registrationMethod->SetMetric( metric ); - registrationMethod->SetTransform( transform ); - - registrationMethod->SetMovingImage( movingImage ); - registrationMethod->SetFixedPointSet( fixedPointSet ); - - - optimizer->SetMaximumStepLength( 1.00 ); - optimizer->SetMinimumStepLength( 0.001 ); - optimizer->SetNumberOfIterations( 300 ); - optimizer->SetRelaxationFactor( 0.90 ); - optimizer->SetGradientMagnitudeTolerance( 0.05 ); - optimizer->MinimizeOn(); - optimizer->AddObserver( itk::IterationEvent(), iterationObserver ); - - TransformType::TranslationType initialTranslation; - initialTranslation[0] = 0.0; - initialTranslation[1] = 0.0; - - if( argc >= 4 ) - { - initialTranslation[0] = std::stod( argv[2] ); - initialTranslation[1] = std::stod( argv[3] ); - } - - - TransformType::OutputPointType rotationCenter; - rotationCenter[0] = boxSize[0] / 2.0; - rotationCenter[1] = boxSize[1] / 2.0; - - transform->SetIdentity(); - transform->SetCenter( rotationCenter ); - transform->SetTranslation( initialTranslation ); - - registrationMethod->SetInitialTransformParameters( - transform->GetParameters() ); - - OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() ); - - const double translationScale = 1.0 / 1000.0; - - optimizerScales[0] = 1.0; - optimizerScales[1] = translationScale; - optimizerScales[2] = translationScale; - - optimizer->SetScales( optimizerScales ); - - try - { - registrationMethod->Update(); - std::cout << "Optimizer stop condition: " - << registrationMethod->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Problem found during the registration" << std::endl; - std::cerr << argv[1] << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - ParametersType transformParameters = - registrationMethod->GetLastTransformParameters(); - - - TransformType::OutputPointType center = transform->GetCenter(); - - std::cout << "Registration parameter = " << std::endl; - std::cout << "Rotation center = " << center << std::endl; - std::cout << "Parameters = " << transformParameters << std::endl; - - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/MultiResImageRegistration2.cxx b/Examples/RegistrationITKv3/MultiResImageRegistration2.cxx deleted file mode 100644 index ca3dea85e38..00000000000 --- a/Examples/RegistrationITKv3/MultiResImageRegistration2.cxx +++ /dev/null @@ -1,633 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Software Guide : BeginCommandLineArgs -// INPUTS: {BrainT1SliceBorder20.png} -// INPUTS: {BrainProtonDensitySliceShifted13x17y.png} -// OUTPUTS: {MultiResImageRegistration2Output.png} -// ARGUMENTS: 100 -// OUTPUTS: {MultiResImageRegistration2CheckerboardBefore.png} -// OUTPUTS: {MultiResImageRegistration2CheckerboardAfter.png} -// Software Guide : EndCommandLineArgs - -// Software Guide : BeginLatex -// -// This example illustrates the use of more complex components of the -// registration framework. In particular, it introduces the use of the -// \doxygen{AffineTransform} and the importance of fine-tuning the scale -// parameters of the optimizer. -// -// \index{itk::ImageRegistrationMethod!AffineTransform} -// \index{itk::ImageRegistrationMethod!Scaling parameter space} -// \index{itk::AffineTransform!Image Registration} -// -// The AffineTransform is a linear transformation that maps lines into -// lines. It can be used to represent translations, rotations, anisotropic -// scaling, shearing or any combination of them. Details about the affine -// transform can be seen in Section~\ref{sec:AffineTransform}. -// -// In order to use the AffineTransform class, the following header -// must be included. -// -// \index{itk::AffineTransform!Header} -// -// Software Guide : EndLatex - -// Software Guide : BeginCodeSnippet -#include "itkAffineTransform.h" -// Software Guide : EndCodeSnippet - -#include "itkCenteredTransformInitializer.h" -#include "itkMultiResolutionImageRegistrationMethod.h" -#include "itkMattesMutualInformationImageToImageMetric.h" -#include "itkRegularStepGradientDescentOptimizer.h" -#include "itkRecursiveMultiResolutionPyramidImageFilter.h" -#include "itkImage.h" - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkCheckerBoardImageFilter.h" - -// The following section of code implements an observer -// that will monitor the evolution of the registration process. -// -#include "itkCommand.h" -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate(): m_CumulativeIterationIndex(0) {}; - -public: - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) override - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - std::cout << optimizer->GetCurrentIteration() << " "; - std::cout << optimizer->GetValue() << " "; - std::cout << optimizer->GetCurrentPosition() << " " << - m_CumulativeIterationIndex++ << std::endl; - } - -private: - unsigned int m_CumulativeIterationIndex; -}; - -// The following section of code implements a Command observer -// that will control the modification of optimizer parameters -// at every change of resolution level. -// -template -class RegistrationInterfaceCommand : public itk::Command -{ -public: - using Self = RegistrationInterfaceCommand; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - RegistrationInterfaceCommand() {}; - -public: - using RegistrationType = TRegistration; - using RegistrationPointer = RegistrationType *; - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = OptimizerType *; - void Execute(itk::Object * object, const itk::EventObject & event) - { - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - RegistrationPointer registration = static_cast( object ); - OptimizerPointer optimizer = static_cast< OptimizerPointer >(registration->GetModifiableOptimizer() ); - - std::cout << "-------------------------------------" << std::endl; - std::cout << "MultiResolution Level : " - << registration->GetCurrentLevel() << std::endl; - std::cout << std::endl; - - if ( registration->GetCurrentLevel() == 0 ) - { - optimizer->SetMaximumStepLength( 16.00 ); - optimizer->SetMinimumStepLength( 0.01 ); - } - else - { - optimizer->SetMaximumStepLength( optimizer->GetMaximumStepLength() / 4.0 ); - optimizer->SetMinimumStepLength( optimizer->GetMinimumStepLength() / 10.0 ); - } - } - void Execute(const itk::Object * , const itk::EventObject & ) - { return; } -}; - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImagefile [backgroundGrayLevel]"; - std::cerr << " [checkerboardbefore] [CheckerBoardAfter]"; - std::cerr << " [useExplicitPDFderivatives ] " << std::endl; - std::cerr << " [numberOfBins] [numberOfSamples ] " << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 2; - using PixelType = unsigned short; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - using InternalPixelType = float; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - - // Software Guide : BeginLatex - // - // The configuration of the registration method in this example closely - // follows the procedure in the previous section. The main changes involve the - // construction and initialization of the transform. The instantiation of - // the transform type requires only the dimension of the space and the - // type used for representing space coordinates. - // - // \index{itk::AffineTransform!Instantiation} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using TransformType = itk::AffineTransform< double, Dimension >; - // Software Guide : EndCodeSnippet - - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using InterpolatorType = itk::LinearInterpolateImageFunction< - InternalImageType, - double >; - using MetricType = itk::MattesMutualInformationImageToImageMetric< - InternalImageType, - InternalImageType >; - - using OptimizerScalesType = OptimizerType::ScalesType; - - using RegistrationType = itk::MultiResolutionImageRegistrationMethod< - InternalImageType, - InternalImageType >; - - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - MetricType::Pointer metric = MetricType::New(); - - registration->SetOptimizer( optimizer ); - registration->SetInterpolator( interpolator ); - registration->SetMetric( metric ); - - // Software Guide : BeginLatex - // - // The transform is constructed using the standard \code{New()} method and - // assigning it to a SmartPointer. - // - // \index{itk::AffineTransform!New()} - // \index{itk::AffineTransform!Pointer} - // \index{itk::Multi\-Resolution\-Image\-Registration\-Method!SetTransform()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - TransformType::Pointer transform = TransformType::New(); - registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - using FixedCastFilterType = itk::CastImageFilter< - FixedImageType, InternalImageType >; - using MovingCastFilterType = itk::CastImageFilter< - MovingImageType, InternalImageType >; - FixedCastFilterType::Pointer fixedCaster = FixedCastFilterType::New(); - MovingCastFilterType::Pointer movingCaster = MovingCastFilterType::New(); - - fixedCaster->SetInput( fixedImageReader->GetOutput() ); - movingCaster->SetInput( movingImageReader->GetOutput() ); - - registration->SetFixedImage( fixedCaster->GetOutput() ); - registration->SetMovingImage( movingCaster->GetOutput() ); - - fixedCaster->Update(); - - registration->SetFixedImageRegion( - fixedCaster->GetOutput()->GetBufferedRegion() ); - - // Software Guide : BeginLatex - // - // One of the easiest ways of preparing a consistent set of parameters for - // the transform is to use the \doxygen{CenteredTransformInitializer}. Once - // the transform is initialized, we can invoke its \code{GetParameters()} - // method to extract the array of parameters. Finally the array is passed to - // the registration method using its \code{SetInitialTransformParameters()} - // method. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - using TransformInitializerType = itk::CenteredTransformInitializer< - TransformType, FixedImageType, - MovingImageType >; - TransformInitializerType::Pointer initializer - = TransformInitializerType::New(); - initializer->SetTransform( transform ); - initializer->SetFixedImage( fixedImageReader->GetOutput() ); - initializer->SetMovingImage( movingImageReader->GetOutput() ); - initializer->MomentsOn(); - initializer->InitializeTransform(); - registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // The set of parameters in the AffineTransform have different - // dynamic ranges. Typically the parameters associated with the matrix - // have values around $[-1:1]$, although they are not restricted to this - // interval. Parameters associated with translations, on the other hand, - // tend to have much higher values, typically in the order of $10.0$ to - // $100.0$. This difference in dynamic range negatively affects the - // performance of gradient descent optimizers. ITK provides a mechanism to - // compensate for such differences in values among the parameters when - // they are passed to the optimizer. The mechanism consists of providing an - // array of scale factors to the optimizer. These factors re-normalize the - // gradient components before they are used to compute the step of the - // optimizer at the current iteration. In our particular case, a common - // choice for the scale parameters is to set to $1.0$ all those associated - // with the matrix coefficients, that is, the first $N \times N$ - // factors. Then, we set the remaining scale factors to a small value. The - // following code sets up the scale coefficients. - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() ); - - optimizerScales[0] = 1.0; // scale for M11 - optimizerScales[1] = 1.0; // scale for M12 - optimizerScales[2] = 1.0; // scale for M21 - optimizerScales[3] = 1.0; // scale for M22 - - optimizerScales[4] = 1.0 / 1e7; // scale for translation on X - optimizerScales[5] = 1.0 / 1e7; // scale for translation on Y - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // - // Here the affine transform is represented by the matrix $\bf{M}$ and the - // vector $\bf{T}$. The transformation of a point $\bf{P}$ into $\bf{P'}$ - // is expressed as - // - // \begin{equation} - // \left[ - // \begin{array}{c} - // {P'}_x \\ {P'}_y \\ \end{array} - // \right] - // = - // \left[ - // \begin{array}{cc} - // M_{11} & M_{12} \\ M_{21} & M_{22} \\ \end{array} - // \right] - // \cdot - // \left[ - // \begin{array}{c} - // P_x \\ P_y \\ \end{array} - // \right] - // + - // \left[ - // \begin{array}{c} - // T_x \\ T_y \\ \end{array} - // \right] - // \end{equation} - // - // - // Software Guide : EndLatex - - // Software Guide : BeginLatex - // - // The array of scales is then passed to the optimizer using the - // \code{SetScales()} method. - // - // \index{itk::Optimizer!SetScales()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - optimizer->SetScales( optimizerScales ); - // Software Guide : EndCodeSnippet - - metric->SetNumberOfHistogramBins( 128 ); - metric->SetNumberOfSpatialSamples( 50000 ); - - if( argc > 8 ) - { - // optionally, override the values with numbers taken from the command line arguments. - metric->SetNumberOfHistogramBins( std::stoi( argv[8] ) ); - } - - if( argc > 9 ) - { - // optionally, override the values with numbers taken from the command line arguments. - metric->SetNumberOfSpatialSamples( std::stoi( argv[9] ) ); - } - - // Software Guide : BeginLatex - // - // Given that the Mattes Mutual Information metric uses a random iterator in - // order to collect the samples from the images, it is usually convenient to - // initialize the seed of the random number generator. - // - // \index{itk::Mattes\-Mutual\-Information\-Image\-To\-Image\-Metric!ReinitializeSeed()} - // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - metric->ReinitializeSeed( 76926294 ); - // Software Guide : EndCodeSnippet - - if( argc > 7 ) - { - // Define whether to calculate the metric derivative by explicitly - // computing the derivatives of the joint PDF with respect to the Transform - // parameters, or doing it by progressively accumulating contributions from - // each bin in the joint PDF. - metric->SetUseExplicitPDFDerivatives( std::stoi( argv[7] ) ); - } - - // Software Guide : BeginLatex - // - // The step length has to be proportional to the expected values of the - // parameters in the search space. Since the expected values of the matrix - // coefficients are around $1.0$, the initial step of the optimization - // should be a small number compared to $1.0$. As a guideline, it is - // useful to think of the matrix coefficients as combinations of - // $cos(\theta)$ and $sin(\theta)$. This leads to use values close to the - // expected rotation measured in radians. For example, a rotation of $1.0$ - // degree is about $0.017$ radians. As in the previous example, the - // maximum and minimum step length of the optimizer are set by the - // \code{RegistrationInterfaceCommand} when it is called at the beginning - // of registration at each multi-resolution level. - // - // Software Guide : EndLatex - - optimizer->SetNumberOfIterations( 200 ); - optimizer->SetRelaxationFactor( 0.8 ); - - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - // Create the Command interface observer and register it with the optimizer. - // - using CommandType = RegistrationInterfaceCommand; - CommandType::Pointer command = CommandType::New(); - registration->AddObserver( itk::IterationEvent(), command ); - registration->SetNumberOfLevels( 3 ); - - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - std::cout << "Optimizer Stopping Condition = " - << optimizer->GetStopCondition() << std::endl; - - using ParametersType = RegistrationType::ParametersType; - ParametersType finalParameters = registration->GetLastTransformParameters(); - - double TranslationAlongX = finalParameters[4]; - double TranslationAlongY = finalParameters[5]; - - unsigned int numberOfIterations = optimizer->GetCurrentIteration(); - - double bestValue = optimizer->GetValue(); - - // Print out results - // - std::cout << "Result = " << std::endl; - std::cout << " Translation X = " << TranslationAlongX << std::endl; - std::cout << " Translation Y = " << TranslationAlongY << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - - // Software Guide : BeginLatex - // - // Let's execute this example using the same multi-modality images as - // before. The registration converges after $5$ iterations in the first - // level, $7$ in the second level and $4$ in the third level. The final - // results when printed as an array of parameters are - // - // \begin{verbatim} - // [1.00164, 0.00147688, 0.00168372, 1.0027, 12.6296, 16.4768] - // \end{verbatim} - // - // By reordering them as coefficient of matrix $\bf{M}$ and vector $\bf{T}$ - // they can now be seen as - // - // \begin{equation} - // M = - // \left[ - // \begin{array}{cc} - // 1.00164 & 0.0014 \\ 0.00168 & 1.0027 \\ \end{array} - // \right] - // \mbox{ and } - // T = - // \left[ - // \begin{array}{c} - // 12.6296 \\ 16.4768 \\ \end{array} - // \right] - // \end{equation} - // - // In this form, it is easier to interpret the effect of the - // transform. The matrix $\bf{M}$ is responsible for scaling, rotation and - // shearing while $\bf{T}$ is responsible for translations. It can be seen - // that the translation values in this case closely match the true - // misalignment introduced in the moving image. - // - // It is important to note that once the images are registered at a - // sub-pixel level, any further improvement of the registration relies - // heavily on the quality of the interpolator. It may then be reasonable to - // use a coarse and fast interpolator in the lower resolution levels and - // switch to a high-quality but slow interpolator in the final resolution - // level. - // - // Software Guide : EndLatex - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - TransformType::Pointer finalTransform = TransformType::New(); - - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - PixelType backgroundGrayLevel = 100; - if( argc > 4 ) - { - backgroundGrayLevel = std::stoi( argv[4] ); - } - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( backgroundGrayLevel ); - - using OutputPixelType = unsigned char; - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - using WriterType = itk::ImageFileWriter< OutputImageType >; - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - writer->SetFileName( argv[3] ); - - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - // Software Guide : BeginLatex - // - // \begin{figure} - // \center - // \includegraphics[width=0.32\textwidth]{MultiResImageRegistration2Output} - // \includegraphics[width=0.32\textwidth]{MultiResImageRegistration2CheckerboardBefore} - // \includegraphics[width=0.32\textwidth]{MultiResImageRegistration2CheckerboardAfter} - // \itkcaption[Multi-Resolution Registration Input Images]{Mapped moving image - // (left) and composition of fixed and moving images before (center) and - // after (right) multi-resolution registration with the AffineTransform class.} - // \label{fig:MultiResImageRegistration2Output} - // \end{figure} - // - // The result of resampling the moving image is shown in the left image - // of Figure \ref{fig:MultiResImageRegistration2Output}. The center and - // right images of the figure present a checkerboard composite of the fixed - // and moving images before and after registration. - // - // Software Guide : EndLatex - - // Software Guide : BeginLatex - // - // \begin{figure} - // \center - // \includegraphics[height=0.44\textwidth]{MultiResImageRegistration2TraceTranslations} - // \includegraphics[height=0.44\textwidth]{MultiResImageRegistration2TraceMetric} - // \itkcaption[Multi-Resolution Registration output plots]{Sequence of - // translations and metric values at each iteration of the optimizer for - // multi-resolution with the AffineTransform class.} - // \label{fig:MultiResImageRegistration2Trace} - // \end{figure} - // - // Figure \ref{fig:MultiResImageRegistration2Trace} (left) presents the - // sequence of translations followed by the optimizer as it searched the - // parameter space. The right side of the same figure shows the sequence of - // metric values computed as the optimizer explored the parameter space. - // - // Software Guide : EndLatex - - // - // Generate checkerboards before and after registration - // - using CheckerBoardFilterType = itk::CheckerBoardImageFilter< FixedImageType >; - - CheckerBoardFilterType::Pointer checker = CheckerBoardFilterType::New(); - - checker->SetInput1( fixedImage ); - checker->SetInput2( resample->GetOutput() ); - - caster->SetInput( checker->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - - resample->SetDefaultPixelValue( 0 ); - - // Write out checkerboard outputs - // Before registration - TransformType::Pointer identityTransform = TransformType::New(); - identityTransform->SetIdentity(); - resample->SetTransform( identityTransform ); - - if( argc > 5 ) - { - writer->SetFileName( argv[5] ); - writer->Update(); - } - - // After registration - resample->SetTransform( finalTransform ); - if( argc > 6 ) - { - writer->SetFileName( argv[6] ); - writer->Update(); - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/MultiResImageRegistration3.cxx b/Examples/RegistrationITKv3/MultiResImageRegistration3.cxx deleted file mode 100644 index 5a3301b4907..00000000000 --- a/Examples/RegistrationITKv3/MultiResImageRegistration3.cxx +++ /dev/null @@ -1,395 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// -// This example is the 3D version of the 2D example in MultiResImageRegistration1.cxx -// - -#include "itkMultiResolutionImageRegistrationMethod.h" -#include "itkTranslationTransform.h" -#include "itkMattesMutualInformationImageToImageMetric.h" -#include "itkRegularStepGradientDescentOptimizer.h" -#include "itkImage.h" -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" -#include "itkResampleImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkCheckerBoardImageFilter.h" - - -#include "itkCommand.h" - - -template -class RegistrationInterfaceCommand : public itk::Command -{ -public: - using Self = RegistrationInterfaceCommand; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - RegistrationInterfaceCommand() {}; - -public: - using RegistrationType = TRegistration; - using RegistrationPointer = RegistrationType *; - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = OptimizerType *; - - void Execute(itk::Object * object, const itk::EventObject & event) override - { - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - RegistrationPointer registration = static_cast( object ); - - OptimizerPointer optimizer = static_cast< OptimizerPointer >( registration->GetModifiableOptimizer() ); - - std::cout << "-------------------------------------" << std::endl; - std::cout << "MultiResolution Level : " - << registration->GetCurrentLevel() << std::endl; - std::cout << std::endl; - - if ( registration->GetCurrentLevel() == 0 ) - { - optimizer->SetMaximumStepLength( 16.00 ); - optimizer->SetMinimumStepLength( 0.01 ); - } - else - { - optimizer->SetMaximumStepLength( optimizer->GetMaximumStepLength() / 4.0 ); - optimizer->SetMinimumStepLength( optimizer->GetMinimumStepLength() / 10.0 ); - } - } - - void Execute(const itk::Object * , const itk::EventObject & ) override - { return; } -}; - - -// The following section of code implements an observer -// that will monitor the evolution of the registration process. -// -class CommandIterationUpdate : public itk::Command -{ -public: - using Self = CommandIterationUpdate; - using Superclass = itk::Command; - using Pointer = itk::SmartPointer; - itkNewMacro( Self ); - -protected: - CommandIterationUpdate() {}; - -public: - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using OptimizerPointer = const OptimizerType *; - - void Execute(itk::Object *caller, const itk::EventObject & event) - { - Execute( (const itk::Object *)caller, event); - } - - void Execute(const itk::Object * object, const itk::EventObject & event) - { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - if( !(itk::IterationEvent().CheckEvent( &event )) ) - { - return; - } - std::cout << optimizer->GetCurrentIteration() << " "; - std::cout << optimizer->GetValue() << " "; - std::cout << optimizer->GetCurrentPosition() << std::endl; - } -}; - - -int main( int argc, char *argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " fixedImageFile movingImageFile "; - std::cerr << " outputImagefile [backgroundGrayLevel]"; - std::cerr << " [checkerBoardBefore] [checkerBoardAfter]"; - std::cerr << " [useExplicitPDFderivatives ] " << std::endl; - std::cerr << " [numberOfBins] [numberOfSamples ] " << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int Dimension = 3; - using PixelType = unsigned short; - - using FixedImageType = itk::Image< PixelType, Dimension >; - using MovingImageType = itk::Image< PixelType, Dimension >; - - using InternalPixelType = float; - using InternalImageType = itk::Image< InternalPixelType, Dimension >; - - using TransformType = itk::TranslationTransform< double, Dimension >; - using OptimizerType = itk::RegularStepGradientDescentOptimizer; - using InterpolatorType = itk::LinearInterpolateImageFunction< - InternalImageType, - double >; - using MetricType = itk::MattesMutualInformationImageToImageMetric< - InternalImageType, - InternalImageType >; - using RegistrationType = itk::MultiResolutionImageRegistrationMethod< - InternalImageType, - InternalImageType >; - - using FixedImagePyramidType = itk::MultiResolutionPyramidImageFilter< - InternalImageType, - InternalImageType >; - using MovingImagePyramidType = itk::MultiResolutionPyramidImageFilter< - InternalImageType, - InternalImageType >; - - - // All the components are instantiated using their \code{New()} method - // and connected to the registration object as in previous example. - // - TransformType::Pointer transform = TransformType::New(); - OptimizerType::Pointer optimizer = OptimizerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - RegistrationType::Pointer registration = RegistrationType::New(); - MetricType::Pointer metric = MetricType::New(); - - FixedImagePyramidType::Pointer fixedImagePyramid = - FixedImagePyramidType::New(); - MovingImagePyramidType::Pointer movingImagePyramid = - MovingImagePyramidType::New(); - - registration->SetOptimizer( optimizer ); - registration->SetTransform( transform ); - registration->SetInterpolator( interpolator ); - registration->SetMetric( metric ); - registration->SetFixedImagePyramid( fixedImagePyramid ); - registration->SetMovingImagePyramid( movingImagePyramid ); - - - using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; - using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; - - FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); - MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); - - fixedImageReader->SetFileName( argv[1] ); - movingImageReader->SetFileName( argv[2] ); - - - using FixedCastFilterType = itk::CastImageFilter< - FixedImageType, InternalImageType >; - using MovingCastFilterType = itk::CastImageFilter< - MovingImageType, InternalImageType >; - - FixedCastFilterType::Pointer fixedCaster = FixedCastFilterType::New(); - MovingCastFilterType::Pointer movingCaster = MovingCastFilterType::New(); - - fixedCaster->SetInput( fixedImageReader->GetOutput() ); - movingCaster->SetInput( movingImageReader->GetOutput() ); - - registration->SetFixedImage( fixedCaster->GetOutput() ); - registration->SetMovingImage( movingCaster->GetOutput() ); - - - fixedCaster->Update(); - - registration->SetFixedImageRegion( - fixedCaster->GetOutput()->GetBufferedRegion() ); - - - using ParametersType = RegistrationType::ParametersType; - ParametersType initialParameters( transform->GetNumberOfParameters() ); - - initialParameters[0] = 0.0; // Initial offset in mm along X - initialParameters[1] = 0.0; // Initial offset in mm along Y - initialParameters[2] = 0.0; // Initial offset in mm along Z - - registration->SetInitialTransformParameters( initialParameters ); - - metric->SetNumberOfHistogramBins( 128 ); - metric->SetNumberOfSpatialSamples( 50000 ); - - if( argc > 8 ) - { - // optionally, override the values with numbers taken from the command line arguments. - metric->SetNumberOfHistogramBins( std::stoi( argv[8] ) ); - } - - if( argc > 9 ) - { - // optionally, override the values with numbers taken from the command line arguments. - metric->SetNumberOfSpatialSamples( std::stoi( argv[9] ) ); - } - - metric->ReinitializeSeed( 76926294 ); - - - if( argc > 7 ) - { - // Define whether to calculate the metric derivative by explicitly - // computing the derivatives of the joint PDF with respect to the Transform - // parameters, or doing it by progressively accumulating contributions from - // each bin in the joint PDF. - metric->SetUseExplicitPDFDerivatives( std::stoi( argv[7] ) ); - } - - - optimizer->SetNumberOfIterations( 200 ); - optimizer->SetRelaxationFactor( 0.9 ); - - - // Create the Command observer and register it with the optimizer. - // - CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - optimizer->AddObserver( itk::IterationEvent(), observer ); - - using CommandType = RegistrationInterfaceCommand; - CommandType::Pointer command = CommandType::New(); - registration->AddObserver( itk::IterationEvent(), command ); - - - registration->SetNumberOfLevels( 3 ); - - try - { - registration->Update(); - std::cout << "Optimizer stop condition: " - << registration->GetOptimizer()->GetStopConditionDescription() - << std::endl; - } - catch( itk::ExceptionObject & err ) - { - std::cout << "ExceptionObject caught !" << std::endl; - std::cout << err << std::endl; - return EXIT_FAILURE; - } - - ParametersType finalParameters = registration->GetLastTransformParameters(); - - double TranslationAlongX = finalParameters[0]; - double TranslationAlongY = finalParameters[1]; - double TranslationAlongZ = finalParameters[2]; - - unsigned int numberOfIterations = optimizer->GetCurrentIteration(); - - double bestValue = optimizer->GetValue(); - - - // Print out results - // - std::cout << "Result = " << std::endl; - std::cout << " Translation X = " << TranslationAlongX << std::endl; - std::cout << " Translation Y = " << TranslationAlongY << std::endl; - std::cout << " Translation Z = " << TranslationAlongZ << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; - - using ResampleFilterType = itk::ResampleImageFilter< - MovingImageType, - FixedImageType >; - - TransformType::Pointer finalTransform = TransformType::New(); - - finalTransform->SetParameters( finalParameters ); - finalTransform->SetFixedParameters( transform->GetFixedParameters() ); - - ResampleFilterType::Pointer resample = ResampleFilterType::New(); - - resample->SetTransform( finalTransform ); - resample->SetInput( movingImageReader->GetOutput() ); - - FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); - - PixelType backgroundGrayLevel = 100; - if( argc > 4 ) - { - backgroundGrayLevel = std::stoi( argv[4] ); - } - - resample->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); - resample->SetOutputOrigin( fixedImage->GetOrigin() ); - resample->SetOutputSpacing( fixedImage->GetSpacing() ); - resample->SetOutputDirection( fixedImage->GetDirection() ); - resample->SetDefaultPixelValue( backgroundGrayLevel ); - - - using OutputPixelType = unsigned char; - - using OutputImageType = itk::Image< OutputPixelType, Dimension >; - - using CastFilterType = itk::CastImageFilter< - FixedImageType, - OutputImageType >; - - using WriterType = itk::ImageFileWriter< OutputImageType >; - - - WriterType::Pointer writer = WriterType::New(); - CastFilterType::Pointer caster = CastFilterType::New(); - - - writer->SetFileName( argv[3] ); - - - caster->SetInput( resample->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - writer->Update(); - - // - // Generate checkerboards before and after registration - // - using CheckerBoardFilterType = itk::CheckerBoardImageFilter< FixedImageType >; - - CheckerBoardFilterType::Pointer checker = CheckerBoardFilterType::New(); - - checker->SetInput1( fixedImage ); - checker->SetInput2( resample->GetOutput() ); - - caster->SetInput( checker->GetOutput() ); - writer->SetInput( caster->GetOutput() ); - - resample->SetDefaultPixelValue( 0 ); - - // Before registration - TransformType::Pointer identityTransform = TransformType::New(); - identityTransform->SetIdentity(); - resample->SetTransform( identityTransform ); - - if( argc > 5 ) - { - writer->SetFileName( argv[5] ); - writer->Update(); - } - - - // After registration - resample->SetTransform( finalTransform ); - if( argc > 6 ) - { - writer->SetFileName( argv[6] ); - writer->Update(); - } - - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/ThinPlateSplineWarp.cxx b/Examples/RegistrationITKv3/ThinPlateSplineWarp.cxx deleted file mode 100644 index 2c99053481a..00000000000 --- a/Examples/RegistrationITKv3/ThinPlateSplineWarp.cxx +++ /dev/null @@ -1,224 +0,0 @@ -/*========================================================================= - * - * Copyright Insight Software Consortium - * - * 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. - * - *=========================================================================*/ - -// Command Line Arguments: Insight/Testing/Data/LandmarkWarping3Landmarks1.txt -// inputImage deformedImage deformationField -// -// Software Guide : BeginLatex -// This example deforms a 3D volume with the Thin plate spline. -// \index{ThinPlateSplineKernelTransform} -// Software Guide : EndLatex - - -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" -#include "itkImage.h" -#include "itkResampleImageFilter.h" - -// Software Guide : BeginCodeSnippet -#include "itkThinPlateSplineKernelTransform.h" -// Software Guide : EndCodeSnippet - -#include "itkPointSet.h" -#include - - -int main( int argc, char * argv[] ) -{ - if( argc < 4 ) - { - std::cerr << "Missing Parameters " << std::endl; - std::cerr << "Usage: " << argv[0]; - std::cerr << " landmarksFile inputImage "; - std::cerr << "DeformedImage " << std::endl; - std::cerr << "deformationField" << std::endl; - return EXIT_FAILURE; - } - - constexpr unsigned int ImageDimension = 3; - - using PixelType = unsigned char; - using InputImageType = itk::Image< PixelType, ImageDimension >; - using ReaderType = itk::ImageFileReader< InputImageType >; - using DeformedImageWriterType = itk::ImageFileWriter< InputImageType >; - using FieldVectorType = itk::Vector< float, ImageDimension >; - using DisplacementFieldType = itk::Image< FieldVectorType, ImageDimension >; - using FieldWriterType = itk::ImageFileWriter< DisplacementFieldType >; - using CoordinateRepType = double; - using TransformType = itk::ThinPlateSplineKernelTransform< CoordinateRepType, - ImageDimension>; - using PointType = itk::Point< CoordinateRepType, - ImageDimension >; - using PointSetType = TransformType::PointSetType; - using PointIdType = PointSetType::PointIdentifier; - using ResamplerType = itk::ResampleImageFilter< InputImageType, - InputImageType >; - using InterpolatorType = itk::LinearInterpolateImageFunction< - InputImageType, double >; - - ReaderType::Pointer reader = ReaderType::New(); - reader->SetFileName( argv[2] ); - - try - { - reader->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - // Software Guide : BeginLatex - // Landmarks correspondances may be associated with the SplineKernelTransforms - // via Point Set containers. Let us define containers for the landmarks. - // Software Guide : EndLatex - - // Define container for landmarks - - // Software Guide : BeginCodeSnippet - PointSetType::Pointer sourceLandMarks = PointSetType::New(); - PointSetType::Pointer targetLandMarks = PointSetType::New(); - PointType p1; PointType p2; - PointSetType::PointsContainer::Pointer sourceLandMarkContainer = - sourceLandMarks->GetPoints(); - PointSetType::PointsContainer::Pointer targetLandMarkContainer = - targetLandMarks->GetPoints(); - // Software Guide : EndCodeSnippet - - PointIdType id = itk::NumericTraits< PointIdType >::ZeroValue(); - - // Read in the list of landmarks - std::ifstream infile; - infile.open( argv[1] ); - while (!infile.eof()) - { - infile >> p1[0] >> p1[1] >> p1[2] >> p2[0] >> p2[1] >> p2[2]; - - // Software Guide : BeginCodeSnippet - sourceLandMarkContainer->InsertElement( id, p1 ); - targetLandMarkContainer->InsertElement( id++, p2 ); - // Software Guide : EndCodeSnippet - - } - infile.close(); - - // Software Guide : BeginCodeSnippet - TransformType::Pointer tps = TransformType::New(); - tps->SetSourceLandmarks(sourceLandMarks); - tps->SetTargetLandmarks(targetLandMarks); - tps->ComputeWMatrix(); - // Software Guide : EndCodeSnippet - - // Software Guide : BeginLatex - // The image is then resampled to produce an output image as defined by the - // transform. Here we use a LinearInterpolator. - // Software Guide : EndLatex - - // Set the resampler params - InputImageType::ConstPointer inputImage = reader->GetOutput(); - ResamplerType::Pointer resampler = ResamplerType::New(); - InterpolatorType::Pointer interpolator = InterpolatorType::New(); - resampler->SetInterpolator( interpolator ); - InputImageType::SpacingType spacing = inputImage->GetSpacing(); - InputImageType::PointType origin = inputImage->GetOrigin(); - InputImageType::DirectionType direction = inputImage->GetDirection(); - InputImageType::RegionType region = inputImage->GetBufferedRegion(); - InputImageType::SizeType size = region.GetSize(); - - // Software Guide : BeginCodeSnippet - resampler->SetOutputSpacing( spacing ); - resampler->SetOutputDirection( direction ); - resampler->SetOutputOrigin( origin ); - resampler->SetSize( size ); - resampler->SetTransform( tps ); - // Software Guide : EndCodeSnippet - - resampler->SetOutputStartIndex( region.GetIndex() ); - resampler->SetInput( reader->GetOutput() ); - - //Set and write deformed image - DeformedImageWriterType::Pointer deformedImageWriter = - DeformedImageWriterType::New(); - deformedImageWriter->SetInput( resampler->GetOutput() ); - deformedImageWriter->SetFileName( argv[3] ); - - try - { - deformedImageWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - - - // Software Guide : BeginLatex - // The deformation field is computed as the difference between the input and - // the deformed image by using an iterator. - // Software Guide : EndLatex - - // Compute the deformation field - - DisplacementFieldType::Pointer field = DisplacementFieldType::New(); - field->SetRegions( region ); - field->SetOrigin( origin ); - field->SetSpacing( spacing ); - field->Allocate(); - - using FieldIterator = itk::ImageRegionIterator< DisplacementFieldType >; - FieldIterator fi( field, region ); - fi.GoToBegin(); - TransformType::InputPointType point1; - TransformType::OutputPointType point2; - DisplacementFieldType::IndexType index; - - FieldVectorType displacement; - while( ! fi.IsAtEnd() ) - { - index = fi.GetIndex(); - field->TransformIndexToPhysicalPoint( index, point1 ); - point2 = tps->TransformPoint( point1 ); - for ( unsigned int i = 0;i < ImageDimension;i++) - { - displacement[i] = point2[i] - point1[i]; - } - fi.Set( displacement ); - ++fi; - } - - //Write computed deformation field - FieldWriterType::Pointer fieldWriter = FieldWriterType::New(); - fieldWriter->SetFileName( argv[4] ); - fieldWriter->SetInput( field ); - try - { - fieldWriter->Update(); - } - catch( itk::ExceptionObject & excp ) - { - std::cerr << "Exception thrown " << std::endl; - std::cerr << excp << std::endl; - return EXIT_FAILURE; - } - return EXIT_SUCCESS; -} diff --git a/Examples/RegistrationITKv3/test/CMakeLists.txt b/Examples/RegistrationITKv3/test/CMakeLists.txt deleted file mode 100644 index 5052a04b8d2..00000000000 --- a/Examples/RegistrationITKv3/test/CMakeLists.txt +++ /dev/null @@ -1,964 +0,0 @@ -set(BASELINE ${ITK_DATA_ROOT}/Baseline/Registration) -set(TEMP ${ITK_BINARY_DIR}/Testing/Temporary) - -itk_add_test(NAME ITKv3ImageRegistration1Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration1TestPixelCentered.png} - ${TEMP}/ImageRegistration1TestPixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration1TestPixelCentered.png - ${TEMP}/ImageRegistration1DifferenceAfterTestPixelCentered.png - ${TEMP}/ImageRegistration1DifferenceBeforeTestPixelCentered.png -) - -itk_add_test(NAME ITKv3ImageRegistration2Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration2Test.png} - ${TEMP}/ImageRegistration2Test.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainT1SliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration2Test.png - ${TEMP}/ImageRegistration2BeforeTest.png - ${TEMP}/ImageRegistration2AfterTest.png -) -set_property(TEST ITKv3ImageRegistration2Test APPEND PROPERTY LABELS RUNS_LONG) - -itk_add_test(NAME ITKv3ImageRegistration3Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration3TestPixelCentered.png} - ${TEMP}/ImageRegistration3TestPixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration3TestPixelCentered.png -) - -itk_add_test(NAME ITKv3ImageRegistration4Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ITKv3ImageRegistration4Test.png} - ${TEMP}/ImageRegistration4Test.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainT1SliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration4Test.png 0 - ${TEMP}/ImageRegistration4BeforeTest.png - ${TEMP}/ImageRegistration4AfterTest.png - 24 10000 1 -) - -itk_add_test(NAME ITKv3ImageRegistration4Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ITKv3ImageRegistration4Test.png} - ${TEMP}/ImageRegistration4Test2.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainT1SliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration4Test2.png 0 - ${TEMP}/ImageRegistration4BeforeTest.png - ${TEMP}/ImageRegistration4AfterTest.png - 24 10000 0 -) - -itk_add_test(NAME ITKv3ImageRegistration4Test3 COMMAND ${ITK_TEST_DRIVER} - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20Mask.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20Mask.png - ${TEMP}/ImageRegistration4Test3.png 0 - ${TEMP}/ImageRegistration4BeforeTest3.png - ${TEMP}/ImageRegistration4AfterTest3.png - 5 10000 0 -) - -itk_add_test(NAME ITKv3ImageRegistration5Test1 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration5Test1PixelCentered.png} - ${TEMP}/ImageRegistration5Test1PixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceRotated10.png - ${TEMP}/ImageRegistration5Test1PixelCentered.png -) - -itk_add_test(NAME ITKv3ImageRegistration5Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ITKv3ImageRegistration5Test2PixelCentered.png} - ${TEMP}/ImageRegistration5Test2PixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${TEMP}/ImageRegistration5Test2PixelCentered.png -) - -itk_add_test(NAME ITKv3ImageRegistration6Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration6TestPixelCentered.png} - ${TEMP}/ImageRegistration6TestPixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${TEMP}/ImageRegistration6TestPixelCentered.png -) - -itk_add_test(NAME ITKv3ImageRegistration7Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration7TestPixelCentered.png} - ${TEMP}/ImageRegistration7TestPixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17S12.png - ${TEMP}/ImageRegistration7TestPixelCentered.png - ${TEMP}/ImageRegistration7BeforeTestPixelCentered.png - ${TEMP}/ImageRegistration7AfterTestPixelCentered.png - 1.0 1.0 0.0 -) - -if(ITK_USE_BRAINWEB_DATA) - -## A test needed to prepare for making the latex documentation. -itk_add_test(NAME ITKv3ITKv3ConfidenceConnected3DTest COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb165a10f17.mha} - ${TEMP}/WhiteMatterSegmentation.mhd -) - -itk_add_test(NAME ITKv3ImageRegistration8Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration8RegisteredSlice.png} - ${TEMP}/ImageRegistration8v3RegisteredSlice.png - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - DATA{../../Data/BrainWeb/brainweb1e1a10f20Rot10Tx15.mha} - ${TEMP}/ImageRegistration8v3Output.mhd - ${TEMP}/ImageRegistration8v3DifferenceBefore.mhd - ${TEMP}/ImageRegistration8v3DifferenceAfter.mhd - ${TEMP}/ImageRegistration8v3Output.png - ${TEMP}/ImageRegistration8v3DifferenceBefore.png - ${TEMP}/ImageRegistration8v3DifferenceAfter.png - ${TEMP}/ImageRegistration8v3RegisteredSlice.png -) - - -if( ${CMAKE_BUILD_TYPE} MATCHES "Release") - # This test is computationally demanding. - # Therefore we only run it in a Release build - itk_add_test(NAME ITKv3ImageRegistration20Test COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - DATA{../../Data/BrainWeb/brainweb1e1a10f20Rot10Tx15.mha} - ${TEMP}/ImageRegistration20Output.mhd - ${TEMP}/ImageRegistration20DifferenceBefore.mhd - ${TEMP}/ImageRegistration20DifferenceAfter.mhd - 0.1 # Step length - 300 # maximum number of iterations - ) - set_tests_properties(ITKv3ImageRegistration20Test PROPERTIES RUN_SERIAL 1) -endif() - -endif() - -itk_add_test(NAME ITKv3ImageRegistration9Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration9TestPixelCentered.png} - ${TEMP}/ImageRegistration9TestPixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${TEMP}/ImageRegistration9TestPixelCentered.png -) - -itk_add_test(NAME ITKv3ImageRegistration10Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration10TestPixelCentered.png,:} - ${TEMP}/ImageRegistration10TestPixelCentered.png - $ - DATA{${ITK_SOURCE_DIR}/Testing/Data/Baseline/Segmentation/WatershedSegmentation1Test1.png} - DATA{${ITK_SOURCE_DIR}/Testing/Data/Baseline/Segmentation/WatershedSegmentation1Test2.png} - ${TEMP}/ImageRegistration10TestPixelCentered.png - ${TEMP}/ImageRegistration10DifferenceTestPixelCentered.png - -11 -13 -) - -itk_add_test(NAME ITKv3ImageRegistration13Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} - ${TEMP}/ImageRegistration13TestPixelCentered.png - --compareNumberOfPixelsTolerance 5 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${TEMP}/ImageRegistration13TestPixelCentered.png -) - -itk_add_test(NAME ITKv3ImageRegistration13Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} - ${TEMP}/ImageRegistration13Test2PixelCentered.png - --compareNumberOfPixelsTolerance 10 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${TEMP}/ImageRegistration13Test2PixelCentered.png - 0 0 -) - -itk_add_test(NAME ITKv3ImageRegistration13Test3 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} - ${TEMP}/ImageRegistration13Test3PixelCentered.png - --compareNumberOfPixelsTolerance 10 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${TEMP}/ImageRegistration13Test3PixelCentered.png - 0 1 -) - -itk_add_test(NAME ITKv3ImageRegistration13Test4 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} - ${TEMP}/ImageRegistration13Test4PixelCentered.png - --compareNumberOfPixelsTolerance 5 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${TEMP}/ImageRegistration13Test4PixelCentered.png - 1 0 -) - -itk_add_test(NAME ITKv3ImageRegistration13Test5 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} - ${TEMP}/ImageRegistration13Test5PixelCentered.png - --compareNumberOfPixelsTolerance 5 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${TEMP}/ImageRegistration13Test5PixelCentered.png - 1 1 -) - -itk_add_test(NAME ITKv3ImageRegistration14Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration14Test.png,:} - ${TEMP}/ImageRegistration14Test.png - --compareNumberOfPixelsTolerance 2000 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${TEMP}/ImageRegistration14Test.png 32 0.01 0.1 0.15 10.0 14.0 -) -set_property(TEST ITKv3ImageRegistration14Test APPEND PROPERTY LABELS RUNS_LONG) - -itk_add_test(NAME ITKv3ImageRegistration15Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration15TestPixelCentered.png} - ${TEMP}/ImageRegistration15TestPixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration15TestPixelCentered.png 32 0.1 0.05 0.0 0.0 -) -set_property(TEST ITKv3ImageRegistration15Test APPEND PROPERTY LABELS RUNS_LONG) - -itk_add_test(NAME ITKv3ImageRegistration16Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration16TestPixelCentered.png} - ${TEMP}/ImageRegistration16TestPixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration16TestPixelCentered.png 0.0 0.0 -) - -itk_add_test(NAME ITKv3ImageRegistration16Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration16TestPixelCentered.png} - ${TEMP}/ImageRegistration16Test2PixelCentered.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration16Test2PixelCentered.png 0.0 0.0 - 0 -) - -itk_add_test(NAME ITKv3ImageRegistration17Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration17TestPixelCentered.png,:} - ${TEMP}/ImageRegistration17TestPixelCentered.png - --compareNumberOfPixelsTolerance 5 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration17TestPixelCentered.png 0.0 0.0 -) - -itk_add_test(NAME ITKv3ImageRegistration18Test COMMAND ITKv3ImageRegistration18 - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/ImageRegistration18Test.png 0.0 0.0 -) - -itk_add_test(NAME ITKv3ImageRegistration19Test COMMAND ITKv3ImageRegistration19 - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20Mask.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20Mask.png - ${TEMP}/ImageRegistration19Test.png - ${TEMP}/ImageRegistration19DifferenceTest.png - 2.0 2.0 # Initial translation parameters -) - -itk_add_test(NAME ITKv3MultiResImageRegistration1Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/MultiResImageRegistration1Test.png,:} - ${TEMP}/MultiResImageRegistration1Test.png - --compareNumberOfPixelsTolerance 10 - --compareIntensityTolerance 7 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainT1SliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/MultiResImageRegistration1Test.png 100 - ${TEMP}/MultiResImageRegistration1CheckerBoardBeforeTest.png - ${TEMP}/MultiResImageRegistration1CheckerBoardAfterTest.png -) -set_property(TEST ITKv3MultiResImageRegistration1Test APPEND PROPERTY LABELS RUNS_LONG) - -itk_add_test(NAME ITKv3MultiResImageRegistration1Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/MultiResImageRegistration1Test.png,:} - ${TEMP}/MultiResImageRegistration1Test2.png - --compareNumberOfPixelsTolerance 10 - --compareIntensityTolerance 7 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainT1SliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/MultiResImageRegistration1Test2.png 100 - ${TEMP}/MultiResImageRegistration1CheckerBoardBeforeTest2.png - ${TEMP}/MultiResImageRegistration1CheckerBoardAfterTest2.png - 0 -) -set_property(TEST ITKv3MultiResImageRegistration1Test2 APPEND PROPERTY LABELS RUNS_LONG) - - -itk_add_test(NAME ITKv3MultiResImageRegistration2Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/MultiResImageRegistration2Test.png,:} - ${TEMP}/MultiResImageRegistration2Test.png - --compareNumberOfPixelsTolerance 10000 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainT1SliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/MultiResImageRegistration2Test.png 0 - ${TEMP}/MultiResImageRegistration2CheckerBoardBeforeTest.png - ${TEMP}/MultiResImageRegistration2CheckerBoardAfterTest.png -) -set_property(TEST ITKv3MultiResImageRegistration2Test APPEND PROPERTY LABELS RUNS_LONG) - - -itk_add_test(NAME ITKv3MultiResImageRegistration2Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/MultiResImageRegistration2Test.png,:} - ${TEMP}/MultiResImageRegistration2Test2.png - --compareNumberOfPixelsTolerance 10000 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainT1SliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceShifted13x17y.png - ${TEMP}/MultiResImageRegistration2Test2.png 0 - ${TEMP}/MultiResImageRegistration2CheckerBoardBeforeTest2.png - ${TEMP}/MultiResImageRegistration2CheckerBoardAfterTest2.png - 0 -) -set_property(TEST ITKv3MultiResImageRegistration2Test2 APPEND PROPERTY LABELS RUNS_LONG) - - -itk_add_test(NAME ITKv3DeformableRegistration2Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/DeformableRegistration2Test.png} - ${TEMP}/DeformableRegistration2Test.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBSplined10.png - ${TEMP}/DeformableRegistration2Test.png -) - -itk_add_test(NAME ITKv3DeformableRegistration3Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/DeformableRegistration3Test.png,:} - ${TEMP}/DeformableRegistration3Test.png - --compareNumberOfPixelsTolerance 100 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBSplined10.png - ${TEMP}/DeformableRegistration3Test.png -) - -#Disable until BSplineDeformableTransform is fully implemented. -#itk_add_test(NAME ITKv3DeformableRegistration4Test COMMAND ${ITK_TEST_DRIVER} -# --compare DATA{Baseline/DeformableRegistration4TestPixelCentered.png} -# ${TEMP}/DeformableRegistration4TestPixelCentered.png -# $ -# ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png -# ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBSplined10.png -# ${TEMP}/DeformableRegistration4TestPixelCentered.png -#) - -itk_add_test(NAME ITKv3DeformableRegistration5Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/DeformableRegistration5Test.png,:} - ${TEMP}/DeformableRegistration5Test.png - --compareNumberOfPixelsTolerance 100 - --compareIntensityTolerance 70 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBSplined10.png - ${TEMP}/DeformableRegistration5Test.png -) - -#Disable until BSplineDeformableTransform is fully implemented. -#itk_add_test(NAME ITKv3DeformableRegistration6Test COMMAND ${ITK_TEST_DRIVER} -# --compare DATA{Baseline/DeformableRegistration6TestPixelCentered.png} -# ${TEMP}/DeformableRegistration6TestPixelCentered.png -# $ -# ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png -# ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBSplined10.png -# ${TEMP}/DeformableRegistration6TestPixelCentered.png -#) - -itk_add_test(NAME ITKv3BSplineWarping1Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{Baseline/BSplineWarping1Test.png} - ${TEMP}/BSplineWarping1Test.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/BSplineDisplacements1.txt - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${TEMP}/BSplineWarping1Test.png - ${TEMP}/BSplineWarping1TestDisplacementField.mhd - ${TEMP}/BSplineWarping1TestTransform.txt -) - -itk_add_test(NAME ITKv3DeformableRegistration12Test1 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{Baseline/DeformableRegistration12Test.png} - ${TEMP}/DeformableRegistration12Test1.png - --compareNumberOfPixelsTolerance 600 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - DATA{Baseline/BSplineWarping1Test.png} - ${TEMP}/DeformableRegistration12Test1.png - ${TEMP}/DeformableRegistration12Test1DifferenceAfter.png - ${TEMP}/DeformableRegistration12Test1DifferenceBefore.png - ${TEMP}/DeformableRegistration12Test1DisplacementField.mhd - 0 0 - ${TEMP}/DeformableRegistration12Test1FinalTransformParameters.txt -) -set_property(TEST ITKv3DeformableRegistration12Test1 APPEND PROPERTY LABELS RUNS_LONG) - -itk_add_test(NAME ITKv3DeformableRegistration12Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{Baseline/DeformableRegistration12Test.png} - ${TEMP}/DeformableRegistration12Test2.png - --compareNumberOfPixelsTolerance 600 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - DATA{Baseline/BSplineWarping1Test.png} - ${TEMP}/DeformableRegistration12Test2.png - ${TEMP}/DeformableRegistration12Test2DifferenceAfter.png - ${TEMP}/DeformableRegistration12Test2DifferenceBefore.png - ${TEMP}/DeformableRegistration12Test2DisplacementField.mhd - 0 1 - ${TEMP}/DeformableRegistration12Test2FinalTransformParameters.txt -) - -itk_add_test(NAME ITKv3DeformableRegistration12Test3 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{Baseline/DeformableRegistration12Test.png} - ${TEMP}/DeformableRegistration12Test3.png - --compareNumberOfPixelsTolerance 600 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - DATA{Baseline/BSplineWarping1Test.png} - ${TEMP}/DeformableRegistration12Test3.png - ${TEMP}/DeformableRegistration12Test3DifferenceAfter.png - ${TEMP}/DeformableRegistration12Test3DifferenceBefore.png - ${TEMP}/DeformableRegistration12Test3DisplacementField.mhd - 1 0 - ${TEMP}/DeformableRegistration12Test3FinalTransformParameters.txt -) -set_property(TEST ITKv3DeformableRegistration12Test3 APPEND PROPERTY LABELS RUNS_LONG) - -itk_add_test(NAME ITKv3DeformableRegistration12Test4 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{Baseline/DeformableRegistration12Test.png} - ${TEMP}/DeformableRegistration12Test4.png - --compareNumberOfPixelsTolerance 600 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - DATA{Baseline/BSplineWarping1Test.png} - ${TEMP}/DeformableRegistration12Test4.png - ${TEMP}/DeformableRegistration12Test4DifferenceAfter.png - ${TEMP}/DeformableRegistration12Test4DifferenceBefore.png - ${TEMP}/DeformableRegistration12Test4DisplacementField.mhd - 1 1 - ${TEMP}/DeformableRegistration12Test4FinalTransformParameters.txt -) - -itk_add_test(NAME ITKv3DeformableRegistration13Test1 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{Baseline/DeformableRegistration13Test.png} - ${TEMP}/DeformableRegistration13Test1.png - --compareNumberOfPixelsTolerance 400 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - DATA{Baseline/BSplineWarping1Test.png} - ${TEMP}/DeformableRegistration13Test1.png - ${TEMP}/DeformableRegistration13Test1DifferenceAfter.png - ${TEMP}/DeformableRegistration13Test1DifferenceBefore.png - ${TEMP}/DeformableRegistration13Test1DisplacementField.mhd - 0 0 - ${TEMP}/DeformableRegistration13Test1FinalTransformParameters.txt -) -set_property(TEST ITKv3DeformableRegistration13Test1 APPEND PROPERTY LABELS RUNS_LONG) - -itk_add_test(NAME ITKv3DeformableRegistration13Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{Baseline/DeformableRegistration13Test.png} - ${TEMP}/DeformableRegistration13Test2.png - --compareNumberOfPixelsTolerance 400 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - DATA{Baseline/BSplineWarping1Test.png} - ${TEMP}/DeformableRegistration13Test2.png - ${TEMP}/DeformableRegistration13Test2DifferenceAfter.png - ${TEMP}/DeformableRegistration13Test2DifferenceBefore.png - ${TEMP}/DeformableRegistration13Test2DisplacementField.mhd - 0 1 - ${TEMP}/DeformableRegistration13Test2FinalTransformParameters.txt -) - -itk_add_test(NAME ITKv3DeformableRegistration13Test3 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{Baseline/DeformableRegistration13Test.png} - ${TEMP}/DeformableRegistration13Test3.png - --compareNumberOfPixelsTolerance 400 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - DATA{Baseline/BSplineWarping1Test.png} - ${TEMP}/DeformableRegistration13Test3.png - ${TEMP}/DeformableRegistration13Test3DifferenceAfter.png - ${TEMP}/DeformableRegistration13Test3DifferenceBefore.png - ${TEMP}/DeformableRegistration13Test3DisplacementField.mhd - 1 0 - ${TEMP}/DeformableRegistration13Test3FinalTransformParameters.txt -) -set_property(TEST ITKv3DeformableRegistration13Test3 APPEND PROPERTY LABELS RUNS_LONG) - -itk_add_test(NAME ITKv3DeformableRegistration13Test4 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{Baseline/DeformableRegistration13Test.png} - ${TEMP}/DeformableRegistration13Test4.png - --compareNumberOfPixelsTolerance 400 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - DATA{Baseline/BSplineWarping1Test.png} - ${TEMP}/DeformableRegistration13Test4.png - ${TEMP}/DeformableRegistration13Test4DifferenceAfter.png - ${TEMP}/DeformableRegistration13Test4DifferenceBefore.png - ${TEMP}/DeformableRegistration13Test4DisplacementField.mhd - 1 1 - ${TEMP}/DeformableRegistration13Test4FinalTransformParameters.txt -) - -if( ITK_USE_BRAINWEB_DATA ) - - itk_add_test(NAME ITKv3BSplineWarping2Test COMMAND ${ITK_TEST_DRIVER} - $ - ${ITK_SOURCE_DIR}/Examples/Data/BSplineDisplacements2.txt - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/BSplineWarping2TestDisplacementField.mhd - ${TEMP}/BSplineWarping2TestTransform.txt - ) - - set( NUMBER_OF_BSPLINE_GRID_NODES 5 ) - - if( DART_TESTING_TIMEOUT GREATER 3000 ) - - itk_add_test(NAME ITKv3DeformableRegistration8Test1 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/DeformableRegistration8Test1.mhd - --compareNumberOfPixelsTolerance 700000 - --compareIntensityTolerance 15 - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test1.mhd - ${TEMP}/DeformableRegistration8Test1DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test1DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test1DisplacementField.mhd - 0 0 - ${TEMP}/DeformableRegistration8Test1FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ${ITK_SOURCE_DIR}/Examples/Data/IdentityTransform.tfm - ) - set_property(TEST ITKv3DeformableRegistration8Test1 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test1 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration8Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/DeformableRegistration8Test2.mhd - --compareNumberOfPixelsTolerance 700000 - --compareIntensityTolerance 15 - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test2.mhd - ${TEMP}/DeformableRegistration8Test2DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test2DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test2DisplacementField.mhd - 1 0 - ${TEMP}/DeformableRegistration8Test2FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ${ITK_SOURCE_DIR}/Examples/Data/IdentityTransform.tfm - ) - set_property(TEST ITKv3DeformableRegistration8Test2 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test2 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration8Test3 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/DeformableRegistration8Test3.mhd - --compareNumberOfPixelsTolerance 700000 - --compareIntensityTolerance 15 - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test3.mhd - ${TEMP}/DeformableRegistration8Test3DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test3DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test3DisplacementField.mhd - 0 1 - ${TEMP}/DeformableRegistration8Test3FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ${ITK_SOURCE_DIR}/Examples/Data/IdentityTransform.tfm - ) - set_property(TEST ITKv3DeformableRegistration8Test3 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test3 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration8Test4 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/DeformableRegistration8Test4.mhd - --compareNumberOfPixelsTolerance 700000 - --compareIntensityTolerance 15 - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test4.mhd - ${TEMP}/DeformableRegistration8Test4DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test4DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test4DisplacementField.mhd - 1 1 - ${TEMP}/DeformableRegistration8Test4FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ${ITK_SOURCE_DIR}/Examples/Data/IdentityTransform.tfm - ) - set_property(TEST ITKv3DeformableRegistration8Test4 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test4 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration14Test1 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/DeformableRegistration14Test1.mhd - --compareNumberOfPixelsTolerance 700000 - --compareIntensityTolerance 15 - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration14Test1.mhd - ${TEMP}/DeformableRegistration14Test1DifferenceAfter.mhd - ${TEMP}/DeformableRegistration14Test1DifferenceBefore.mhd - ${TEMP}/DeformableRegistration14Test1DisplacementField.mhd - 0 0 - ${TEMP}/DeformableRegistration14Test1FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ${ITK_SOURCE_DIR}/Examples/Data/IdentityTransform.tfm - 10.0 50 - ) - set_property(TEST ITKv3DeformableRegistration14Test1 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration14Test1 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration14Test2 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/DeformableRegistration14Test2.mhd - --compareNumberOfPixelsTolerance 700000 - --compareIntensityTolerance 15 - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration14Test2.mhd - ${TEMP}/DeformableRegistration14Test2DifferenceAfter.mhd - ${TEMP}/DeformableRegistration14Test2DifferenceBefore.mhd - ${TEMP}/DeformableRegistration14Test2DisplacementField.mhd - 0 1 - ${TEMP}/DeformableRegistration14Test2FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ${ITK_SOURCE_DIR}/Examples/Data/IdentityTransform.tfm - 10.0 50 - ) - set_property(TEST ITKv3DeformableRegistration14Test2 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration14Test2 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration14Test3 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/DeformableRegistration14Test3.mhd - --compareNumberOfPixelsTolerance 700000 - --compareIntensityTolerance 15 - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration14Test3.mhd - ${TEMP}/DeformableRegistration14Test3DifferenceAfter.mhd - ${TEMP}/DeformableRegistration14Test3DifferenceBefore.mhd - ${TEMP}/DeformableRegistration14Test3DisplacementField.mhd - 1 0 - ${TEMP}/DeformableRegistration14Test3FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ${ITK_SOURCE_DIR}/Examples/Data/IdentityTransform.tfm - 10.0 50 - ) - set_property(TEST ITKv3DeformableRegistration14Test3 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration14Test3 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration14Test4 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/DeformableRegistration14Test4.mhd - --compareNumberOfPixelsTolerance 700000 - --compareIntensityTolerance 15 - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration14Test4.mhd - ${TEMP}/DeformableRegistration14Test4DifferenceAfter.mhd - ${TEMP}/DeformableRegistration14Test4DifferenceBefore.mhd - ${TEMP}/DeformableRegistration14Test4DisplacementField.mhd - 1 1 - ${TEMP}/DeformableRegistration14Test4FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ${ITK_SOURCE_DIR}/Examples/Data/IdentityTransform.tfm - 10.0 50 - ) - set_property(TEST ITKv3DeformableRegistration14Test4 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration14Test4 APPEND PROPERTY LABELS RUNS_LONG) - - endif() # DART_TESTING_TIMEOUT GREATER 3000 - - itk_add_test(NAME ChangeInformationTest1 COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplinedTranlatedScaledRotated.mhd - 1.05 - 1.0 2.0 0.0 - 10.0 - ) - - if( DART_TESTING_TIMEOUT GREATER 10000 ) - itk_add_test(NAME ITKv3DeformableRegistration15Test1 COMMAND ${ITK_TEST_DRIVER} - --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/DeformableRegistration15Test1.mhd - --compareNumberOfPixelsTolerance 700000 - --compareIntensityTolerance 15 - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplinedTranlatedScaledRotated.mhd - ${TEMP}/DeformableRegistration15Test1.mhd - ${TEMP}/DeformableRegistration15Test1DifferenceAfter.mhd - ${TEMP}/DeformableRegistration15Test1DifferenceBefore.mhd - ${TEMP}/DeformableRegistration15Test1DisplacementField.mhd - 0 0 - ${TEMP}/DeformableRegistration15Test1FinalTransformParameters.txt - 5 100 - 10.0 50 - ) - set_property(TEST ITKv3DeformableRegistration15Test1 PROPERTY DEPENDS ChangeInformationTest1) - set_property(TEST ITKv3DeformableRegistration15Test1 APPEND PROPERTY LABELS RUNS_LONG) - endif() - - if( "${ITK_COMPUTER_MEMORY_SIZE}" GREATER 6 ) - - set(NUMBER_OF_BSPLINE_GRID_NODES 32) - itk_add_test(NAME ITKv3DeformableRegistration8Test5 COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test5.mhd - ${TEMP}/DeformableRegistration8Test5DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test5DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test5DisplacementField.mhd - 0 0 - ${TEMP}/DeformableRegistration8Test5FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ) - set_property(TEST ITKv3DeformableRegistration8Test5 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test5 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration8Test6 COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test6.mhd - ${TEMP}/DeformableRegistration8Test6DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test6DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test6DisplacementField.mhd - 0 1 - ${TEMP}/DeformableRegistration8Test6FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ) - set_property(TEST ITKv3DeformableRegistration8Test6 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test6 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration8Test7 COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test7.mhd - ${TEMP}/DeformableRegistration8Test7DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test7DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test7DisplacementField.mhd - 1 0 - ${TEMP}/DeformableRegistration8Test7FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ) - set_property(TEST ITKv3DeformableRegistration8Test7 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test7 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration8Test8 COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test8.mhd - ${TEMP}/DeformableRegistration8Test8DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test8DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test8DisplacementField.mhd - 1 1 - ${TEMP}/DeformableRegistration8Test8FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ) - set_property(TEST ITKv3DeformableRegistration8Test8 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test8 APPEND PROPERTY LABELS RUNS_LONG) - - set(NUMBER_OF_BSPLINE_GRID_NODES 100) - itk_add_test(NAME ITKv3DeformableRegistration8Test9 COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test9.mhd - ${TEMP}/DeformableRegistration8Test9DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test9DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test9DisplacementField.mhd - 0 0 - ${TEMP}/DeformableRegistration8Test9FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ) - set_property(TEST ITKv3DeformableRegistration8Test9 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test9 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration8Test10 COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test10.mhd - ${TEMP}/DeformableRegistration8Test10DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test10DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test10DisplacementField.mhd - 0 1 - ${TEMP}/DeformableRegistration8Test10FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ) - set_property(TEST ITKv3DeformableRegistration8Test10 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test10 APPEND PROPERTY LABELS RUNS_LONG) - - # Due to the large memory requirements this tests must be run one by one - set_tests_properties( - DeformableRegistration8Test5 - DeformableRegistration8Test6 - DeformableRegistration8Test7 - DeformableRegistration8Test8 - DeformableRegistration8Test9 - DeformableRegistration8Test10 - PROPERTIES - RESOURCE_LOCK MEMORY_SIZE - ) - - if( "${ITK_COMPUTER_MEMORY_SIZE}" GREATER 16 ) - - itk_add_test(NAME ITKv3DeformableRegistration8Test11 COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test11.mhd - ${TEMP}/DeformableRegistration8Test11DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test11DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test11DisplacementField.mhd - 1 0 - ${TEMP}/DeformableRegistration8Test11FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ) - set_property(TEST ITKv3DeformableRegistration8Test11 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test11 APPEND PROPERTY LABELS RUNS_LONG) - - itk_add_test(NAME ITKv3DeformableRegistration8Test12 COMMAND ${ITK_TEST_DRIVER} - $ - DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} - ${TEMP}/BSplineWarping2Test.mhd - ${TEMP}/DeformableRegistration8Test12.mhd - ${TEMP}/DeformableRegistration8Test12DifferenceAfter.mhd - ${TEMP}/DeformableRegistration8Test12DifferenceBefore.mhd - ${TEMP}/DeformableRegistration8Test12DisplacementField.mhd - 1 1 - ${TEMP}/DeformableRegistration8Test12FinalTransformParameters.txt - ${NUMBER_OF_BSPLINE_GRID_NODES} - ) - set_property(TEST ITKv3DeformableRegistration8Test12 PROPERTY DEPENDS BSplineWarping2Test) - set_property(TEST ITKv3DeformableRegistration8Test12 APPEND PROPERTY LABELS RUNS_LONG) - - # Due to the large memory requirements this tests lock the memory size resource - set_tests_properties( - DeformableRegistration8Test11 - DeformableRegistration8Test12 - PROPERTIES - RESOURCE_LOCK MEMORY_SIZE - ) - endif() # ITK_COMPUTER_MEMORY_SIZE GREATER 16 - - endif() # ITK_COMPUTER_MEMORY_SIZE GREATER 6 - -endif() # ITK_USE_BRAINWEB_DATA - - -if(ITK_MRI_UNC_DATABASE_DATA_ROOT) - -if( DART_TESTING_TIMEOUT GREATER 10000 ) - itk_add_test(NAME ITKv3DeformableRegistration15Test2 COMMAND ${ITK_TEST_DRIVER} - $ - ${ITK_MRI_UNC_DATABASE_DATA_ROOT}/b/I.hdr - ${ITK_MRI_UNC_DATABASE_DATA_ROOT}/d/I.hdr - ${TEMP}/DeformableRegistration15Test2.mhd - ${TEMP}/DeformableRegistration15Test2DifferenceAfter.mhd - ${TEMP}/DeformableRegistration15Test2DifferenceBefore.mhd - ${TEMP}/DeformableRegistration15Test2DisplacementField.mhd - 0 0 - ${TEMP}/DeformableRegistration15Test2FinalTransformParameters.txt - 5 100 - 10.0 50 - ) - set_property(TEST ITKv3DeformableRegistration15Test2 APPEND PROPERTY LABELS RUNS_LONG) -endif() - -endif() - - -itk_add_test(NAME LandmarkWarping2Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/LandmarkWarping2Test.png} - ${TEMP}/LandmarkWarping2Test.png - $ - ${ITK_SOURCE_DIR}/Examples/Data/LandmarkWarping2Landmarks1.txt - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${TEMP}/LandmarkWarping2Test.png -) -itk_add_test(NAME ITKv3ImageRegistration12Test COMMAND ${ITK_TEST_DRIVER} - --compare DATA{${BASELINE}/ImageRegistration12TestPixelCentered.png} - ${TEMP}/ImageRegistration12TestPixelCentered.png - --compareNumberOfPixelsTolerance 2 - $ - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceR10X13Y17.png - ${ITK_SOURCE_DIR}/Examples/Data/BrainProtonDensitySliceBorder20Mask.png - ${TEMP}/ImageRegistration12TestPixelCentered.png -) - -itk_add_test(NAME ITKv3ModelToImageRegistration2Test COMMAND ${ITK_TEST_DRIVER} - $ - DATA{${ITK_SOURCE_DIR}/Testing/Data/Input/cake_easy.png} 12 12 -) - - -itk_add_test(NAME IterativeClosestPoint1Test COMMAND ${ITK_TEST_DRIVER} - $ - ${ITK_SOURCE_DIR}/Examples/Data/IterativeClosestPointFixedPoints.txt - ${ITK_SOURCE_DIR}/Examples/Data/IterativeClosestPointMovingPoints.txt -) - -itk_add_test(NAME IterativeClosestPoint2Test COMMAND ${ITK_TEST_DRIVER} - $ - ${ITK_SOURCE_DIR}/Examples/Data/IterativeClosestPointFixedPoints2.txt - ${ITK_SOURCE_DIR}/Examples/Data/IterativeClosestPointMovingPoints2.txt -) - -itk_add_test(NAME IterativeClosestPoint3Test COMMAND ${ITK_TEST_DRIVER} - $ - ${ITK_SOURCE_DIR}/Examples/Data/IterativeClosestPointFixedPoints.txt - ${ITK_SOURCE_DIR}/Examples/Data/IterativeClosestPointMovingPoints.txt -) diff --git a/Examples/RegistrationITKv4/DeformableRegistration12.cxx b/Examples/RegistrationITKv4/DeformableRegistration12.cxx index eb1ab3d481d..dc5c85ea9dc 100644 --- a/Examples/RegistrationITKv4/DeformableRegistration12.cxx +++ b/Examples/RegistrationITKv4/DeformableRegistration12.cxx @@ -197,8 +197,8 @@ int main( int argc, char *argv[] ) { fixedOrigin[i] = fixedImage->GetOrigin()[i]; fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] * - static_cast( - fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 ); + static_cast( + fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 ); } meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder ); @@ -212,7 +212,7 @@ int main( int argc, char *argv[] ) using ParametersType = TransformType::ParametersType; - const unsigned int numberOfParameters = transform->GetNumberOfParameters(); + const unsigned int numberOfParameters = transform->GetNumberOfParameters(); ParametersType parameters( numberOfParameters ); diff --git a/Examples/RegistrationITKv4/DeformableRegistration6.cxx b/Examples/RegistrationITKv4/DeformableRegistration6.cxx index 98fe9009556..fa0d9857fba 100644 --- a/Examples/RegistrationITKv4/DeformableRegistration6.cxx +++ b/Examples/RegistrationITKv4/DeformableRegistration6.cxx @@ -291,8 +291,8 @@ int main( int argc, char *argv[] ) for( unsigned int i=0; i< SpaceDimension; i++ ) { fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] * - static_cast( - fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 ); + static_cast( + fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 ); } // Create the transform adaptors specific to B-splines diff --git a/Examples/RegistrationITKv4/ImageRegistration5.py b/Examples/RegistrationITKv4/ImageRegistration5.py index fd30dd7f79a..fe1114914f2 100644 --- a/Examples/RegistrationITKv4/ImageRegistration5.py +++ b/Examples/RegistrationITKv4/ImageRegistration5.py @@ -27,7 +27,7 @@ # if len(argv) < 4: print 'Missing Parameters' - print 'Usage: ImageRegistration3.py fixedImageFile movingImageFile outputImagefile' + print 'Usage: ImageRegistration5.py fixedImageFile movingImageFile outputImagefile' exit() diff --git a/Modules/Core/Transform/include/itkRigid3DTransform.h b/Modules/Core/Transform/include/itkRigid3DTransform.h index 3782f9bebd9..71c83a2491a 100644 --- a/Modules/Core/Transform/include/itkRigid3DTransform.h +++ b/Modules/Core/Transform/include/itkRigid3DTransform.h @@ -66,10 +66,8 @@ class ITK_TEMPLATE_EXPORT Rigid3DTransform: using Pointer = SmartPointer; using ConstPointer = SmartPointer; -//HACK #ifdef ITKV3_COMPATIBILITY /** Run-time type information (and related methods). */ itkNewMacro(Self); -//HACK #endif /** Run-time type information (and related methods). */ itkTypeMacro(Rigid3DTransform, MatrixOffsetTransformBase); diff --git a/Modules/Core/Transform/include/itkv3Rigid3DTransform.h b/Modules/Core/Transform/include/itkv3Rigid3DTransform.h index 7d112354085..aaee703d550 100644 --- a/Modules/Core/Transform/include/itkv3Rigid3DTransform.h +++ b/Modules/Core/Transform/include/itkv3Rigid3DTransform.h @@ -32,8 +32,8 @@ namespace v3 * NOTE: In ITK4, the itkNewMacro() was removed from * itk::Rigid3DTransform. This class, itkv3::Rigid3DTransform provides * the ITK3.x functionality. The purpose of the class is provide ITKv3 - * functionality while allowing the user to turn off - * ITKV3_COMPATIBILITY. + * functionality with backward compatibility after ITK 5.0 removal of + * ITKV3_COMPATIBILITY support. * * Even though the name Rigid3DTransform is conceptually closer to * what a user may expect, the VersorRigid3DTransform is often a diff --git a/Modules/Registration/Common/itk-module.cmake b/Modules/Registration/Common/itk-module.cmake index 65b0659b4f3..ea0f6de12be 100644 --- a/Modules/Registration/Common/itk-module.cmake +++ b/Modules/Registration/Common/itk-module.cmake @@ -10,6 +10,14 @@ ITKTransform, and optimizers can be found in ITKOptimizers. To compare the moving image to the fixed image with the image metric, an interpolator is required-- these can be found in ITKImageFunction.") +if(BUILD_EXAMPLES) +set(EXAMPLE_TEST_CASE_DEPENDANCIES + ITKImageCompare + ITKIOTransformBase + ITKIOImageBase +) +endif() + itk_module(ITKRegistrationCommon DEPENDS ITKOptimizers @@ -29,6 +37,7 @@ itk_module(ITKRegistrationCommon ITKImageSources ITKColormap ITKQuadEdgeMesh + ${EXAMPLE_TEST_CASE_DEPENDANCIES} DESCRIPTION "${DOCUMENTATION}" ) diff --git a/Modules/Registration/Common/test/CMakeLists.txt b/Modules/Registration/Common/test/CMakeLists.txt index f209a067c16..8b86fae78ab 100644 --- a/Modules/Registration/Common/test/CMakeLists.txt +++ b/Modules/Registration/Common/test/CMakeLists.txt @@ -225,3 +225,11 @@ itk_add_test(NAME itkEuclideanDistancePointMetricTestSquaredDistanceOff COMMAND ITKRegistrationCommonTestDriver itkEuclideanDistancePointMetricTest 0) itk_add_test(NAME itkEuclideanDistancePointMetricTestSquaredDistanceOn COMMAND ITKRegistrationCommonTestDriver itkEuclideanDistancePointMetricTest 1) + +if(BUILD_EXAMPLES) +#The historical examples from RegistrationITKv3 should no longer be used +#as exemplars for best practices, but do provide reasonable historically +#relavant tests to exercise the toolkit in ways that older software +#bases may continue to use for backwards compatibility reasons. +add_subdirectory(RegistrationITKv3) +endif() diff --git a/Modules/Registration/Common/test/RegistrationITKv3/CMakeLists.txt b/Modules/Registration/Common/test/RegistrationITKv3/CMakeLists.txt new file mode 100644 index 00000000000..d1d337b3ced --- /dev/null +++ b/Modules/Registration/Common/test/RegistrationITKv3/CMakeLists.txt @@ -0,0 +1,74 @@ +project(ITKv3ImageRegistration) + +add_executable(ITKv3ImageRegistration3 ImageRegistration3.cxx ) +target_link_libraries(ITKv3ImageRegistration3 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3ImageRegistration5 ImageRegistration5.cxx ) +target_link_libraries(ITKv3ImageRegistration5 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3ImageRegistration6 ImageRegistration6.cxx ) +target_link_libraries(ITKv3ImageRegistration6 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3ImageRegistration8 ImageRegistration8.cxx ) +target_link_libraries(ITKv3ImageRegistration8 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3ImageRegistration9 ImageRegistration9.cxx ) +target_link_libraries(ITKv3ImageRegistration9 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3DeformableRegistration4 DeformableRegistration4.cxx ) +target_link_libraries(ITKv3DeformableRegistration4 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3ImageRegistration4 ImageRegistration4.cxx ) +target_link_libraries(ITKv3ImageRegistration4 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3ImageRegistration7 ImageRegistration7.cxx ) +target_link_libraries(ITKv3ImageRegistration7 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3ImageRegistration11 ImageRegistration11.cxx ) +target_link_libraries(ITKv3ImageRegistration11 "${ITKRegistrationCommon-Test_LIBRARIES}") + +# This example in getting stuck and timing out, likely due to spatial +# object changes. +if (TEST_DISABLED) +add_executable(ITKv3ImageRegistration12 ImageRegistration12.cxx ) +target_link_libraries(ITKv3ImageRegistration12 "${ITKRegistrationCommon-Test_LIBRARIES}") +endif() + +add_executable(ITKv3ImageRegistration13 ImageRegistration13.cxx ) +target_link_libraries(ITKv3ImageRegistration13 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3ImageRegistration14 ImageRegistration14.cxx ) +target_link_libraries(ITKv3ImageRegistration14 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3DeformableRegistration6 DeformableRegistration6.cxx ) +target_link_libraries(ITKv3DeformableRegistration6 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3DeformableRegistration7 DeformableRegistration7.cxx ) +target_link_libraries(ITKv3DeformableRegistration7 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3DeformableRegistration8 DeformableRegistration8.cxx ) +target_link_libraries(ITKv3DeformableRegistration8 "${ITKRegistrationCommon-Test_LIBRARIES}") + +if( ITK_USE_FFTWD AND NOT ITK_USE_CUFFTW ) + add_executable(ITKv3DeformableRegistration10 DeformableRegistration10.cxx ) + target_link_libraries(ITKv3DeformableRegistration10 "${ITKRegistrationCommon-Test_LIBRARIES}") +endif() + +add_executable(ITKv3MultiResImageRegistration1 MultiResImageRegistration1.cxx ) +target_link_libraries(ITKv3MultiResImageRegistration1 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3DeformableRegistration12 DeformableRegistration12.cxx ) +target_link_libraries(ITKv3DeformableRegistration12 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3ImageRegistration1 ImageRegistration1.cxx ) +target_link_libraries(ITKv3ImageRegistration1 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3MeanSquaresImageMetric1 MeanSquaresImageMetric1.cxx ) +target_link_libraries(ITKv3MeanSquaresImageMetric1 "${ITKRegistrationCommon-Test_LIBRARIES}") + +add_executable(ITKv3DeformationFieldJacobian DeformationFieldJacobian.cxx ) +target_link_libraries(ITKv3DeformationFieldJacobian "${ITKRegistrationCommon-Test_LIBRARIES}") + +if(BUILD_TESTING) + add_subdirectory(test) +endif() diff --git a/Examples/RegistrationITKv3/DeformableRegistration10.cxx b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration10.cxx similarity index 90% rename from Examples/RegistrationITKv3/DeformableRegistration10.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration10.cxx index bcd328a039b..806501f655a 100644 --- a/Examples/RegistrationITKv3/DeformableRegistration10.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration10.cxx @@ -53,22 +53,22 @@ constexpr unsigned int Dimension = 3; using DisplacementFieldType = itk::Image< VectorPixelType, Dimension >; using RegistrationFilterType = itk::CurvatureRegistrationFilter< - InternalImageType, InternalImageType, - DisplacementFieldType, - itk::FastSymmetricForcesDemonsRegistrationFunction< - InternalImageType, InternalImageType, - DisplacementFieldType> >; + InternalImageType, + InternalImageType, + DisplacementFieldType, + itk::FastSymmetricForcesDemonsRegistrationFunction< + InternalImageType,InternalImageType,DisplacementFieldType> >; public: - void Execute(itk::Object *caller, const itk::EventObject & event) + void Execute(itk::Object *caller, const itk::EventObject & event) override { Execute( (const itk::Object *)caller, event); } void Execute(const itk::Object * object, const itk::EventObject & event) { - const RegistrationFilterType * filter = static_cast< const RegistrationFilterType * >( object ); + const auto * filter = static_cast< const RegistrationFilterType * >( object ); if( !(itk::IterationEvent().CheckEvent( &event )) ) { return; @@ -78,8 +78,10 @@ constexpr unsigned int Dimension = 3; }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -134,12 +136,10 @@ int main( int argc, char *argv[] ) using VectorPixelType = itk::Vector< float, Dimension >; using DisplacementFieldType = itk::Image< VectorPixelType, Dimension >; using RegistrationFilterType = itk::CurvatureRegistrationFilter< - InternalImageType, - InternalImageType, - DisplacementFieldType, - itk::FastSymmetricForcesDemonsRegistrationFunction< - InternalImageType,InternalImageType, - DisplacementFieldType> >; + InternalImageType, InternalImageType, DisplacementFieldType, + itk::FastSymmetricForcesDemonsRegistrationFunction< + InternalImageType,InternalImageType,DisplacementFieldType> >; + RegistrationFilterType::Pointer filter = RegistrationFilterType::New(); filter->SetTimeStep( 1 ); filter->SetConstraintWeight( 0.1 ); diff --git a/Examples/RegistrationITKv3/DeformableRegistration12.cxx b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration12.cxx similarity index 91% rename from Examples/RegistrationITKv3/DeformableRegistration12.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration12.cxx index 83e60179ba9..23281f72f00 100644 --- a/Examples/RegistrationITKv3/DeformableRegistration12.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration12.cxx @@ -16,7 +16,6 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // This example illustrates the use of the // \doxygen{BSplineTransform} class for performing @@ -30,7 +29,6 @@ // \index{itk::LBFGSBOptimizer} // // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMattesMutualInformationImageToImageMetric.h" @@ -39,21 +37,17 @@ #include "itkTimeProbesCollectorBase.h" #include "itkMemoryProbesCollectorBase.h" -// Software Guide : BeginLatex + // // The following are the most relevant headers to this example. // // \index{itk::BSplineTransform!header} // \index{itk::LBFGSBOptimizer!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkBSplineTransform.h" #include "itkLBFGSBOptimizer.h" -// Software Guide : EndCodeSnippet -// Software Guide : BeginLatex // // The parameter space of the \code{BSplineTransform} is composed by // the set of all the deformations associated with the nodes of the BSpline @@ -63,7 +57,6 @@ // // \index{itk::BSplineTransform!header} // -// Software Guide : EndLatex #include "itkImageFileReader.h" #include "itkImageFileWriter.h" @@ -72,7 +65,6 @@ #include "itkCastImageFilter.h" #include "itkSquaredDifferenceImageFilter.h" - // The following section of code implements a Command observer // used to monitor the evolution of the registration process. // @@ -86,7 +78,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::LBFGSBOptimizer; @@ -99,7 +91,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( !(itk::IterationEvent().CheckEvent( &event )) ) { return; @@ -110,9 +102,10 @@ class CommandIterationUpdate : public itk::Command } }; - +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -132,7 +125,7 @@ int main( int argc, char *argv[] ) using FixedImageType = itk::Image< PixelType, ImageDimension >; using MovingImageType = itk::Image< PixelType, ImageDimension >; - // Software Guide : BeginLatex + // // We instantiate now the type of the \code{BSplineTransform} using // as template parameters the type for coordinates representation, the @@ -141,9 +134,7 @@ int main( int argc, char *argv[] ) // \index{BSplineTransform!New} // \index{BSplineTransform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet const unsigned int SpaceDimension = ImageDimension; constexpr unsigned int SplineOrder = 3; using CoordinateRepType = double; @@ -152,7 +143,6 @@ int main( int argc, char *argv[] ) CoordinateRepType, SpaceDimension, SplineOrder >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::LBFGSBOptimizer; @@ -181,18 +171,14 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // // The transform object is constructed below and passed to the registration // method. // \index{itk::RegistrationMethod!SetTransform()} // - // Software Guide : EndLatex - - // Software Guide : BeginCodeSnippet - TransformType::Pointer transform = TransformType::New(); + // + TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; @@ -215,7 +201,6 @@ int main( int argc, char *argv[] ) registration->SetFixedImageRegion( fixedRegion ); - // Software Guide : BeginCodeSnippet unsigned int numberOfGridNodesInOneDimension = 7; @@ -228,48 +213,38 @@ int main( int argc, char *argv[] ) fixedOrigin[i] = fixedImage->GetOrigin()[i]; fixedPhysicalDimensions[i] = fixedImage->GetSpacing()[i] * static_cast( - fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 ); + fixedImage->GetLargestPossibleRegion().GetSize()[i] - 1 ); } meshSize.Fill( numberOfGridNodesInOneDimension - SplineOrder ); transform->SetTransformDomainOrigin( fixedOrigin ); - transform->SetTransformDomainPhysicalDimensions( - fixedPhysicalDimensions ); + transform->SetTransformDomainPhysicalDimensions( fixedPhysicalDimensions ); transform->SetTransformDomainMeshSize( meshSize ); transform->SetTransformDomainDirection( fixedImage->GetDirection() ); using ParametersType = TransformType::ParametersType; - const unsigned int numberOfParameters = - transform->GetNumberOfParameters(); + const unsigned int numberOfParameters = transform->GetNumberOfParameters(); ParametersType parameters( numberOfParameters ); parameters.Fill( 0.0 ); transform->SetParameters( parameters ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We now pass the parameters of the current transform as the initial // parameters to be used when the registration process starts. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Next we set the parameters of the LBFGSB Optimizer. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet OptimizerType::BoundSelectionType boundSelect( transform->GetNumberOfParameters() ); OptimizerType::BoundValueType upperBound( @@ -290,7 +265,6 @@ int main( int argc, char *argv[] ) optimizer->SetMaximumNumberOfIterations( 200 ); optimizer->SetMaximumNumberOfEvaluations( 200 ); optimizer->SetMaximumNumberOfCorrections( 7 ); - // Software Guide : EndCodeSnippet // Create the Command observer and register it with the optimizer. // @@ -325,7 +299,7 @@ int main( int argc, char *argv[] ) metric->ReinitializeSeed(121212); - // Add a time probe + // Add time and memory probes itk::TimeProbesCollectorBase chronometer; itk::MemoryProbesCollectorBase memorymeter; @@ -360,9 +334,7 @@ int main( int argc, char *argv[] ) chronometer.Report( std::cout ); memorymeter.Report( std::cout ); - // Software Guide : BeginCodeSnippet transform->SetParameters( finalParameters ); - // Software Guide : EndCodeSnippet using ResampleFilterType = itk::ResampleImageFilter< diff --git a/Examples/RegistrationITKv3/DeformableRegistration4.cxx b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration4.cxx similarity index 91% rename from Examples/RegistrationITKv3/DeformableRegistration4.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration4.cxx index 66566b26305..041ee968779 100644 --- a/Examples/RegistrationITKv3/DeformableRegistration4.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration4.cxx @@ -16,7 +16,6 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // This example illustrates the use of the \doxygen{BSplineTransform} // class for performing registration of two $2D$ images. The example code is @@ -33,7 +32,6 @@ // \index{itk::LBFGSOptimizer} // // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMeanSquaresImageToImageMetric.h" @@ -41,31 +39,25 @@ #include "itkTimeProbesCollectorBase.h" #include "itkMemoryProbesCollectorBase.h" -// Software Guide : BeginLatex // // The following are the most relevant headers to this example. // // \index{itk::BSplineTransform!header} // \index{itk::LBFGSOptimizer!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkBSplineTransform.h" #include "itkLBFGSOptimizer.h" -// Software Guide : EndCodeSnippet -// Software Guide : BeginLatex // // The parameter space of the \code{BSplineTransform} is composed by // the set of all the deformations associated with the nodes of the BSpline -// grid. This large number of parameters makes possible to represent a wide -// variety of deformations, but it also has the price of requiring a +// grid. This large number of parameters makes it possible to represent a wide +// variety of deformations, at the cost of requiring a // significant amount of computation time. // // \index{itk::BSplineTransform!header} // -// Software Guide : EndLatex #include "itkImageFileReader.h" #include "itkImageFileWriter.h" @@ -78,8 +70,10 @@ // NOTE: the LBFGSOptimizer does not invoke events +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -97,7 +91,6 @@ int main( int argc, char *argv[] ) using MovingImageType = itk::Image< PixelType, ImageDimension >; - // Software Guide : BeginLatex // // We instantiate now the type of the \code{BSplineTransform} using // as template parameters the type for coordinates representation, the @@ -106,9 +99,7 @@ int main( int argc, char *argv[] ) // \index{BSplineTransform!New} // \index{BSplineTransform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet const unsigned int SpaceDimension = ImageDimension; constexpr unsigned int SplineOrder = 3; using CoordinateRepType = double; @@ -117,7 +108,6 @@ int main( int argc, char *argv[] ) CoordinateRepType, SpaceDimension, SplineOrder >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::LBFGSOptimizer; @@ -146,18 +136,14 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // // The transform object is constructed below and passed to the registration // method. // \index{itk::RegistrationMethod!SetTransform()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; @@ -179,7 +165,6 @@ int main( int argc, char *argv[] ) registration->SetFixedImageRegion( fixedRegion ); - // Software Guide : BeginCodeSnippet TransformType::PhysicalDimensionsType fixedPhysicalDimensions; TransformType::MeshSizeType meshSize; @@ -212,35 +197,26 @@ int main( int argc, char *argv[] ) parameters.Fill( 0.0 ); transform->SetParameters( parameters ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We now pass the parameters of the current transform as the initial // parameters to be used when the registration process starts. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet std::cout << "Intial Parameters = " << std::endl; std::cout << transform->GetParameters() << std::endl; - // Software Guide : BeginLatex // // Next we set the parameters of the LBFGS Optimizer. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet optimizer->SetGradientConvergenceTolerance( 0.05 ); optimizer->SetLineSearchAccuracy( 0.9 ); optimizer->SetDefaultStepLength( 1.5 ); optimizer->TraceOn(); optimizer->SetMaximumNumberOfFunctionEvaluations( 1000 ); - // Software Guide : EndCodeSnippet // Add time and memory probes itk::TimeProbesCollectorBase chronometer; @@ -280,7 +256,6 @@ int main( int argc, char *argv[] ) chronometer.Report( std::cout ); memorymeter.Report( std::cout ); - // Software Guide : BeginLatex // // Let's execute this example using the rat lung images from the previous examples. // @@ -290,11 +265,8 @@ int main( int argc, char *argv[] ) // \end{itemize} // // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet transform->SetParameters( finalParameters ); - // Software Guide : EndCodeSnippet using ResampleFilterType = itk::ResampleImageFilter< diff --git a/Examples/RegistrationITKv3/DeformableRegistration6.cxx b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration6.cxx similarity index 93% rename from Examples/RegistrationITKv3/DeformableRegistration6.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration6.cxx index f0d5d80faf3..d50778fdfa6 100644 --- a/Examples/RegistrationITKv3/DeformableRegistration6.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration6.cxx @@ -16,7 +16,6 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // This example illustrates the use of the \doxygen{BSplineTransform} // class in a manually controlled multi-resolution scheme. Here we define two @@ -33,24 +32,19 @@ // \index{itk::LBFGSOptimizer} // // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMeanSquaresImageToImageMetric.h" -// Software Guide : BeginLatex // -// We include the header files for the transform and the optimizer. +// We include the header files for the transform, optimizer and adaptor. // // \index{itk::BSplineTransform!header} // \index{itk::LBFGSOptimizer!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkBSplineTransform.h" #include "itkLBFGSOptimizer.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" @@ -67,8 +61,10 @@ // NOTE: the LBFGSOptimizer does not invoke events +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -86,18 +82,15 @@ int main( int argc, char *argv[] ) using MovingImageType = itk::Image< PixelType, ImageDimension >; - // Software Guide : BeginLatex // - // We instantiate now the type of the \code{BSplineTransform} using + // We instantiate the type of the \code{BSplineTransform} using // as template parameters the type for coordinates representation, the // dimension of the space, and the order of the BSpline. // // \index{BSplineTransform!New} // \index{BSplineTransform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet const unsigned int SpaceDimension = ImageDimension; constexpr unsigned int SplineOrder = 3; using CoordinateRepType = double; @@ -106,7 +99,6 @@ int main( int argc, char *argv[] ) CoordinateRepType, SpaceDimension, SplineOrder >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::LBFGSOptimizer; @@ -135,7 +127,6 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // // We construct two transform objects, each one will be configured for a resolution level. // Notice than in this multi-resolution scheme we are not modifying the @@ -144,12 +135,9 @@ int main( int argc, char *argv[] ) // // \index{itk::RegistrationMethod!SetTransform()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer transformLow = TransformType::New(); registration->SetTransform( transformLow ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; @@ -203,16 +191,12 @@ int main( int argc, char *argv[] ) parametersLow.Fill( 0.0 ); transformLow->SetParameters( parametersLow ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We now pass the parameters of the current transform as the initial // parameters to be used when the registration process starts. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transformLow->GetParameters() ); @@ -237,16 +221,13 @@ int main( int argc, char *argv[] ) std::cerr << err << std::endl; return EXIT_FAILURE; } - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Once the registration has finished with the low resolution grid, we // proceed to instantiate a higher resolution // \code{BSplineTransform}. // - // Software Guide : EndLatex TransformType::Pointer transformHigh = TransformType::New(); @@ -270,7 +251,6 @@ int main( int argc, char *argv[] ) ParametersType parametersHigh( transformHigh->GetNumberOfParameters() ); parametersHigh.Fill( 0.0 ); - // Software Guide : BeginLatex // // Now we need to initialize the BSpline coefficients of the higher resolution // transform. This is done by first computing the actual deformation field @@ -278,7 +258,6 @@ int main( int argc, char *argv[] ) // Then a BSpline decomposition is done to obtain the BSpline coefficient of // the higher resolution transform. // - // Software Guide : EndLatex unsigned int counter = 0; @@ -329,24 +308,19 @@ int main( int argc, char *argv[] ) transformHigh->SetParameters( parametersHigh ); - // Software Guide : BeginLatex // // We now pass the parameters of the high resolution transform as the initial // parameters to be used in a second stage of the registration process. // - // Software Guide : EndLatex std::cout << "Starting Registration with high resolution transform" << std::endl; - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters(transformHigh->GetParameters()); registration->SetTransform( transformHigh ); - // Software Guide : BeginLatex // // Typically, we will also want to tighten the optimizer parameters // when we move from lower to higher resolution grid. // - // Software Guide : EndLatex optimizer->SetGradientConvergenceTolerance( 0.01 ); optimizer->SetDefaultStepLength( 0.25 ); try @@ -359,7 +333,6 @@ int main( int argc, char *argv[] ) std::cerr << err << std::endl; return EXIT_FAILURE; } - // Software Guide : EndCodeSnippet // Finally we use the last transform parameters in order to resample the image. // diff --git a/Examples/RegistrationITKv3/DeformableRegistration7.cxx b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration7.cxx similarity index 92% rename from Examples/RegistrationITKv3/DeformableRegistration7.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration7.cxx index 1d8f7fd33fb..78f6b6cc5ea 100644 --- a/Examples/RegistrationITKv3/DeformableRegistration7.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration7.cxx @@ -16,7 +16,6 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // This example illustrates the use of the \doxygen{BSplineTransform} // class for performing registration of two $3D$ images. The example code is @@ -25,7 +24,7 @@ // that this example we set the image dimension to 3 and replace the // \doxygen{LBFGSOptimizer} optimizer with the \doxygen{LBFGSBOptimizer}. We // made the modification because we found that LBFGS does not behave well when -// the starting positions is at or close to optimal; instead we used LBFGSB in +// the starting position is at or close to optimal; instead we used LBFGSB in // unconstrained mode. // // @@ -34,7 +33,6 @@ // \index{itk::LBFGSOptimizer} // // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMeanSquaresImageToImageMetric.h" @@ -42,31 +40,25 @@ #include "itkTimeProbesCollectorBase.h" #include "itkMemoryProbesCollectorBase.h" -// Software Guide : BeginLatex // // The following are the most relevant headers to this example. // // \index{itk::BSplineTransform!header} // \index{itk::LBFGSOptimizer!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkBSplineTransform.h" #include "itkLBFGSBOptimizer.h" -// Software Guide : EndCodeSnippet -// Software Guide : BeginLatex // // The parameter space of the \code{BSplineTransform} is composed by // the set of all the deformations associated with the nodes of the BSpline -// grid. This large number of parameters makes possible to represent a wide -// variety of deformations, but it also has the price of requiring a +// grid. This large number of parameters enables it to represent a wide +// variety of deformations, at the cost of requiring a // significant amount of computation time. // // \index{itk::BSplineTransform!header} // -// Software Guide : EndLatex #include "itkImageFileReader.h" #include "itkImageFileWriter.h" @@ -89,16 +81,16 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::LBFGSBOptimizer; using OptimizerPointer = const OptimizerType *; void Execute(itk::Object *caller, const itk::EventObject & event) override - { - Execute( (const itk::Object *)caller, event); - } + { + Execute( (const itk::Object *)caller, event); + } void Execute(const itk::Object * object, const itk::EventObject & event) override { @@ -114,8 +106,10 @@ class CommandIterationUpdate : public itk::Command }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -133,7 +127,6 @@ int main( int argc, char *argv[] ) using MovingImageType = itk::Image< PixelType, ImageDimension >; - // Software Guide : BeginLatex // // We instantiate now the type of the \code{BSplineTransform} using // as template parameters the type for coordinates representation, the @@ -142,9 +135,7 @@ int main( int argc, char *argv[] ) // \index{BSplineTransform!New} // \index{BSplineTransform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet const unsigned int SpaceDimension = ImageDimension; constexpr unsigned int SplineOrder = 3; using CoordinateRepType = double; @@ -153,7 +144,6 @@ int main( int argc, char *argv[] ) CoordinateRepType, SpaceDimension, SplineOrder >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::LBFGSBOptimizer; @@ -182,18 +172,14 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // // The transform object is constructed below and passed to the registration // method. // \index{itk::RegistrationMethod!SetTransform()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; @@ -215,7 +201,6 @@ int main( int argc, char *argv[] ) registration->SetFixedImageRegion( fixedRegion ); - // Software Guide : BeginCodeSnippet unsigned int numberOfGridNodes = 8; TransformType::PhysicalDimensionsType fixedPhysicalDimensions; @@ -247,27 +232,20 @@ int main( int argc, char *argv[] ) parameters.Fill( 0.0 ); transform->SetParameters( parameters ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We now pass the parameters of the current transform as the initial // parameters to be used when the registration process starts. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet std::cout << "Intial Parameters = " << std::endl; std::cout << transform->GetParameters() << std::endl; - // Software Guide : BeginLatex // // Next we set the parameters of the LBFGSB Optimizer. // - // Software Guide : EndLatex OptimizerType::BoundSelectionType boundSelect( transform->GetNumberOfParameters() ); OptimizerType::BoundValueType upperBound( transform->GetNumberOfParameters() ); OptimizerType::BoundValueType lowerBound( transform->GetNumberOfParameters() ); @@ -330,9 +308,7 @@ int main( int argc, char *argv[] ) chronometer.Report( std::cout ); memorymeter.Report( std::cout ); - // Software Guide : BeginCodeSnippet transform->SetParameters( finalParameters ); - // Software Guide : EndCodeSnippet using ResampleFilterType = itk::ResampleImageFilter< diff --git a/Examples/RegistrationITKv3/DeformableRegistration8.cxx b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration8.cxx similarity index 92% rename from Examples/RegistrationITKv3/DeformableRegistration8.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration8.cxx index 4658a86e5cf..33bf87304f4 100644 --- a/Examples/RegistrationITKv3/DeformableRegistration8.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/DeformableRegistration8.cxx @@ -16,7 +16,6 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // This example illustrates the use of the \doxygen{BSplineTransform} // class for performing registration of two $3D$ images and for the case of @@ -28,7 +27,6 @@ // \index{itk::LBFGSBOptimizer} // // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMattesMutualInformationImageToImageMetric.h" @@ -37,21 +35,16 @@ #include "itkMemoryProbesCollectorBase.h" -// Software Guide : BeginLatex // // The following are the most relevant headers to this example. // // \index{itk::BSplineTransform!header} // \index{itk::LBFGSBOptimizer!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkBSplineTransform.h" #include "itkLBFGSBOptimizer.h" -// Software Guide : EndCodeSnippet -// Software Guide : BeginLatex // // The parameter space of the \code{BSplineTransform} is composed by // the set of all the deformations associated with the nodes of the BSpline @@ -61,7 +54,6 @@ // // \index{itk::BSplineTransform!header} // -// Software Guide : EndLatex #include "itkImageFileReader.h" #include "itkImageFileWriter.h" @@ -111,8 +103,10 @@ class CommandIterationUpdate : public itk::Command }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -133,7 +127,6 @@ int main( int argc, char *argv[] ) using MovingImageType = itk::Image< PixelType, ImageDimension >; - // Software Guide : BeginLatex // // We instantiate now the type of the \code{BSplineTransform} using // as template parameters the type for coordinates representation, the @@ -142,9 +135,7 @@ int main( int argc, char *argv[] ) // \index{BSplineTransform!New} // \index{BSplineTransform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet const unsigned int SpaceDimension = ImageDimension; constexpr unsigned int SplineOrder = 3; using CoordinateRepType = double; @@ -153,7 +144,6 @@ int main( int argc, char *argv[] ) CoordinateRepType, SpaceDimension, SplineOrder >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::LBFGSBOptimizer; @@ -182,18 +172,14 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // // The transform object is constructed below and passed to the registration // method. // \index{itk::RegistrationMethod!SetTransform()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; @@ -223,7 +209,6 @@ int main( int argc, char *argv[] ) numberOfGridNodesInOneDimension = std::stoi( argv[10] ); } - // Software Guide : BeginCodeSnippet TransformType::PhysicalDimensionsType fixedPhysicalDimensions; TransformType::MeshSizeType meshSize; @@ -254,28 +239,20 @@ int main( int argc, char *argv[] ) parameters.Fill( 0.0 ); transform->SetParameters( parameters ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We now pass the parameters of the current transform as the initial // parameters to be used when the registration process starts. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Next we set the parameters of the LBFGSB Optimizer. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet const unsigned int numParameters = transform->GetNumberOfParameters(); OptimizerType::BoundSelectionType boundSelect( numParameters ); OptimizerType::BoundValueType upperBound( numParameters ); @@ -294,7 +271,6 @@ int main( int argc, char *argv[] ) optimizer->SetMaximumNumberOfIterations( 200 ); optimizer->SetMaximumNumberOfEvaluations( 30 ); optimizer->SetMaximumNumberOfCorrections( 5 ); - // Software Guide : EndCodeSnippet // Create the Command observer and register it with the optimizer. // @@ -302,22 +278,17 @@ int main( int argc, char *argv[] ) optimizer->AddObserver( itk::IterationEvent(), observer ); - // Software Guide : BeginLatex // // Next we set the parameters of the Mattes Mutual Information Metric. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet metric->SetNumberOfHistogramBins( 50 ); const unsigned int numberOfSamples = static_cast( fixedRegion.GetNumberOfPixels() * 0.2F ); metric->SetNumberOfSpatialSamples( numberOfSamples ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Given that the Mattes Mutual Information metric uses a random iterator in // order to collect the samples from the images, it is usually convenient to @@ -325,11 +296,8 @@ int main( int argc, char *argv[] ) // // \index{itk::Mattes\-Mutual\-Information\-Image\-To\-Image\-Metric!ReinitializeSeed()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet metric->ReinitializeSeed( 76926294 ); - // Software Guide : EndCodeSnippet if( argc > 7 ) { @@ -386,9 +354,7 @@ int main( int argc, char *argv[] ) chronometer.Report( std::cout ); memorymeter.Report( std::cout ); - // Software Guide : BeginCodeSnippet transform->SetParameters( finalParameters ); - // Software Guide : EndCodeSnippet using ResampleFilterType = itk::ResampleImageFilter< diff --git a/Examples/RegistrationITKv3/DeformationFieldJacobian.cxx b/Modules/Registration/Common/test/RegistrationITKv3/DeformationFieldJacobian.cxx similarity index 86% rename from Examples/RegistrationITKv3/DeformationFieldJacobian.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/DeformationFieldJacobian.cxx index e8e4411d77a..a82d571a1ce 100644 --- a/Examples/RegistrationITKv3/DeformationFieldJacobian.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/DeformationFieldJacobian.cxx @@ -19,10 +19,13 @@ #include "itkImageFileReader.h" #include "itkImageFileWriter.h" -#include "itkDeformationFieldJacobianDeterminantFilter.h" +// itkDeformationFieldJacobianDeterminantFilter.h -> itkDisplacementFieldJacobianDeterminantFilter.h +#include "itkDisplacementFieldJacobianDeterminantFilter.h" +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char * argv[] ) { + RegisterRequiredFactories(); if( argc < 3 ) { std::cerr << "Usage: " << std::endl; @@ -39,7 +42,7 @@ int main( int argc, char * argv[] ) using ReaderType = itk::ImageFileReader< InputImageType >; - using FilterType = itk::DeformationFieldJacobianDeterminantFilter< InputImageType >; + using FilterType = itk::DisplacementFieldJacobianDeterminantFilter< InputImageType >; // Set up deformation field reader ReaderType::Pointer reader = ReaderType::New(); diff --git a/Examples/RegistrationITKv3/ImageRegistration1.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration1.cxx similarity index 79% rename from Examples/RegistrationITKv3/ImageRegistration1.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration1.cxx index bc0839f5d53..7fd1333d8f1 100644 --- a/Examples/RegistrationITKv3/ImageRegistration1.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration1.cxx @@ -16,15 +16,12 @@ * *=========================================================================*/ -// Software Guide : BeginCommandLineArgs // INPUTS: {BrainProtonDensitySliceBorder20.png} // INPUTS: {BrainProtonDensitySliceShifted13x17y.png} // OUTPUTS: {ImageRegistration1Output.png} // OUTPUTS: {ImageRegistration1DifferenceAfter.png} // OUTPUTS: {ImageRegistration1DifferenceBefore.png} -// Software Guide : EndCommandLineArgs -// Software Guide : BeginLatex // // This example illustrates the use of the image registration framework in // Insight. It should be read as a ``Hello World'' for ITK registration. @@ -41,15 +38,12 @@ // registration is intended. The following header files provide declarations // of common types used for these components. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkImageRegistrationMethod.h" #include "itkTranslationTransform.h" #include "itkMeanSquaresImageToImageMetric.h" #include "itkRegularStepGradientDescentOptimizer.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" @@ -70,7 +64,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: @@ -84,7 +78,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { @@ -99,131 +93,92 @@ class CommandIterationUpdate : public itk::Command }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; std::cerr << "Usage: " << argv[0]; std::cerr << " fixedImageFile movingImageFile "; std::cerr << "outputImagefile [differenceImageAfter]"; - std::cerr << "[differenceImageBefore]" << std::endl; + std::cerr << "[differenceImageBefore] [useEstimator]" << std::endl; return EXIT_FAILURE; } - // Software Guide : BeginLatex // - // The types of each one of the components in the registration methods should + // The type of each registration component should // be instantiated first. We start by selecting the image // dimension and the types to be used for representing image pixels. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet constexpr unsigned int Dimension = 2; using PixelType = float; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The types of the input images are instantiated by the following lines. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using FixedImageType = itk::Image< PixelType, Dimension >; using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The transform that will map the fixed image space into the moving image // space is defined below. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformType = itk::TranslationTransform< double, Dimension >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // An optimizer is required to explore the parameter space of the transform // in search of optimal values of the metric. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using OptimizerType = itk::RegularStepGradientDescentOptimizer; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The metric will compare how well the two images match each other. Metric // types are usually templated over the image types as seen in // the following type declaration. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using MetricType = itk::MeanSquaresImageToImageMetric< - FixedImageType, - MovingImageType >; - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex - // - // Finally, the type of the interpolator is declared. The interpolator will - // evaluate the intensities of the moving image at non-grid positions. - // - // Software Guide : EndLatex + FixedImageType, + MovingImageType >; - // Software Guide : BeginCodeSnippet using InterpolatorType = itk:: LinearInterpolateImageFunction< MovingImageType, double >; - // Software Guide : EndCodeSnippet - - - // Software Guide : BeginLatex // // The registration method type is instantiated using the types of the - // fixed and moving images. This class is responsible for interconnecting - // all the components that we have described so far. + // fixed and moving images as well as the output transform type. This class + // is responsible for interconnecting all the components that we have described so far. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using RegistrationType = itk::ImageRegistrationMethod< FixedImageType, MovingImageType >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Each one of the registration components is created using its // \code{New()} method and is assigned to its respective // \doxygen{SmartPointer}. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet MetricType::Pointer metric = MetricType::New(); TransformType::Pointer transform = TransformType::New(); OptimizerType::Pointer optimizer = OptimizerType::New(); InterpolatorType::Pointer interpolator = InterpolatorType::New(); RegistrationType::Pointer registration = RegistrationType::New(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Each component is now connected to the instance of the registration method. // \index{itk::RegistrationMethod!SetMetric()} @@ -233,14 +188,11 @@ int main( int argc, char *argv[] ) // \index{itk::RegistrationMethod!SetMovingImage()} // \index{itk::RegistrationMethod!SetInterpolator()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetMetric( metric ); registration->SetOptimizer( optimizer ); registration->SetTransform( transform ); registration->SetInterpolator( interpolator ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; @@ -252,21 +204,16 @@ int main( int argc, char *argv[] ) movingImageReader->SetFileName( argv[2] ); - // Software Guide : BeginLatex // // In this example, the fixed and moving images are read from files. This // requires the \doxygen{ImageRegistrationMethod} to acquire its inputs from // the output of the readers. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetFixedImage( fixedImageReader->GetOutput() ); registration->SetMovingImage( movingImageReader->GetOutput() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The registration can be restricted to consider only a particular region // of the fixed image as input to the metric computation. This region is @@ -281,16 +228,12 @@ int main( int argc, char *argv[] ) // \index{itk::ImageRegistrationMethod!SetFixedImageRegion()} // \index{itk::Image!GetBufferedRegion()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet fixedImageReader->Update(); registration->SetFixedImageRegion( fixedImageReader->GetOutput()->GetBufferedRegion() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The parameters of the transform are initialized by passing them in an // array. This can be used to setup an initial known correction of the @@ -305,9 +248,7 @@ int main( int argc, char *argv[] ) // \index{itk::TranslationTransform!GetNumberOfParameters()} // \index{itk::RegistrationMethod!SetInitialTransformParameters()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using ParametersType = RegistrationType::ParametersType; ParametersType initialParameters( transform->GetNumberOfParameters() ); @@ -315,10 +256,8 @@ int main( int argc, char *argv[] ) initialParameters[1] = 0.0; // Initial offset in mm along Y registration->SetInitialTransformParameters( initialParameters ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // At this point the registration method is ready for execution. The // optimizer is the component that drives the execution of the @@ -330,7 +269,7 @@ int main( int argc, char *argv[] ) // Each optimizer has particular parameters that must be interpreted in the // context of the optimization strategy it implements. The optimizer used in // this example is a variant of gradient descent that attempts to prevent it - // from taking steps that are too large. At each iteration, this optimizer + // from taking steps that are too large. At each iteration, this optimizer // will take a step along the direction of the \doxygen{ImageToImageMetric} // derivative. The initial length of the step is defined by the user. Each // time the direction of the derivative abruptly changes, the optimizer @@ -348,15 +287,11 @@ int main( int argc, char *argv[] ) // \index{itk::Regular\-Setp\-Gradient\-Descent\-Optimizer!SetMaximumStepLength()} // \index{itk::Regular\-Step\-Gradient\-Descent\-Optimizer!SetMinimumStepLength()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet optimizer->SetMaximumStepLength( 4.00 ); optimizer->SetMinimumStepLength( 0.01 ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // In case the optimizer never succeeds reaching the desired // precision tolerance, it is prudent to establish a limit on the number of @@ -365,11 +300,8 @@ int main( int argc, char *argv[] ) // // \index{itk::Regular\-Setp\-Gradient\-Descent\-Optimizer!SetNumberOfIterations()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet optimizer->SetNumberOfIterations( 200 ); - // Software Guide : EndCodeSnippet // Connect an observer @@ -377,17 +309,14 @@ int main( int argc, char *argv[] ) optimizer->AddObserver( itk::IterationEvent(), observer ); - // Software Guide : BeginLatex // - // The registration process is triggered by an invocation to the + // The registration process is triggered by an invocation of the // \code{Update()} method. If something goes wrong during the // initialization or execution of the registration an exception will be // thrown. We should therefore place the \code{Update()} method // inside a \code{try/catch} block as illustrated in the following lines. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet try { registration->Update(); @@ -398,18 +327,13 @@ int main( int argc, char *argv[] ) std::cerr << err << std::endl; return EXIT_FAILURE; } - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // - // In a real life application, you may attempt to recover from the error by - // taking more effective actions in the catch block. Here we are simply - // printing out a message and then terminating the execution of the program. + // In a real life application, you may attempt to recover from the error by + // taking more effective actions in the catch block. Here we are simply + // printing out a message and then terminating the execution of the program. // - // Software Guide : EndLatex - - // Software Guide : BeginLatex // // The result of the registration process is an array of parameters that // defines the spatial transformation in an unique way. This final result is @@ -417,28 +341,20 @@ int main( int argc, char *argv[] ) // // \index{itk::RegistrationMethod!GetLastTransformParameters()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet ParametersType finalParameters = registration->GetLastTransformParameters(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // In the case of the \doxygen{TranslationTransform}, there is a // straightforward interpretation of the parameters. Each element of the // array corresponds to a translation along one spatial dimension. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet const double TranslationAlongX = finalParameters[0]; const double TranslationAlongY = finalParameters[1]; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The optimizer can be queried for the actual number of iterations // performed to reach convergence. The \code{GetCurrentIteration()} @@ -448,22 +364,15 @@ int main( int argc, char *argv[] ) // // \index{itk::Regular\-Setp\-Gradient\-Descent\-Optimizer!GetCurrentIteration()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet const unsigned int numberOfIterations = optimizer->GetCurrentIteration(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The value of the image metric corresponding to the last set of parameters // can be obtained with the \code{GetValue()} method of the optimizer. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet const double bestValue = optimizer->GetValue(); - // Software Guide : EndCodeSnippet // Print out results @@ -475,7 +384,6 @@ int main( int argc, char *argv[] ) std::cout << " Metric value = " << bestValue << std::endl; - // Software Guide : BeginLatex // // Let's execute this example over two of the images provided in // \code{Examples/Data}: @@ -508,10 +416,8 @@ int main( int argc, char *argv[] ) // \end{figure} // // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // It is common, as the last step of a registration task, to use the // resulting transform to map the moving image into the fixed image space. @@ -522,29 +428,21 @@ int main( int argc, char *argv[] ) // the output type since it is likely that the transformed moving image // will be compared with the fixed image. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using ResampleFilterType = itk::ResampleImageFilter< MovingImageType, FixedImageType >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // A resampling filter is created and the moving image is connected as // its input. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput( movingImageReader->GetOutput() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The Transform that is produced as output of the Registration method is // also passed as input to the resampling filter. Note the use of the @@ -561,14 +459,10 @@ int main( int argc, char *argv[] ) // \index{itk::DataObjectDecorator!Use in Registration} // \index{itk::DataObjectDecorator!Get()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet resampler->SetTransform( registration->GetOutput()->Get() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // As described in Section \ref{sec:ResampleImageFilter}, the // ResampleImageFilter requires additional parameters to be specified, in @@ -576,19 +470,15 @@ int main( int argc, char *argv[] ) // pixel value is also set to a distinct gray level in order to highlight // the regions that are mapped outside of the moving image. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); resampler->SetSize( fixedImage->GetLargestPossibleRegion().GetSize() ); resampler->SetOutputOrigin( fixedImage->GetOrigin() ); resampler->SetOutputSpacing( fixedImage->GetSpacing() ); resampler->SetOutputDirection( fixedImage->GetDirection() ); resampler->SetDefaultPixelValue( 100 ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -600,59 +490,48 @@ int main( int argc, char *argv[] ) // \label{fig:ImageRegistration1Output} // \end{figure} // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // The output of the filter is passed to a writer that will store the // image in a file. An \doxygen{CastImageFilter} is used to convert the // pixel type of the resampled image to the final type used by the // writer. The cast and writer filters are instantiated below. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using OutputPixelType = unsigned char; + using OutputImageType = itk::Image< OutputPixelType, Dimension >; + using CastFilterType = itk::CastImageFilter< FixedImageType, OutputImageType >; + using WriterType = itk::ImageFileWriter< OutputImageType >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The filters are created by invoking their \code{New()} // method. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet WriterType::Pointer writer = WriterType::New(); CastFilterType::Pointer caster = CastFilterType::New(); - // Software Guide : EndCodeSnippet writer->SetFileName( argv[3] ); - // Software Guide : BeginLatex // // The filters are connected together and the \code{Update()} method of the // writer is invoked in order to trigger the execution of the pipeline. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet caster->SetInput( resampler->GetOutput() ); writer->SetInput( caster->GetOutput() ); writer->Update(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -663,18 +542,14 @@ int main( int argc, char *argv[] ) // \end{figure} // // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // The fixed image and the transformed moving image can easily be compared // using the \doxygen{SubtractImageFilter}. This pixel-wise filter computes // the difference between homologous pixels of its two input images. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using DifferenceFilterType = itk::SubtractImageFilter< FixedImageType, FixedImageType, @@ -684,34 +559,28 @@ int main( int argc, char *argv[] ) difference->SetInput1( fixedImageReader->GetOutput() ); difference->SetInput2( resampler->GetOutput() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Note that the use of subtraction as a method for comparing the images is // appropriate here because we chose to represent the images using a pixel // type \code{float}. A different filter would have been used if the pixel - // type of the images were any of the \code{unsigned} integer type. + // type of the images were any of the \code{unsigned} integer types. // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // Since the differences between the two images may correspond to very low // values of intensity, we rescale those intensities with a // \doxygen{RescaleIntensityImageFilter} in order to make them more visible. - // This rescaling will also make possible to visualize the negative values - // even if we save the difference image in a file format that only support + // This rescaling will also make it possible to visualize the negative values + // even if we save the difference image in a file format that only supports // unsigned pixel values\footnote{This is the case of PNG, BMP, JPEG and // TIFF among other common file formats.}. We also reduce the // \code{DefaultPixelValue} to ``1'' in order to prevent that value from // absorbing the dynamic range of the differences between the two images. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using RescalerType = itk::RescaleIntensityImageFilter< FixedImageType, OutputImageType >; @@ -723,19 +592,14 @@ int main( int argc, char *argv[] ) intensityRescaler->SetOutputMaximum( 255 ); resampler->SetDefaultPixelValue( 1 ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Its output can be passed to another writer. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet WriterType::Pointer writer2 = WriterType::New(); writer2->SetInput( intensityRescaler->GetOutput() ); - // Software Guide : EndCodeSnippet if( argc > 4 ) @@ -745,7 +609,6 @@ int main( int argc, char *argv[] ) } - // Software Guide : BeginLatex // // For the purpose of comparison, the difference between the fixed image and // the moving image before registration can also be computed by simply @@ -756,13 +619,10 @@ int main( int argc, char *argv[] ) // process with an identity transform will ensure that we have a // representation of the moving image in the grid of the fixed image. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer identityTransform = TransformType::New(); identityTransform->SetIdentity(); resampler->SetTransform( identityTransform ); - // Software Guide : EndCodeSnippet if( argc > 5 ) @@ -772,7 +632,6 @@ int main( int argc, char *argv[] ) } - // Software Guide : BeginLatex // // The complete pipeline structure of the current example is presented in // Figure~\ref{fig:ImageRegistration1Pipeline}. The components of the @@ -782,20 +641,18 @@ int main( int argc, char *argv[] ) // and right borders of the image appear in the gray level selected with the // \code{SetDefaultPixelValue()} in the ResampleImageFilter. The center // image shows the difference between the fixed image and the original - // moving image. That is, the difference before the registration is - // performed. The right image shows the difference between the fixed image - // and the transformed moving image. That is, after the registration has - // been performed. Both difference images have been rescaled in intensity + // moving image (i.e. the difference before the registration is + // performed). The right image shows the difference between the fixed image + // and the transformed moving image (i.e. after the registration has + // been performed). Both difference images have been rescaled in intensity // in order to highlight those pixels where differences exist. Note that // the final registration is still off by a fraction of a pixel, which - // results in bands around edges of anatomical structures to appear in the + // causes bands around edges of anatomical structures to appear in the // difference image. A perfect registration would have produced a null // difference image. // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -816,7 +673,6 @@ int main( int argc, char *argv[] ) // log plot helps to highlight the normal oscillations of the optimizer // around the extrema value. // - // Software Guide : EndLatex return EXIT_SUCCESS; diff --git a/Examples/RegistrationITKv3/ImageRegistration11.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration11.cxx similarity index 92% rename from Examples/RegistrationITKv3/ImageRegistration11.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration11.cxx index 102ffe9168e..7902c377cc9 100644 --- a/Examples/RegistrationITKv3/ImageRegistration11.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration11.cxx @@ -16,7 +16,6 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // This example illustrates how to combine the MutualInformation metric with an // Evolutionary algorithm for optimization. Evolutionary algorithms are @@ -31,16 +30,13 @@ // \index{itk::ImageRegistrationMethod!Multi-Modality} // \index{itk::OnePlusOneEvolutionaryOptimizer!Multi-Modality} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkImageRegistrationMethod.h" #include "itkTranslationTransform.h" #include "itkMattesMutualInformationImageToImageMetric.h" #include "itkOnePlusOneEvolutionaryOptimizer.h" #include "itkNormalVariateGenerator.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" @@ -76,7 +72,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -97,8 +93,10 @@ class CommandIterationUpdate : public itk::Command }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 3 ) { std::cerr << "Missing Parameters " << std::endl; @@ -124,7 +122,6 @@ int main( int argc, char *argv[] ) FixedImageType, MovingImageType >; - // Software Guide : BeginLatex // // In this example the image types and all registration components, // except the metric, are declared as in Section @@ -132,13 +129,10 @@ int main( int argc, char *argv[] ) // The Mattes mutual information metric type is // instantiated using the image types. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using MetricType = itk::MattesMutualInformationImageToImageMetric< FixedImageType, MovingImageType >; - // Software Guide : EndCodeSnippet TransformType::Pointer transform = TransformType::New(); OptimizerType::Pointer optimizer = OptimizerType::New(); @@ -191,7 +185,6 @@ int main( int argc, char *argv[] ) registration->SetInitialTransformParameters( initialParameters ); - // Software Guide : BeginLatex // // Evolutionary algorithms are based on testing random variations // of parameters. In order to support the computation of random values, @@ -202,29 +195,21 @@ int main( int argc, char *argv[] ) // \index{itk::NormalVariateGenerator!New()} // \index{itk::NormalVariateGenerator!Pointer} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using GeneratorType = itk::Statistics::NormalVariateGenerator; GeneratorType::Pointer generator = GeneratorType::New(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The random number generator must be initialized with a seed. // // \index{itk::NormalVariateGenerator!Initialize()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet generator->Initialize(12345); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Another significant difference in the metric is that it // computes the negative mutual information and hence we @@ -232,16 +217,13 @@ int main( int argc, char *argv[] ) // example we will use the same optimization parameters as in // Section \ref{sec:IntroductionImageRegistration}. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet optimizer->MaximizeOff(); optimizer->SetNormalVariateGenerator( generator ); optimizer->Initialize( 10 ); optimizer->SetEpsilon( 1.0 ); optimizer->SetMaximumIteration( 4000 ); - // Software Guide : EndCodeSnippet // Create the Command observer and register it with the optimizer. @@ -284,7 +266,6 @@ int main( int argc, char *argv[] ) std::cout << " Metric value = " << bestValue << std::endl; - // Software Guide : BeginLatex // // This example is executed using the same multi-modality images as // in the previous one. The registration converges after $24$ iterations and produces @@ -297,7 +278,6 @@ int main( int argc, char *argv[] ) // These values are a very close match to // the true misalignment introduced in the moving image. // - // Software Guide : EndLatex using ResampleFilterType = itk::ResampleImageFilter< diff --git a/Examples/RegistrationITKv3/ImageRegistration12.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration12.cxx similarity index 89% rename from Examples/RegistrationITKv3/ImageRegistration12.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration12.cxx index 2f3aa8aabd1..9c1dd005d6c 100644 --- a/Examples/RegistrationITKv3/ImageRegistration12.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration12.cxx @@ -16,15 +16,13 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // -// This example illustrates the use SpatialObjects as masks for selecting the +// This example illustrates the use of \code{SpatialObject}s as masks for selecting the // pixels that should contribute to the computation of Image Metrics. This // example is almost identical to ImageRegistration6 with the exception that -// the SpatialObject masks are created and passed to the image metric. +// the \code{SpatialObject} masks are created and passed to the image metric. // // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMeanSquaresImageToImageMetric.h" @@ -40,18 +38,14 @@ #include "itkCastImageFilter.h" #include "itkSquaredDifferenceImageFilter.h" -// Software Guide : BeginLatex // // The most important header in this example is the one corresponding to the // \doxygen{ImageMaskSpatialObject} class. // // \index{itk::ImageMaskSpatialObject!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkImageMaskSpatialObject.h" -// Software Guide : EndCodeSnippet // // The following section of code implements a command observer @@ -67,7 +61,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -80,7 +74,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -91,8 +85,10 @@ class CommandIterationUpdate : public itk::Command } }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 5 ) { std::cerr << "Missing Parameters " << std::endl; @@ -188,20 +184,15 @@ int main( int argc, char *argv[] ) CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); optimizer->AddObserver( itk::IterationEvent(), observer ); - // Software Guide : BeginLatex // // Here we instantiate the type of the \doxygen{ImageMaskSpatialObject} // using the same dimension of the images to be registered. // // \index{itk::ImageMaskSpatialObject!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using MaskType = itk::ImageMaskSpatialObject< Dimension >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Then we use the type for creating the spatial object mask that will // restrict the registration to a reduced region of the image. @@ -209,39 +200,27 @@ int main( int argc, char *argv[] ) // \index{itk::ImageMaskSpatialObject!New} // \index{itk::ImageMaskSpatialObject!Pointer} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet MaskType::Pointer spatialObjectMask = MaskType::New(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The mask in this case is read from a binary file using the // \code{ImageFileReader} instantiated for an \code{unsigned char} pixel // type. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using ImageMaskType = itk::Image< unsigned char, Dimension >; using MaskReaderType = itk::ImageFileReader< ImageMaskType >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The reader is constructed and a filename is passed to it. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet MaskReaderType::Pointer maskReader = MaskReaderType::New(); maskReader->SetFileName( argv[3] ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // As usual, the reader is triggered by invoking its \code{Update()} method. // Since this may eventually throw an exception, the call must be placed in @@ -249,9 +228,7 @@ int main( int argc, char *argv[] ) // this \code{try/catch} block at a much higher level, probably under the // control of the GUI. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet try { maskReader->Update(); @@ -262,32 +239,23 @@ int main( int argc, char *argv[] ) std::cerr << err << std::endl; return EXIT_FAILURE; } - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The output of the mask reader is connected as input to the // \code{ImageMaskSpatialObject}. // // \index{itk::ImageMaskSpatialObject!SetImage()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet spatialObjectMask->SetImage( maskReader->GetOutput() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Finally, the spatial object mask is passed to the image metric. // // \index{itk::ImageToImageMetric!SetFixedImage()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet metric->SetFixedImageMask( spatialObjectMask ); - // Software Guide : EndCodeSnippet try { @@ -329,7 +297,6 @@ int main( int argc, char *argv[] ) std::cout << " Iterations = " << numberOfIterations << std::endl; std::cout << " Metric value = " << bestValue << std::endl; - // Software Guide : BeginLatex // // Let's execute this example over some of the images provided in // \code{Examples/Data}, for example: @@ -344,9 +311,7 @@ int main( int argc, char *argv[] ) // $Y$. Both images have unit-spacing and are shown in Figure // \ref{fig:FixedMovingImageRegistration5}. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet transform->SetParameters( finalParameters ); TransformType::MatrixType matrix = transform->GetMatrix(); @@ -354,14 +319,11 @@ int main( int argc, char *argv[] ) std::cout << "Matrix = " << std::endl << matrix << std::endl; std::cout << "Offset = " << std::endl << offset << std::endl; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Now we resample the moving image using the transform resulting from the // registration process. // - // Software Guide : EndLatex using ResampleFilterType = itk::ResampleImageFilter< MovingImageType, diff --git a/Examples/RegistrationITKv3/ImageRegistration13.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration13.cxx similarity index 93% rename from Examples/RegistrationITKv3/ImageRegistration13.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration13.cxx index dfa4de9c8d9..537883acdb2 100644 --- a/Examples/RegistrationITKv3/ImageRegistration13.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration13.cxx @@ -16,12 +16,10 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // This example illustrates how to do registration with a 2D Rigid Transform // and with MutualInformation metric. // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" @@ -29,9 +27,7 @@ #include "itkCenteredRigid2DTransform.h" #include "itkCenteredTransformInitializer.h" -// Software Guide : BeginCodeSnippet #include "itkMattesMutualInformationImageToImageMetric.h" -// Software Guide : EndCodeSnippet #include "itkRegularStepGradientDescentOptimizer.h" #include "itkMersenneTwisterRandomVariateGenerator.h" @@ -57,7 +53,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -70,7 +66,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -82,8 +78,10 @@ class CommandIterationUpdate : public itk::Command }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 3 ) { std::cerr << "Missing Parameters " << std::endl; @@ -101,13 +99,9 @@ int main( int argc, char *argv[] ) using FixedImageType = itk::Image< PixelType, Dimension >; using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : BeginLatex // The CenteredRigid2DTransform applies a rigid transform in 2D space. - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformType = itk::CenteredRigid2DTransform< double >; using OptimizerType = itk::RegularStepGradientDescentOptimizer; - // Software Guide : EndCodeSnippet using InterpolatorType = itk::LinearInterpolateImageFunction< MovingImageType, @@ -117,16 +111,12 @@ int main( int argc, char *argv[] ) MovingImageType >; - // Software Guide : BeginCodeSnippet using MetricType = itk::MattesMutualInformationImageToImageMetric< FixedImageType, MovingImageType >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); OptimizerType::Pointer optimizer = OptimizerType::New(); - // Software Guide : EndCodeSnippet InterpolatorType::Pointer interpolator = InterpolatorType::New(); RegistrationType::Pointer registration = RegistrationType::New(); @@ -183,7 +173,6 @@ int main( int argc, char *argv[] ) registration->SetFixedImageRegion( fixedImageReader->GetOutput()->GetBufferedRegion() ); - // Software Guide : BeginLatex // The \doxygen{CenteredRigid2DTransform} is initialized by 5 parameters, // indicating the angle of rotation, the center coordinates and the // translation to be applied after rotation. The initialization is done @@ -198,8 +187,6 @@ int main( int argc, char *argv[] ) // mass is computed from the moments obtained from the gray level values. // Here we adopt the first approach. The \code{GeometryOn()} method // toggles between the approaches. - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformInitializerType = itk::CenteredTransformInitializer< TransformType, FixedImageType, MovingImageType >; @@ -211,21 +198,17 @@ int main( int argc, char *argv[] ) initializer->SetMovingImage( movingImageReader->GetOutput() ); initializer->GeometryOn(); initializer->InitializeTransform(); - // Software Guide : EndCodeSnippet transform->SetAngle( 0.0 ); registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : BeginLatex // The optimizer scales the metrics (the gradient in this case) by the // scales during each iteration. Hence a large value of the center scale // will prevent movement along the center during optimization. Here we // assume that the fixed and moving images are likely to be related by // a translation. - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using OptimizerScalesType = OptimizerType::ScalesType; OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() ); @@ -243,7 +226,6 @@ int main( int argc, char *argv[] ) optimizer->SetMaximumStepLength( 0.5 ); optimizer->SetMinimumStepLength( 0.0001 ); optimizer->SetNumberOfIterations( 400 ); - // Software Guide : EndCodeSnippet // Create the Command observer and register it with the optimizer. // @@ -332,7 +314,6 @@ int main( int argc, char *argv[] ) return EXIT_SUCCESS; } -// Software Guide : BeginLatex // // Let's execute this example over some of the images provided in // \code{Examples/Data}, for example: @@ -353,4 +334,3 @@ int main( int argc, char *argv[] ) // Translation Y = 20 // \end{verbatim} // These values match the true misalignment introduced in the moving image. -// Software Guide : EndLatex diff --git a/Examples/RegistrationITKv3/ImageRegistration14.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration14.cxx similarity index 92% rename from Examples/RegistrationITKv3/ImageRegistration14.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration14.cxx index 84ba742a2fa..039bad8f134 100644 --- a/Examples/RegistrationITKv3/ImageRegistration14.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration14.cxx @@ -16,15 +16,12 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // This example illustrates how to do registration with a 2D Rigid Transform // and with the Normalized Mutual Information metric. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkImageRegistrationMethod.h" #include "itkCenteredRigid2DTransform.h" @@ -60,14 +57,16 @@ class CommandIterationUpdate : public itk::Command using OptimizerType = itk::OnePlusOneEvolutionaryOptimizer; using OptimizerPointer = const OptimizerType *; - void Execute(itk::Object *caller, const itk::EventObject & event) override + void Execute(itk::Object *caller, + const itk::EventObject & event) override { Execute( (const itk::Object *)caller, event); } - void Execute(const itk::Object * object, const itk::EventObject & event) override + void Execute(const itk::Object * object, + const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -89,8 +88,10 @@ class CommandIterationUpdate : public itk::Command }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -120,7 +121,8 @@ int main( int argc, char *argv[] ) MovingImageType >; - using MetricType = itk::NormalizedMutualInformationHistogramImageToImageMetric< + using MetricType = + itk::NormalizedMutualInformationHistogramImageToImageMetric< FixedImageType, MovingImageType >; @@ -283,12 +285,12 @@ int main( int argc, char *argv[] ) std::cout << " Result = " << std::endl; std::cout << " Angle (radians) " << finalAngle << std::endl; std::cout << " Angle (degrees) " << finalAngleInDegrees << std::endl; - std::cout << " Center X = " << finalRotationCenterX << std::endl; - std::cout << " Center Y = " << finalRotationCenterY << std::endl; - std::cout << " Translation X = " << finalTranslationX << std::endl; - std::cout << " Translation Y = " << finalTranslationY << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; + std::cout << " Center X = " << finalRotationCenterX << std::endl; + std::cout << " Center Y = " << finalRotationCenterY << std::endl; + std::cout << " Translation X = " << finalTranslationX << std::endl; + std::cout << " Translation Y = " << finalTranslationY << std::endl; + std::cout << " Iterations = " << numberOfIterations << std::endl; + std::cout << " Metric value = " << bestValue << std::endl; using ResampleFilterType = itk::ResampleImageFilter< MovingImageType, FixedImageType >; @@ -312,6 +314,5 @@ int main( int argc, char *argv[] ) writer->SetFileName( argv[3] ); writer->SetInput( resample->GetOutput() ); writer->Update(); - // Software Guide : EndCodeSnippet return EXIT_SUCCESS; } diff --git a/Examples/RegistrationITKv3/ImageRegistration3.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration3.cxx similarity index 87% rename from Examples/RegistrationITKv3/ImageRegistration3.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration3.cxx index c30a61aa387..9a909463aac 100644 --- a/Examples/RegistrationITKv3/ImageRegistration3.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration3.cxx @@ -16,7 +16,6 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // Given the numerous parameters involved in tuning a registration method for // a particular application, it is not uncommon for a registration process to @@ -54,7 +53,6 @@ // \index{itk::ImageRegistrationMethod!Monitoring} // // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" @@ -69,7 +67,6 @@ #include "itkCastImageFilter.h" -// Software Guide : BeginLatex // // The following code illustrates a simple way of creating a // Observer/Command to monitor a registration process. This new @@ -77,73 +74,53 @@ // implementation of the \code{Execute()} method. First, the header file of // the Command class must be included. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkCommand.h" -// Software Guide : EndCodeSnippet -// Software Guide : BeginLatex // // Our custom command class is called \code{CommandIterationUpdate}. It // derives from the Command class and declares for convenience the // types \code{Self} and \code{Superclass}. This facilitate the use of // standard macros later in the class implementation. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet class CommandIterationUpdate : public itk::Command { public: using Self = CommandIterationUpdate; using Superclass = itk::Command; -// Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The following type alias declares the type of the SmartPointer capable of // holding a reference to this object. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using Pointer = itk::SmartPointer; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The \code{itkNewMacro} takes care of defining all the necessary code for // the \code{New()} method. Those with curious minds are invited to see the // details of the macro in the file \code{itkMacro.h} in the // \code{Insight/Code/Common} directory. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet itkNewMacro( Self ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // In order to ensure that the \code{New()} method is used to instantiate // the class (and not the C++ \code{new} operator), the constructor is // declared \code{protected}. // - // Software Guide : EndLatex -// Software Guide : BeginCodeSnippet protected: - CommandIterationUpdate() {}; -// Software Guide : EndCodeSnippet + CommandIterationUpdate() = default; public: - // Software Guide : BeginLatex // // Since this Command object will be observing the optimizer, // the following type alias are useful for converting pointers when the @@ -153,15 +130,11 @@ class CommandIterationUpdate : public itk::Command // way. A \code{const} interface ensures that all operations invoked on the // optimizer are read-only. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using OptimizerType = itk::RegularStepGradientDescentOptimizer; using OptimizerPointer = const OptimizerType *; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // ITK enforces const-correctness. There is hence a distinction between the // \code{Execute()} method that can be invoked from a \code{const} object @@ -174,31 +147,23 @@ class CommandIterationUpdate : public itk::Command // similar case could happen when a user is controlling the registration // process from a GUI. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet void Execute(itk::Object *caller, const itk::EventObject & event) override { Execute( (const itk::Object *)caller, event); } - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Finally we get to the heart of the observer, the \code{Execute()} method. // Two arguments are passed to this method. The first argument is the pointer // to the object that invoked the event. The second argument is the event that // was invoked. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet void Execute(const itk::Object * object, const itk::EventObject & event) override { - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Note that the first argument is a pointer to an Object even // though the actual object invoking the event is probably a subclass of @@ -206,14 +171,10 @@ class CommandIterationUpdate : public itk::Command // optimizer. Thus we can perform a \code{dynamic\_cast} to the real type // of the object. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); - // Software Guide : EndCodeSnippet + auto optimizer = static_cast< OptimizerPointer >( object ); - // Software Guide : BeginLatex // // The next step is to verify that the event invoked is actually the one in // which we are interested. This is checked using the RTTI\footnote{RTTI @@ -227,17 +188,13 @@ class CommandIterationUpdate : public itk::Command // // \index{itk::EventObject!CheckEvent} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; } - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // If the event matches the type we are looking for, we are ready to // query data from the optimizer. Here, for example, we get the current @@ -246,27 +203,24 @@ class CommandIterationUpdate : public itk::Command // to the standard output. You could imagine more elaborate actions like // updating a GUI or refreshing a visualization pipeline. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet std::cout << optimizer->GetCurrentIteration() << " = "; std::cout << optimizer->GetValue() << " : "; std::cout << optimizer->GetCurrentPosition() << std::endl; - // Software Guide : EndCodeSnippet } - // Software Guide : BeginLatex // // This concludes our implementation of a minimal Command class // capable of observing our registration method. We can now move on to // configuring the registration process. // - // Software Guide : EndLatex }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -343,20 +297,15 @@ int main( int argc, char *argv[] ) optimizer->MaximizeOff(); - // Software Guide : BeginLatex // // Once all the registration components are in place we can create one // instance of our observer. This is done with the standard \code{New()} // method and assigned to a SmartPointer. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet CommandIterationUpdate::Pointer observer = CommandIterationUpdate::New(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -367,10 +316,8 @@ int main( int argc, char *argv[] ) // \end{figure} // // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // The newly created command is registered as observer on the // optimizer, using the \code{AddObserver()} method. Note @@ -378,27 +325,21 @@ int main( int argc, char *argv[] ) // method. In order for the RTTI mechanism to work correctly, a newly // created event of the desired type must be passed as the first // argument. The second argument is simply the smart pointer to the - // optimizer. Figure \ref{fig:ImageRegistration3Observer} illustrates the + // observer. Figure \ref{fig:ImageRegistration3Observer} illustrates the // interaction between the Command/Observer class and the registration // method. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet optimizer->AddObserver( itk::IterationEvent(), observer ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // At this point, we are ready to execute the registration. The // typical call to \code{Update()} will do it. Note again the // use of the \code{try/catch} block around the \code{Update()} // method in case an exception is thrown. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet try { registration->Update(); @@ -412,10 +353,8 @@ int main( int argc, char *argv[] ) std::cout << err << std::endl; return EXIT_FAILURE; } - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The registration process is applied to the following images in \code{Examples/Data}: // @@ -455,10 +394,10 @@ int main( int argc, char *argv[] ) // process and fine-tune parameters without having to wait until the // optimizer stops by itself. // - // Software Guide : EndLatex - ParametersType finalParameters = registration->GetLastTransformParameters(); + ParametersType finalParameters = + registration->GetLastTransformParameters(); const double TranslationAlongX = finalParameters[0]; const double TranslationAlongY = finalParameters[1]; diff --git a/Examples/RegistrationITKv3/ImageRegistration4.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration4.cxx similarity index 90% rename from Examples/RegistrationITKv3/ImageRegistration4.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration4.cxx index 1deee601dc5..f8dd1a105c5 100644 --- a/Examples/RegistrationITKv3/ImageRegistration4.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration4.cxx @@ -16,7 +16,6 @@ * *=========================================================================*/ -// Software Guide : BeginCommandLineArgs // INPUTS: {BrainT1SliceBorder20.png} // INPUTS: {BrainProtonDensitySliceShifted13x17y.png} // OUTPUTS: {ImageRegistration4Output.png} @@ -24,13 +23,13 @@ // OUTPUTS: {ImageRegistration4CheckerboardBefore.png} // OUTPUTS: {ImageRegistration4CheckerboardAfter.png} // ARGUMENTS: 24 -// Software Guide : EndCommandLineArgs -// Software Guide : BeginLatex // -// In this example, we will solve a simple multi-modality problem using another +// In this example, we will solve a simple multi-modality problem using an // implementation of mutual information. This implementation was published by -// Mattes~\emph{et. al}~\cite{Mattes2003}. One of the main differences between +// Mattes~\emph{et. al}~\cite{Mattes2003}. +// +// One of the main differences between // \doxygen{MattesMutualInformationImageToImageMetric} and // \doxygen{MutualInformationImageToImageMetric} is that only one spatial // sample set is used for the whole registration process instead of using new @@ -47,15 +46,12 @@ // // \index{itk::ImageRegistrationMethod!Multi-Modality} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkImageRegistrationMethod.h" #include "itkTranslationTransform.h" #include "itkMattesMutualInformationImageToImageMetric.h" #include "itkRegularStepGradientDescentOptimizer.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" @@ -80,7 +76,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -93,7 +89,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -104,8 +100,10 @@ class CommandIterationUpdate : public itk::Command } }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -133,7 +131,6 @@ int main( int argc, char *argv[] ) FixedImageType, MovingImageType >; - // Software Guide : BeginLatex // // In this example the image types and all registration components, // except the metric, are declared as in Section @@ -141,13 +138,10 @@ int main( int argc, char *argv[] ) // The Mattes mutual information metric type is // instantiated using the image types. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using MetricType = itk::MattesMutualInformationImageToImageMetric< - FixedImageType, - MovingImageType >; - // Software Guide : EndCodeSnippet + FixedImageType, + MovingImageType >; TransformType::Pointer transform = TransformType::New(); OptimizerType::Pointer optimizer = OptimizerType::New(); @@ -159,20 +153,15 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // // The metric is created using the \code{New()} method and then // connected to the registration object. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet MetricType::Pointer metric = MetricType::New(); registration->SetMetric( metric ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The metric requires two parameters to be selected: the number of bins // used to compute the entropy and the number of spatial samples used to @@ -187,12 +176,9 @@ int main( int argc, char *argv[] ) // \index{itk::Mattes\-Mutual\-Information\-Image\-To\-Image\-Metric!SetNumberOfHistogramBins()} // \index{itk::Mattes\-Mutual\-Information\-Image\-To\-Image\-Metric!SetNumberOfSpatialSamples()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet unsigned int numberOfBins = 24; unsigned int numberOfSamples = 10000; - // Software Guide : EndCodeSnippet if( argc > 7 ) { @@ -205,16 +191,13 @@ int main( int argc, char *argv[] ) } - // Software Guide : BeginCodeSnippet metric->SetNumberOfHistogramBins( numberOfBins ); metric->SetNumberOfSpatialSamples( numberOfSamples ); - // Software Guide : EndCodeSnippet // For consistent results when regression testing. metric->ReinitializeSeed( 121212 ); - // Software Guide : BeginLatex // // One mechanism for bringing the Metric to its limit is to disable the // sampling and use all the pixels present in the FixedImageRegion. This can @@ -224,7 +207,6 @@ int main( int argc, char *argv[] ) // // \index{itk::Mattes\-Mutual\-Information\-Image\-To\-Image\-Metric!UseAllPixelsOn()} // - // Software Guide : EndLatex if( argc > 9 ) @@ -263,30 +245,25 @@ int main( int argc, char *argv[] ) registration->SetInitialTransformParameters( initialParameters ); - // Software Guide : BeginLatex // // Another significant difference in the metric is that it computes the // negative mutual information and hence we need to minimize the cost // function in this case. In this example we will use the same optimization // parameters as in Section \ref{sec:IntroductionImageRegistration}. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet optimizer->MinimizeOn(); optimizer->SetMaximumStepLength( 2.00 ); optimizer->SetMinimumStepLength( 0.001 ); optimizer->SetNumberOfIterations( 200 ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Whenever the regular step gradient descent optimizer encounters that the // direction of movement has changed in the parametric space, it reduces the // size of the step length. The rate at which the step length is reduced is // controlled by a relaxation factor. The default value of the factor is // $0.5$. This value, however may prove to be inadequate for noisy metrics - // since they tend to induce very erratic movements on the optimizers and + // since they tend to induce erratic movements on the optimizers and // therefore result in many directional changes. In those // conditions, the optimizer will rapidly shrink the step length while it is // still too far from the location of the extrema in the cost function. In @@ -295,11 +272,8 @@ int main( int argc, char *argv[] ) // // \index{itk::Regular\-Step\-Gradient\-Descent\-Optimizer!SetRelaxationFactor()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet optimizer->SetRelaxationFactor( 0.8 ); - // Software Guide : EndCodeSnippet // Create the Command observer and register it with the optimizer. // @@ -321,7 +295,8 @@ int main( int argc, char *argv[] ) return EXIT_FAILURE; } - ParametersType finalParameters = registration->GetLastTransformParameters(); + ParametersType finalParameters = + registration->GetLastTransformParameters(); double TranslationAlongX = finalParameters[0]; double TranslationAlongY = finalParameters[1]; @@ -344,7 +319,6 @@ int main( int argc, char *argv[] ) std::cout << " Stop Condition = " << optimizer->GetStopCondition() << std::endl; - // Software Guide : BeginLatex // // This example is executed using the same multi-modality images as the one // in section~\ref{sec:MultiModalityRegistrationViolaWells} The registration @@ -358,8 +332,6 @@ int main( int argc, char *argv[] ) // These values are a very close match to the true misalignment introduced in // the moving image. // - // Software Guide : EndLatex - using ResampleFilterType = itk::ResampleImageFilter< MovingImageType, @@ -411,7 +383,6 @@ int main( int argc, char *argv[] ) writer->Update(); - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -429,7 +400,6 @@ int main( int argc, char *argv[] ) // the figure present a checkerboard composite of the fixed and moving // images before and after registration respectively. // - // Software Guide : EndLatex // @@ -468,7 +438,6 @@ int main( int argc, char *argv[] ) } - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -485,7 +454,9 @@ int main( int argc, char *argv[] ) // parameter space. The upper-right figure presents a closer look at the // convergence basin for the last iterations of the optimizer. The bottom of // the same figure shows the sequence of metric values computed as the - // optimizer searched the parameter space. Comparing these trace plots with + // optimizer searched the parameter space. + // + // Comparing these trace plots with // Figures \ref{fig:ImageRegistration2TraceTranslations} and // \ref{fig:ImageRegistration2TraceMetric}, we can see that the measures // produced by MattesMutualInformationImageToImageMetric are smoother than @@ -495,15 +466,13 @@ int main( int argc, char *argv[] ) // onto the optimal value. // // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // You must note however that there are a number of non-trivial issues // involved in the fine tuning of parameters for the optimization. For // example, the number of bins used in the estimation of Mutual Information // has a dramatic effect on the performance of the optimizer. In order to - // illustrate this effect, this same example has been executed using a range + // illustrate this effect, the same example has been executed using a range // of different values for the number of bins, from $10$ to $30$. If you // repeat this experiment, you will notice that depending on the number of // bins used, the optimizer's path may get trapped early on in local minima. @@ -523,20 +492,18 @@ int main( int argc, char *argv[] ) // \label{fig:ImageRegistration4TraceTranslationsNumberOfBins} // \end{figure} // - + // // Effects such as the one illustrated here highlight how useless is to // compare different algorithms based on a non-exhaustive search of their // parameter setting. It is quite difficult to be able to claim that a // particular selection of parameters represent the best combination for // running a particular algorithm. Therefore, when comparing the performance // of two or more different algorithms, we are faced with the challenge of - // proving that none of the algorithms involved in the comparison is being + // proving that none of the algorithms involved in the comparison are being // run with a sub-optimal set of parameters. // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // The plots in Figures~\ref{fig:ImageRegistration4TraceTranslations} // and~\ref{fig:ImageRegistration4TraceTranslationsNumberOfBins} were @@ -548,7 +515,6 @@ int main( int argc, char *argv[] ) // The use of these scripts was similar to what was described at the end of // section~\ref{sec:MultiModalityRegistrationViolaWells}. // - // Software Guide : EndLatex return EXIT_SUCCESS; diff --git a/Examples/RegistrationITKv3/ImageRegistration5.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration5.cxx similarity index 87% rename from Examples/RegistrationITKv3/ImageRegistration5.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration5.cxx index 59c62db9ea2..af9b6429461 100644 --- a/Examples/RegistrationITKv3/ImageRegistration5.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration5.cxx @@ -16,26 +16,21 @@ * *=========================================================================*/ -// Software Guide : BeginCommandLineArgs // INPUTS: {BrainProtonDensitySliceBorder20.png} // INPUTS: {BrainProtonDensitySliceRotated10.png} // OUTPUTS: {ImageRegistration5Output.png} // OUTPUTS: {ImageRegistration5DifferenceAfter.png} // OUTPUTS: {ImageRegistration5DifferenceBefore.png} // ARGUMENTS: 0.1 -// Software Guide : EndCommandLineArgs -// Software Guide : BeginCommandLineArgs // INPUTS: {BrainProtonDensitySliceBorder20.png} // INPUTS: {BrainProtonDensitySliceR10X13Y17.png} // OUTPUTS: {ImageRegistration5Output2.png} // OUTPUTS: {ImageRegistration5DifferenceAfter2.png} // OUTPUTS: {ImageRegistration5DifferenceBefore2.png} // ARGUMENTS: 1.0 -// Software Guide : EndCommandLineArgs -// Software Guide : BeginLatex // // This example illustrates the use of the \doxygen{CenteredRigid2DTransform} // for performing rigid registration in $2D$. The example code is for the @@ -46,25 +41,20 @@ // // \index{itk::CenteredRigid2DTransform} // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMeanSquaresImageToImageMetric.h" #include "itkRegularStepGradientDescentOptimizer.h" -// Software Guide : BeginLatex // // In addition to the headers included in previous examples, the // following header must also be included. // // \index{itk::CenteredRigid2DTransform!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkCenteredRigid2DTransform.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" @@ -88,7 +78,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -101,7 +91,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -112,8 +102,10 @@ class CommandIterationUpdate : public itk::Command } }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -132,7 +124,6 @@ int main( int argc, char *argv[] ) using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : BeginLatex // // The transform type is instantiated using the code below. The only // template parameter for this class is the representation type of the @@ -140,11 +131,8 @@ int main( int argc, char *argv[] ) // // \index{itk::CenteredRigid2DTransform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformType = itk::CenteredRigid2DTransform< double >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -168,7 +156,6 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // // The transform object is constructed below and passed to the registration // method. @@ -177,12 +164,9 @@ int main( int argc, char *argv[] ) // \index{itk::CenteredRigid2DTransform!Pointer} // \index{itk::RegistrationMethod!SetTransform()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; @@ -203,7 +187,6 @@ int main( int argc, char *argv[] ) fixedImageReader->GetOutput()->GetBufferedRegion() ); - // Software Guide : BeginLatex // // In this example, the input images are taken from readers. The code // below updates the readers in order to ensure that the image parameters @@ -213,26 +196,20 @@ int main( int argc, char *argv[] ) // and the moving image center as the initial translation to be applied // after the rotation. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet fixedImageReader->Update(); movingImageReader->Update(); - // Software Guide : EndCodeSnippet using SpacingType = FixedImageType::SpacingType; using OriginType = FixedImageType::PointType; using RegionType = FixedImageType::RegionType; using SizeType = FixedImageType::SizeType; - // Software Guide : BeginLatex // // The center of rotation is computed using the origin, size and spacing of // the fixed image. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet FixedImageType::Pointer fixedImage = fixedImageReader->GetOutput(); const SpacingType fixedSpacing = fixedImage->GetSpacing(); @@ -244,16 +221,12 @@ int main( int argc, char *argv[] ) centerFixed[0] = fixedOrigin[0] + fixedSpacing[0] * fixedSize[0] / 2.0; centerFixed[1] = fixedOrigin[1] + fixedSpacing[1] * fixedSize[1] / 2.0; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The center of the moving image is computed in a similar way. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet MovingImageType::Pointer movingImage = movingImageReader->GetOutput(); const SpacingType movingSpacing = movingImage->GetSpacing(); @@ -265,54 +238,38 @@ int main( int argc, char *argv[] ) centerMoving[0] = movingOrigin[0] + movingSpacing[0] * movingSize[0] / 2.0; centerMoving[1] = movingOrigin[1] + movingSpacing[1] * movingSize[1] / 2.0; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // - // The most straightforward method of initializing the transform parameters - // is to configure the transform and then get its parameters with the - // method \code{GetParameters()}. Here we initialize the transform by + // Then, we initialize the transform by // passing the center of the fixed image as the rotation center with the - // \code{SetCenter()} method. Then the translation is set as the vector + // \code{SetCenter()} method. Also, the translation is set as the vector // relating the center of the moving image to the center of the fixed // image. This last vector is passed with the method // \code{SetTranslation()}. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet transform->SetCenter( centerFixed ); transform->SetTranslation( centerMoving - centerFixed ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Let's finally initialize the rotation with a zero angle. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet transform->SetAngle( 0.0 ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Now we pass the current transform's parameters as the initial // parameters to be used when the registration process starts. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // - // Keeping in mind that the scale of units in rotation and translation is + // Keep in mind that the scale of units in rotation and translation is // quite different, we take advantage of the scaling functionality provided // by the optimizers. We know that the first element of the parameters array // corresponds to the angle that is measured in radians, while the other @@ -320,9 +277,7 @@ int main( int argc, char *argv[] ) // For this reason we use small factors in the scales associated with // translations and the coordinates of the rotation center . // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using OptimizerScalesType = OptimizerType::ScalesType; OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() ); const double translationScale = 1.0 / 1000.0; @@ -334,10 +289,8 @@ int main( int argc, char *argv[] ) optimizerScales[4] = translationScale; optimizer->SetScales( optimizerScales ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Next we set the normal parameters of the optimization method. In this // case we are using an \doxygen{RegularStepGradientDescentOptimizer}. @@ -350,23 +303,18 @@ int main( int argc, char *argv[] ) // \index{Regular\-Step\-Gradient\-Descent\-Optimizer!SetMinimumStepLength()} // \index{Regular\-Step\-Gradient\-Descent\-Optimizer!SetNumberOfIterations()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet double initialStepLength = 0.1; - // Software Guide : EndCodeSnippet if( argc > 6 ) { initialStepLength = std::stod( argv[6] ); } - // Software Guide : BeginCodeSnippet optimizer->SetRelaxationFactor( 0.6 ); optimizer->SetMaximumStepLength( initialStepLength ); optimizer->SetMinimumStepLength( 0.001 ); optimizer->SetNumberOfIterations( 200 ); - // Software Guide : EndCodeSnippet // Create the Command observer and register it with the optimizer. @@ -407,17 +355,16 @@ int main( int argc, char *argv[] ) const double finalAngleInDegrees = finalAngle * 180.0 / itk::Math::pi; std::cout << "Result = " << std::endl; - std::cout << " Angle (radians) = " << finalAngle << std::endl; - std::cout << " Angle (degrees) = " << finalAngleInDegrees << std::endl; - std::cout << " Center X = " << finalRotationCenterX << std::endl; - std::cout << " Center Y = " << finalRotationCenterY << std::endl; - std::cout << " Translation X = " << finalTranslationX << std::endl; - std::cout << " Translation Y = " << finalTranslationY << std::endl; - std::cout << " Iterations = " << numberOfIterations << std::endl; - std::cout << " Metric value = " << bestValue << std::endl; + std::cout << " Angle (radians) = " << finalAngle << std::endl; + std::cout << " Angle (degrees) = " << finalAngleInDegrees << std::endl; + std::cout << " Translation X = " << finalTranslationX << std::endl; + std::cout << " Translation Y = " << finalTranslationY << std::endl; + std::cout << " Center X = " << finalRotationCenterX << std::endl; + std::cout << " Center Y = " << finalRotationCenterY << std::endl; + std::cout << " Iterations = " << numberOfIterations << std::endl; + std::cout << " Metric value = " << bestValue << std::endl; - // Software Guide : BeginLatex // // Let's execute this example over two of the images provided in // \code{Examples/Data}: @@ -492,12 +439,11 @@ int main( int argc, char *argv[] ) // \end{figure} // // Figure \ref{fig:ImageRegistration5Plots} shows plots of the main output - // parameters produced from the registration process. This includes, the + // parameters produced from the registration process. This includes the // metric values at every iteration, the angle values at every iteration, // and the translation components of the transform as the registration // progress. // - // Software Guide : EndLatex using ResampleFilterType = itk::ResampleImageFilter< @@ -603,7 +549,6 @@ int main( int argc, char *argv[] ) return EXIT_FAILURE; } - // Software Guide : BeginLatex // // Let's now consider the case in which rotations and translations are // present in the initial registration, as in the following pair @@ -683,14 +628,13 @@ int main( int argc, char *argv[] ) // // Figure \ref{fig:ImageRegistration5Plots2} shows plots of the main output // registration parameters when the rotation and translations are combined. - // These results include, the metric values at every iteration, the angle + // These results include the metric values at every iteration, the angle // values at every iteration, and the translation components of the // registration as the registration converges. It can be seen from the // smoothness of these plots that a larger step length could have been // supported easily by the optimizer. You may want to modify this value in // order to get a better idea of how to tune the parameters. // - // Software Guide : EndLatex return EXIT_SUCCESS; diff --git a/Examples/RegistrationITKv3/ImageRegistration6.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration6.cxx similarity index 90% rename from Examples/RegistrationITKv3/ImageRegistration6.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration6.cxx index f948ba08bd8..54fcfcfe98c 100644 --- a/Examples/RegistrationITKv3/ImageRegistration6.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration6.cxx @@ -16,16 +16,13 @@ * *=========================================================================*/ -// Software Guide : BeginCommandLineArgs // INPUTS: {BrainProtonDensitySliceBorder20.png} // INPUTS: {BrainProtonDensitySliceR10X13Y17.png} // OUTPUTS: {ImageRegistration6Output.png} // OUTPUTS: {ImageRegistration6DifferenceBefore.png} // OUTPUTS: {ImageRegistration6DifferenceAfter.png} -// Software Guide : EndCommandLineArgs -// Software Guide : BeginLatex // // This example illustrates the use of the \doxygen{CenteredRigid2DTransform} // for performing registration. The example code is for the most part @@ -65,25 +62,20 @@ // \index{itk::ImageMomentsCalculator} // // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMeanSquaresImageToImageMetric.h" #include "itkRegularStepGradientDescentOptimizer.h" -// Software Guide : BeginLatex // // The following are the most relevant headers in this example. // // \index{itk::CenteredRigid2DTransform!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkCenteredRigid2DTransform.h" #include "itkCenteredTransformInitializer.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" @@ -109,7 +101,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -122,7 +114,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -133,8 +125,10 @@ class CommandIterationUpdate : public itk::Command } }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -152,7 +146,6 @@ int main( int argc, char *argv[] ) using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : BeginLatex // // The transform type is instantiated using the code below. The only // template parameter of this class is the representation type of the @@ -160,11 +153,8 @@ int main( int argc, char *argv[] ) // // \index{itk::CenteredRigid2DTransform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformType = itk::CenteredRigid2DTransform< double >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -189,21 +179,19 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // - // The transform object is constructed below and passed to the - // registration method. + // Like the previous section, a direct initialization method is used here. + // The transform object is constructed below. This transform will + // be initialized, and its initial parameters will be considered as + // the parameters to be used when the registration process begins. // // \index{itk::CenteredRigid2DTransform!New()} // \index{itk::CenteredRigid2DTransform!Pointer} // \index{itk::RegistrationMethod!SetTransform()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; @@ -222,13 +210,12 @@ int main( int argc, char *argv[] ) fixedImageReader->GetOutput()->GetBufferedRegion() ); - // Software Guide : BeginLatex // // The input images are taken from readers. It is not necessary to // explicitly call \code{Update()} on the readers since the // CenteredTransformInitializer class will do it as part of its // initialization. The following code instantiates the initializer. This - // class is templated over the fixed and moving image type as well as the + // class is templated over the fixed and moving images type as well as the // transform type. An initializer is then constructed by calling the // \code{New()} method and assigning the result to a // \doxygen{SmartPointer}. @@ -237,31 +224,25 @@ int main( int argc, char *argv[] ) // \index{itk::CenteredRigid2DTransform!New()} // \index{itk::CenteredRigid2DTransform!SmartPointer} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformInitializerType = itk::CenteredTransformInitializer< - TransformType, FixedImageType, - MovingImageType >; - TransformInitializerType::Pointer initializer - = TransformInitializerType::New(); - // Software Guide : EndCodeSnippet + TransformType, + FixedImageType, + MovingImageType >; + + TransformInitializerType::Pointer initializer = + TransformInitializerType::New(); - // Software Guide : BeginLatex // // The initializer is now connected to the transform and to the fixed and // moving images. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet initializer->SetTransform( transform ); initializer->SetFixedImage( fixedImageReader->GetOutput() ); initializer->SetMovingImage( movingImageReader->GetOutput() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The use of the geometrical centers is selected by calling // \code{GeometryOn()} while the use of center of mass is selected by @@ -270,48 +251,33 @@ int main( int argc, char *argv[] ) // \index{CenteredTransformInitializer!MomentsOn()} // \index{CenteredTransformInitializer!GeometryOn()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet initializer->MomentsOn(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Finally, the computation of the center and translation is triggered by // the \code{InitializeTransform()} method. The resulting values will be // passed directly to the transform. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet initializer->InitializeTransform(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The remaining parameters of the transform are initialized as before. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet transform->SetAngle( 0.0 ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // - // Now the parameters of the current transform are passed as the initial - // parameters to be used when the registration process starts. + // Now the initialized transform object will be set to the registration method, + // and the starting point of the registration is defined by its initial parameters. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet using OptimizerScalesType = OptimizerType::ScalesType; @@ -378,7 +344,6 @@ int main( int argc, char *argv[] ) std::cout << " Metric value = " << bestValue << std::endl; - // Software Guide : BeginLatex // // Let's execute this example over some of the images provided in // \code{Examples/Data}, for example: @@ -417,9 +382,7 @@ int main( int argc, char *argv[] ) // this case to take a look at the actual rotation matrix and offset // resulting form the five parameters. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet transform->SetParameters( finalParameters ); TransformType::MatrixType matrix = transform->GetMatrix(); @@ -427,9 +390,7 @@ int main( int argc, char *argv[] ) std::cout << "Matrix = " << std::endl << matrix << std::endl; std::cout << "Offset = " << std::endl << offset << std::endl; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Which produces the following output. // @@ -481,10 +442,8 @@ int main( int argc, char *argv[] ) // \label{fig:TranslationAndRotationCenter} // \end{figure} // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // You may be wondering why the actual movement is represented by three // parameters when we take the trouble of using five. In particular, why @@ -494,10 +453,8 @@ int main( int argc, char *argv[] ) // offset. Using the minimum three parameters it is not obvious how to // determine what the initial rotation and translations should be. // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -546,7 +503,6 @@ int main( int argc, char *argv[] ) // the observer to print the total offset instead of printing the array of // parameters. Let's call that an exercise for the reader! // - // Software Guide : EndLatex using ResampleFilterType = itk::ResampleImageFilter< diff --git a/Examples/RegistrationITKv3/ImageRegistration7.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration7.cxx similarity index 88% rename from Examples/RegistrationITKv3/ImageRegistration7.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration7.cxx index d39d0f89caa..7709e1ce2a0 100644 --- a/Examples/RegistrationITKv3/ImageRegistration7.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration7.cxx @@ -16,19 +16,16 @@ * *=========================================================================*/ -// Software Guide : BeginCommandLineArgs // INPUTS: {BrainProtonDensitySliceBorder20.png} // INPUTS: {BrainProtonDensitySliceR10X13Y17S12.png} // OUTPUTS: {ImageRegistration7Output.png} // OUTPUTS: {ImageRegistration7DifferenceBefore.png} // OUTPUTS: {ImageRegistration7DifferenceAfter.png} // ARGUMENTS: 1.0 1.0 0.0 -// Software Guide : EndCommandLineArgs -// Software Guide : BeginLatex // // This example illustrates the use of the \doxygen{CenteredSimilarity2DTransform} -// class for performing registration in $2D$. The of example code is for +// class for performing registration in $2D$. The example code is for // the most part identical to the code presented in Section // \ref{sec:InitializingRegistrationWithMoments}. The main difference is the // use of \doxygen{CenteredSimilarity2DTransform} here rather than the @@ -50,7 +47,6 @@ // // \index{itk::CenteredSimilarity2DTransform} // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMeanSquaresImageToImageMetric.h" @@ -60,18 +56,14 @@ #include "itkCenteredTransformInitializer.h" -// Software Guide : BeginLatex // // In addition to the headers included in previous examples, here the // following header must be included. // // \index{itk::CenteredSimilarity2DTransform!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkCenteredSimilarity2DTransform.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" @@ -97,7 +89,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -110,7 +102,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -121,8 +113,10 @@ class CommandIterationUpdate : public itk::Command } }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -143,7 +137,6 @@ int main( int argc, char *argv[] ) using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : BeginLatex // // The Transform class is instantiated using the code below. The only // template parameter of this class is the representation type of the @@ -151,11 +144,8 @@ int main( int argc, char *argv[] ) // // \index{itk::CenteredSimilarity2DTransform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformType = itk::CenteredSimilarity2DTransform< double >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -176,7 +166,6 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // // The transform object is constructed below and passed to the registration // method. @@ -185,12 +174,9 @@ int main( int argc, char *argv[] ) // \index{itk::CenteredSimilarity2DTransform!Pointer} // \index{itk::RegistrationMethod!SetTransform()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; @@ -211,42 +197,37 @@ int main( int argc, char *argv[] ) fixedImageReader->GetOutput()->GetBufferedRegion() ); - // Software Guide : BeginLatex // // In this example, we again use the helper class // \doxygen{CenteredTransformInitializer} to compute a reasonable // value for the initial center of rotation and the translation. // - // Software Guide : EndLatex -// Software Guide : BeginCodeSnippet using TransformInitializerType = itk::CenteredTransformInitializer< - TransformType, FixedImageType, - MovingImageType >; + TransformType, + FixedImageType, + MovingImageType >; TransformInitializerType::Pointer initializer - = TransformInitializerType::New(); + = TransformInitializerType::New(); - initializer->SetTransform( transform ); + initializer->SetTransform( transform ); - initializer->SetFixedImage( fixedImageReader->GetOutput() ); + initializer->SetFixedImage( fixedImageReader->GetOutput() ); initializer->SetMovingImage( movingImageReader->GetOutput() ); initializer->MomentsOn(); initializer->InitializeTransform(); -// Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The remaining parameters of the transform are initialized below. // // \index{itk::CenteredSimilarity2DTransform!SetScale()} // \index{itk::CenteredSimilarity2DTransform!SetAngle()} // - // Software Guide : EndLatex double initialScale = 1.0; @@ -262,24 +243,21 @@ int main( int argc, char *argv[] ) initialAngle = std::stod( argv[8] ); } - // Software Guide : BeginCodeSnippet transform->SetScale( initialScale ); transform->SetAngle( initialAngle ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // - // We now pass the parameter of the current transform as the initial - // parameters to be used when the registration process starts. + // Now the initialized transform object will be set to the registration method, + // and its initial parameters are used to initialize the registration process. + // + // Also, by calling the \code{InPlaceOn()} method, this initialized + // transform will be the output transform + // object or ``grafted'' to the output of the registration process. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Keeping in mind that the scale of units in scaling, rotation and // translation are quite different, we take advantage of the scaling @@ -290,9 +268,7 @@ int main( int argc, char *argv[] ) // factors in the scales associated with translations and the rotation // center. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using OptimizerScalesType = OptimizerType::ScalesType; OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() ); const double translationScale = 1.0 / 100.0; @@ -305,19 +281,16 @@ int main( int argc, char *argv[] ) optimizerScales[5] = translationScale; optimizer->SetScales( optimizerScales ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // - // We set also the normal parameters of the optimization method. In this - // case we are using A - // \doxygen{RegularStepGradientDescentOptimizer}. Below, we define the - // optimization parameters like initial step length, minimal step length - // and number of iterations. These last two act as stopping criteria for - // the optimization. + // We also set the ordinary parameters of the optimization method. In this + // case we are using a + // \doxygen{RegularStepGradientDescentOptimizer}. Below we define the + // optimization parameters, i.e. initial learning rate (step length), minimal + // step length and number of iterations. The last two act as stopping criteria + // for the optimization. // - // Software Guide : EndLatex double steplength = 1.0; @@ -326,11 +299,9 @@ int main( int argc, char *argv[] ) steplength = std::stod( argv[6] ); } - // Software Guide : BeginCodeSnippet optimizer->SetMaximumStepLength( steplength ); optimizer->SetMinimumStepLength( 0.0001 ); optimizer->SetNumberOfIterations( 500 ); - // Software Guide : EndCodeSnippet // Create the Command observer and register it with the optimizer. @@ -386,7 +357,6 @@ int main( int argc, char *argv[] ) std::cout << " Metric value = " << bestValue << std::endl; - // Software Guide : BeginLatex // // Let's execute this example over some of the images provided in // \code{Examples/Data}, for example: @@ -467,7 +437,6 @@ int main( int argc, char *argv[] ) // left while the translation components of the registration are presented // in the plot at right. // - // Software Guide : EndLatex using ResampleFilterType = itk::ResampleImageFilter< MovingImageType, diff --git a/Examples/RegistrationITKv3/ImageRegistration8.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration8.cxx similarity index 89% rename from Examples/RegistrationITKv3/ImageRegistration8.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration8.cxx index 3b7c6b98b25..9bc2d59ad47 100644 --- a/Examples/RegistrationITKv3/ImageRegistration8.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration8.cxx @@ -16,7 +16,6 @@ * *=========================================================================*/ -// Software Guide : BeginCommandLineArgs // INPUTS: brainweb1e1a10f20.mha // INPUTS: brainweb1e1a10f20Rot10Tx15.mha // ARGUMENTS: ImageRegistration8Output.mhd @@ -26,8 +25,7 @@ // OUTPUTS: {ImageRegistration8DifferenceBefore.png} // OUTPUTS: {ImageRegistration8DifferenceAfter.png} // OUTPUTS: {ImageRegistration8RegisteredSlice.png} -// Software Guide : EndCommandLineArgs -// Software Guide : BeginLatex + // // This example illustrates the use of the \doxygen{VersorRigid3DTransform} // class for performing registration of two $3D$ images. The example code is @@ -43,41 +41,39 @@ // \index{itk::Centered\-Transform\-Initializer!In 3D} // // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMeanSquaresImageToImageMetric.h" -// Software Guide : BeginLatex // // The following are the most relevant headers of this example. // // \index{itk::Versor\-Rigid3D\-Transform!header} // \index{itk::Centered\-Transform\-Initializer!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet + #include "itkVersorRigid3DTransform.h" #include "itkCenteredTransformInitializer.h" -// Software Guide : EndCodeSnippet -// Software Guide : BeginLatex + // // The parameter space of the \code{VersorRigid3DTransform} is not a vector -// space, due to the fact that addition is not a closed operation in the space -// of versor components. This precludes the use of standard gradient descent -// algorithms for optimizing the parameter space of this transform. A special -// optimizer should be used in this registration configuration. The optimizer -// designed for this transform is the -// \doxygen{VersorRigid3DTransformOptimizer}. This optimizer uses Versor -// composition for updating the first three components of the parameters -// array, and Vector addition for updating the last three components of the -// parameters array~\cite{Hamilton1866,Joly1905}. +// space, because addition is not a closed operation in the space +// of versor components. Hence, we need to use Versor composition operation to +// update the first three components of the parameter array (rotation parameters), +// and Vector addition for updating the last three components of the parameters +// array (translation parameters)~\cite{Hamilton1866,Joly1905}. // -// \index{itk::Versor\-Rigid3D\-Transform\-Optimizer!header} +// In the previous version of ITK, a special optimizer, \doxygen{VersorRigid3DTransformOptimizer} +// was needed for registration to deal with versor computations. +// Fortunately in ITKv4, the \doxygen{RegularStepGradientDescentOptimizerv4} +// can be used for both vector and versor transform optimizations because, in the new +// registration framework, the task of updating parameters is delegated to the +// moving transform itself. The \code{UpdateTransformParameters} method is implemented +// in the \doxygen{Transform} class as a virtual function, and all the derived transform +// classes can have their own implementations of this function. Due to this +// fact, the updating function is re-implemented for versor transforms +// so it can handle versor composition of the rotation parameters. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkVersorRigid3DTransformOptimizer.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" #include "itkImageFileWriter.h" #include "itkResampleImageFilter.h" @@ -99,7 +95,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::VersorRigid3DTransformOptimizer; @@ -110,7 +106,7 @@ class CommandIterationUpdate : public itk::Command } void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -121,8 +117,10 @@ class CommandIterationUpdate : public itk::Command } }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -141,7 +139,6 @@ int main( int argc, char *argv[] ) using FixedImageType = itk::Image< PixelType, Dimension >; using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : BeginLatex // // The Transform class is instantiated using the code below. The only // template parameter to this class is the representation type of the @@ -149,10 +146,8 @@ int main( int argc, char *argv[] ) // // \index{itk::Versor\-Rigid3D\-Transform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet + using TransformType = itk::VersorRigid3DTransform< double >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::VersorRigid3DTransformOptimizer; using MetricType = itk::MeanSquaresImageToImageMetric< FixedImageType, MovingImageType >; using InterpolatorType = itk:: LinearInterpolateImageFunction< MovingImageType, double >; @@ -167,20 +162,17 @@ int main( int argc, char *argv[] ) registration->SetOptimizer( optimizer ); registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // - // The transform object is constructed below and passed to the registration - // method. + // The initial transform object is constructed below. This transform will be initialized, + // and its initial parameters will be used when + // the registration process starts. // // \index{itk::Versor\-Rigid3D\-Transform!New()} // \index{itk::Versor\-Rigid3D\-Transform!Pointer} // \index{itk::Registration\-Method!SetTransform()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; using MovingImageReaderType = itk::ImageFileReader< MovingImageType >; FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); @@ -193,7 +185,6 @@ int main( int argc, char *argv[] ) registration->SetFixedImageRegion( fixedImageReader->GetOutput()->GetBufferedRegion() ); - // Software Guide : BeginLatex // // The input images are taken from readers. It is not necessary here to // explicitly call \code{Update()} on the readers since the @@ -208,28 +199,20 @@ int main( int argc, char *argv[] ) // \index{itk::Centered\-Transform\-Initializer!New()} // \index{itk::Centered\-Transform\-Initializer!SmartPointer} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformInitializerType = itk::CenteredTransformInitializer< TransformType, FixedImageType, MovingImageType >; TransformInitializerType::Pointer initializer = TransformInitializerType::New(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The initializer is now connected to the transform and to the fixed and // moving images. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet initializer->SetTransform( transform ); initializer->SetFixedImage( fixedImageReader->GetOutput() ); initializer->SetMovingImage( movingImageReader->GetOutput() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The use of the geometrical centers is selected by calling // \code{GeometryOn()} while the use of center of mass is selected by @@ -238,24 +221,16 @@ int main( int argc, char *argv[] ) // \index{Centered\-Transform\-Initializer!MomentsOn()} // \index{Centered\-Transform\-Initializer!GeometryOn()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet initializer->MomentsOn(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Finally, the computation of the center and translation is triggered by // the \code{InitializeTransform()} method. The resulting values will be // passed directly to the transform. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet initializer->InitializeTransform(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The rotation part of the transform is initialized using a // \doxygen{Versor} which is simply a unit quaternion. The @@ -265,8 +240,6 @@ int main( int argc, char *argv[] ) // create a versor object and initialize its parameters by passing a // rotation axis and an angle. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using VersorType = TransformType::VersorType; using VectorType = VersorType::VectorType; VersorType rotation; @@ -277,17 +250,12 @@ int main( int argc, char *argv[] ) constexpr double angle = 0; rotation.Set( axis, angle ); transform->SetRotation( rotation ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We now pass the parameters of the current transform as the initial // parameters to be used when the registration process starts. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet using OptimizerScalesType = OptimizerType::ScalesType; OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() ); const double translationScale = 1.0 / 1000.0; @@ -345,7 +313,6 @@ int main( int argc, char *argv[] ) std::cout << " Iterations = " << numberOfIterations << std::endl; std::cout << " Metric value = " << bestValue << std::endl; - // Software Guide : BeginLatex // // Let's execute this example over some of the images available in the ftp // site @@ -391,16 +358,12 @@ int main( int argc, char *argv[] ) // It is more illustrative in this case to take a look at the actual // rotation matrix and offset resulting form the $6$ parameters. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet transform->SetParameters( finalParameters ); TransformType::MatrixType matrix = transform->GetMatrix(); TransformType::OffsetType offset = transform->GetOffset(); std::cout << "Matrix = " << std::endl << matrix << std::endl; std::cout << "Offset = " << std::endl << offset << std::endl; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The output of this print statements is // @@ -420,9 +383,7 @@ int main( int argc, char *argv[] ) // happening in the X,Y plane and that the angle is on the order of // $\arcsin{(0.173722)}$ which is very close to 10 degrees, as we expected. // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -495,7 +456,6 @@ int main( int argc, char *argv[] ) // results that in practice are impossible to replicate. That is vanity, not // science. // - // Software Guide : EndLatex using ResampleFilterType = itk::ResampleImageFilter< MovingImageType, diff --git a/Examples/RegistrationITKv3/ImageRegistration9.cxx b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration9.cxx similarity index 90% rename from Examples/RegistrationITKv3/ImageRegistration9.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration9.cxx index 407bc7037b8..c1ebe30cbb6 100644 --- a/Examples/RegistrationITKv3/ImageRegistration9.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/ImageRegistration9.cxx @@ -16,16 +16,13 @@ * *=========================================================================*/ -// Software Guide : BeginCommandLineArgs // INPUTS: {BrainProtonDensitySliceBorder20.png} // INPUTS: {BrainProtonDensitySliceR10X13Y17.png} // OUTPUTS: {ImageRegistration9Output.png} // OUTPUTS: {ImageRegistration9DifferenceBefore.png} // OUTPUTS: {ImageRegistration9DifferenceAfter.png} // ARGUMENTS: 1.0 300 -// Software Guide : EndCommandLineArgs -// Software Guide : BeginLatex // // This example illustrates the use of the \doxygen{AffineTransform} // for performing registration in $2D$. The example code is, for the most part, @@ -37,7 +34,6 @@ // // \index{itk::AffineTransform} // -// Software Guide : EndLatex #include "itkImageRegistrationMethod.h" #include "itkMeanSquaresImageToImageMetric.h" @@ -46,17 +42,13 @@ #include "itkCenteredTransformInitializer.h" -// Software Guide : BeginLatex // // Let's start by including the header file of the AffineTransform. // // \index{itk::AffineTransform!header} // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkAffineTransform.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" @@ -82,7 +74,7 @@ class CommandIterationUpdate : public itk::Command itkNewMacro( Self ); protected: - CommandIterationUpdate() {}; + CommandIterationUpdate() = default; public: using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -95,7 +87,7 @@ class CommandIterationUpdate : public itk::Command void Execute(const itk::Object * object, const itk::EventObject & event) override { - OptimizerPointer optimizer = static_cast< OptimizerPointer >( object ); + auto optimizer = static_cast< OptimizerPointer >( object ); if( ! itk::IterationEvent().CheckEvent( &event ) ) { return; @@ -119,8 +111,10 @@ class CommandIterationUpdate : public itk::Command }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -133,22 +127,17 @@ int main( int argc, char *argv[] ) } - // Software Guide : BeginLatex // - // We define then the types of the images to be registered. + // We then define the types of the images to be registered. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet constexpr unsigned int Dimension = 2; using PixelType = float; using FixedImageType = itk::Image< PixelType, Dimension >; using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The transform type is instantiated using the code below. The template // parameters of this class are the representation type of the space @@ -156,11 +145,8 @@ int main( int argc, char *argv[] ) // // \index{itk::AffineTransform!Instantiation} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformType = itk::AffineTransform< double, Dimension >; - // Software Guide : EndCodeSnippet using OptimizerType = itk::RegularStepGradientDescentOptimizer; @@ -181,21 +167,17 @@ int main( int argc, char *argv[] ) registration->SetInterpolator( interpolator ); - // Software Guide : BeginLatex // - // The transform object is constructed below and passed to the registration - // method. + // The transform object is constructed below and is initialized before the registration + // process starts. // // \index{itk::AffineTransform!New()} // \index{itk::AffineTransform!Pointer} // \index{itk::RegistrationMethod!SetTransform()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet TransformType::Pointer transform = TransformType::New(); registration->SetTransform( transform ); - // Software Guide : EndCodeSnippet using FixedImageReaderType = itk::ImageFileReader< FixedImageType >; @@ -214,7 +196,6 @@ int main( int argc, char *argv[] ) fixedImageReader->GetOutput()->GetBufferedRegion() ); - // Software Guide : BeginLatex // // In this example, we again use the // \doxygen{CenteredTransformInitializer} helper class in order to compute @@ -222,9 +203,7 @@ int main( int argc, char *argv[] ) // translation. The initializer is set to use the center of mass of each // image as the initial correspondence correction. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformInitializerType = itk::CenteredTransformInitializer< TransformType, FixedImageType, MovingImageType >; @@ -235,23 +214,17 @@ int main( int argc, char *argv[] ) initializer->SetMovingImage( movingImageReader->GetOutput() ); initializer->MomentsOn(); initializer->InitializeTransform(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Now we pass the parameters of the current transform as the initial // parameters to be used when the registration process starts. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetInitialTransformParameters( transform->GetParameters() ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Keeping in mind that the scale of units in scaling, rotation and // translation are quite different, we take advantage of the scaling @@ -260,7 +233,6 @@ int main( int argc, char *argv[] ) // matrix factor, and the last $N$ are the components of the translation to // be applied after multiplication with the matrix is performed. // - // Software Guide : EndLatex double translationScale = 1.0 / 1000.0; @@ -270,7 +242,6 @@ int main( int argc, char *argv[] ) } - // Software Guide : BeginCodeSnippet using OptimizerScalesType = OptimizerType::ScalesType; OptimizerScalesType optimizerScales( transform->GetNumberOfParameters() ); @@ -282,10 +253,8 @@ int main( int argc, char *argv[] ) optimizerScales[5] = translationScale; optimizer->SetScales( optimizerScales ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We also set the usual parameters of the optimization method. In this // case we are using an @@ -294,7 +263,6 @@ int main( int argc, char *argv[] ) // and number of iterations. These last two act as stopping criteria for // the optimization. // - // Software Guide : EndLatex double steplength = 0.1; @@ -312,25 +280,19 @@ int main( int argc, char *argv[] ) } - // Software Guide : BeginCodeSnippet optimizer->SetMaximumStepLength( steplength ); optimizer->SetMinimumStepLength( 0.0001 ); optimizer->SetNumberOfIterations( maxNumberOfIterations ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We also set the optimizer to do minimization by calling the // \code{MinimizeOn()} method. // // \index{itk::Regular\-Step\-Gradient\-Descent\-Optimizer!MinimizeOn()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet optimizer->MinimizeOn(); - // Software Guide : EndCodeSnippet // Create the Command observer and register it with the optimizer. @@ -339,15 +301,12 @@ int main( int argc, char *argv[] ) optimizer->AddObserver( itk::IterationEvent(), observer ); - // Software Guide : BeginLatex // // Finally we trigger the execution of the registration method by calling // the \code{Update()} method. The call is placed in a \code{try/catch} // block in case any exceptions are thrown. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet try { registration->Update(); @@ -361,10 +320,8 @@ int main( int argc, char *argv[] ) std::cerr << err << std::endl; return EXIT_FAILURE; } - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Once the optimization converges, we recover the parameters from the // registration method. This is done with the @@ -377,9 +334,7 @@ int main( int argc, char *argv[] ) // \index{itk::RegistrationMethod!GetCurrentIteration()} // \index{itk::RegistrationMethod!GetLastTransformParameters()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet OptimizerType::ParametersType finalParameters = registration->GetLastTransformParameters(); @@ -390,7 +345,6 @@ int main( int argc, char *argv[] ) const unsigned int numberOfIterations = optimizer->GetCurrentIteration(); const double bestValue = optimizer->GetValue(); - // Software Guide : EndCodeSnippet // Print out results @@ -424,7 +378,6 @@ int main( int argc, char *argv[] ) std::cout << " Angle (degrees) = " << angleInDegrees << std::endl; - // Software Guide : BeginLatex // // Let's execute this example over two of the images provided in // \code{Examples/Data}: @@ -509,7 +462,6 @@ int main( int argc, char *argv[] ) // is to be computed as a combination of the shift due rotation plus the // explicit translation set on the transform. // - // Software Guide : EndLatex // The following code is used to dump output images to files. diff --git a/Examples/RegistrationITKv3/MeanSquaresImageMetric1.cxx b/Modules/Registration/Common/test/RegistrationITKv3/MeanSquaresImageMetric1.cxx similarity index 78% rename from Examples/RegistrationITKv3/MeanSquaresImageMetric1.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/MeanSquaresImageMetric1.cxx index c2f1501d52e..5eb71940991 100644 --- a/Examples/RegistrationITKv3/MeanSquaresImageMetric1.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/MeanSquaresImageMetric1.cxx @@ -16,19 +16,17 @@ * *=========================================================================*/ -// Software Guide : BeginLatex // // This example illustrates how to explore the domain of an image metric. This -// is a useful exercise to do before starting a registration process, since -// getting familiar with the characteristics of the metric is fundamental for -// the appropriate selection of the optimizer to be use for driving the -// registration process, as well as for selecting the optimizer parameters. -// This process makes possible to identify how noisy a metric may be in a given +// is a useful exercise before starting a registration process, since +// familiarity with the characteristics of the metric is fundamental for +// appropriate selection of the optimizer and its parameters used to drive the +// registration process. +// This process helps identify how noisy a metric may be in a given // range of parameters, and it will also give an idea of the number of local // minima or maxima in which an optimizer may get trapped while exploring the // parametric space. // -// Software Guide : EndLatex #include "itkImage.h" @@ -36,22 +34,20 @@ #include "itkImageFileWriter.h" -// Software Guide : BeginLatex // // We start by including the headers of the basic components: Metric, Transform // and Interpolator. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkMeanSquaresImageToImageMetric.h" #include "itkTranslationTransform.h" #include "itkNearestNeighborInterpolateImageFunction.h" -// Software Guide : EndCodeSnippet +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, char * argv[] ) { + RegisterRequiredFactories(); if( argc < 3 ) { std::cerr << "Usage: " << std::endl; @@ -59,19 +55,15 @@ int main( int argc, char * argv[] ) return EXIT_FAILURE; } -// Software Guide : BeginLatex // // We define the dimension and pixel type of the images to be used in the // evaluation of the Metric. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet constexpr unsigned int Dimension = 2; using PixelType = unsigned char; using ImageType = itk::Image< PixelType, Dimension >; -// Software Guide : EndCodeSnippet using ReaderType = itk::ImageFileReader< ImageType >; @@ -93,40 +85,32 @@ int main( int argc, char * argv[] ) std::cerr << excep << std::endl; } -// Software Guide : BeginLatex // // The type of the Metric is instantiated and one is constructed. In this case // we decided to use the same image type for both the fixed and the moving // images. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet using MetricType = itk::MeanSquaresImageToImageMetric< ImageType, ImageType >; MetricType::Pointer metric = MetricType::New(); -// Software Guide : EndCodeSnippet -// Software Guide : BeginLatex // // We also instantiate the transform and interpolator types, and create objects // of each class. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet using TransformType = itk::TranslationTransform< double, Dimension >; TransformType::Pointer transform = TransformType::New(); using InterpolatorType = itk::NearestNeighborInterpolateImageFunction< - ImageType, double >; + ImageType, double >; InterpolatorType::Pointer interpolator = InterpolatorType::New(); -// Software Guide : EndCodeSnippet transform->SetIdentity(); @@ -135,20 +119,16 @@ int main( int argc, char * argv[] ) ImageType::ConstPointer movingImage = movingReader->GetOutput(); -// Software Guide : BeginLatex // // The classes required by the metric are connected to it. This includes the -// fixed and moving images, the interpolator and the transform. +// fixed and moving images, the interpolator and the transform. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet metric->SetTransform( transform ); metric->SetInterpolator( interpolator ); metric->SetFixedImage( fixedImage ); metric->SetMovingImage( movingImage ); -// Software Guide : EndCodeSnippet metric->SetFixedImageRegion( fixedImage->GetBufferedRegion() ); @@ -164,16 +144,13 @@ int main( int argc, char * argv[] ) } -// Software Guide : BeginLatex // // Finally we select a region of the parametric space to explore. In this case // we are using a translation transform in 2D, so we simply select translations // from a negative position to a positive position, in both $x$ and $y$. For -// each one of those positions we invoke the GetValue() method of the Metric. +// each one of those positions we invoke the \code{GetValue()} method of the Metric. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet MetricType::TransformParametersType displacement( Dimension ); constexpr int rangex = 50; @@ -189,10 +166,8 @@ int main( int argc, char * argv[] ) std::cout << dx << " " << dy << " " << value << std::endl; } } -// Software Guide : EndCodeSnippet -// Software Guide : BeginLatex // // \begin{figure} // \center @@ -205,8 +180,8 @@ int main( int argc, char * argv[] ) // // Running this code using the image BrainProtonDensitySlice.png as both the // fixed and the moving images results in the plot shown in -// Figure~\ref{fig:MeanSquaresMetricPlot}. From this Figure, it can be seen -// that a gradient based optimizer will be appropriate for finding the extrema +// Figure~\ref{fig:MeanSquaresMetricPlot}. From this figure, it can be seen +// that a gradient-based optimizer will be appropriate for finding the extrema // of the Metric. It is also possible to estimate a good value for the step // length of a gradient-descent optimizer. // @@ -224,12 +199,11 @@ int main( int argc, char * argv[] ) // // Of course, this plotting exercise becomes more challenging when the // transform has more than three parameters, and when those parameters have -// very different range of values. In those cases is necessary to select only a +// very different value ranges. In those cases it is necessary to select only a // key subset of parameters from the transform and to study the behavior of the // metric when those parameters are varied. // // -// Software Guide : EndLatex return EXIT_SUCCESS; diff --git a/Examples/RegistrationITKv3/MultiResImageRegistration1.cxx b/Modules/Registration/Common/test/RegistrationITKv3/MultiResImageRegistration1.cxx similarity index 89% rename from Examples/RegistrationITKv3/MultiResImageRegistration1.cxx rename to Modules/Registration/Common/test/RegistrationITKv3/MultiResImageRegistration1.cxx index 4edb6ef8879..db5317d4f2f 100644 --- a/Examples/RegistrationITKv3/MultiResImageRegistration1.cxx +++ b/Modules/Registration/Common/test/RegistrationITKv3/MultiResImageRegistration1.cxx @@ -16,16 +16,13 @@ * *=========================================================================*/ -// Software Guide : BeginCommandLineArgs // INPUTS: {BrainT1SliceBorder20.png} // INPUTS: {BrainProtonDensitySliceShifted13x17y.png} // OUTPUTS: {MultiResImageRegistration1Output.png} // ARGUMENTS: 128 // OUTPUTS: {MultiResImageRegistration1CheckerboardBefore.png} // OUTPUTS: {MultiResImageRegistration1CheckerboardAfter.png} -// Software Guide : EndCommandLineArgs -// Software Guide : BeginLatex // // \index{itk::ImageRegistrationMethod!Multi-Resolution} // \index{itk::ImageRegistrationMethod!Multi-Modality} @@ -39,15 +36,12 @@ // the sequence of downsampled images. To begin the example, we include the // headers of the registration components we will use. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkMultiResolutionImageRegistrationMethod.h" #include "itkTranslationTransform.h" #include "itkMattesMutualInformationImageToImageMetric.h" #include "itkRegularStepGradientDescentOptimizer.h" #include "itkImage.h" -// Software Guide : EndCodeSnippet #include "itkImageFileReader.h" @@ -58,10 +52,9 @@ #include "itkCheckerBoardImageFilter.h" -// Software Guide : BeginLatex // // The MultiResolutionImageRegistrationMethod solves a registration -// problem in a coarse to fine manner as illustrated in Figure +// problem in a coarse-to-fine manner as illustrated in Figure // \ref{fig:MultiResRegistrationConcept}. The registration is first performed // at the coarsest level using the images at the first level of the fixed and // moving image pyramids. The transform parameters determined by the @@ -77,10 +70,8 @@ // \label{fig:MultiResRegistrationConcept} // \end{figure} // -// Software Guide : EndLatex -// Software Guide : BeginLatex // // In a typical registration scenario, a user will tweak component settings // or even swap out components between multi-resolution levels. For example, @@ -103,36 +94,26 @@ // optimizer between each resolution level by way of a simple interface // command. First, we include the header file of the Command class. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet #include "itkCommand.h" -// Software Guide : EndCodeSnippet -// Software Guide : BeginLatex // // Our new interface command class is called // \code{RegistrationInterfaceCommand}. It derives from // Command and is templated over the // multi-resolution registration type. // -// Software Guide : EndLatex -// Software Guide : BeginCodeSnippet template class RegistrationInterfaceCommand : public itk::Command { - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We then define \code{Self}, \code{Superclass}, \code{Pointer}, // \code{New()} and a constructor in a similar fashion to the // \code{CommandIterationUpdate} class in Section // \ref{sec:MonitoringImageRegistration}. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet public: using Self = RegistrationInterfaceCommand; @@ -142,61 +123,43 @@ class RegistrationInterfaceCommand : public itk::Command protected: RegistrationInterfaceCommand() {}; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // For convenience, we declare types useful for converting pointers // in the \code{Execute()} method. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet public: using RegistrationType = TRegistration; using RegistrationPointer = RegistrationType *; using OptimizerType = itk::RegularStepGradientDescentOptimizer; using OptimizerPointer = OptimizerType *; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Two arguments are passed to the \code{Execute()} method: the first // is the pointer to the object which invoked the event and the // second is the event that was invoked. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - void Execute(itk::Object * object, const itk::EventObject & event) + void Execute(itk::Object * object, const itk::EventObject & event) override { - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // First we verify if that the event invoked is of the right type. // If not, we return without any further action. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet if( !(itk::IterationEvent().CheckEvent( &event )) ) { return; } - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We then convert the input object pointer to a RegistrationPointer. // Note that no error checking is done here to verify if the // \code{dynamic\_cast} was successful since we know the actual object // is a multi-resolution registration method. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet RegistrationPointer registration = static_cast( object ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // If this is the first resolution level we set the maximum step length // (representing the first step size) and the minimum step length (representing @@ -209,8 +172,6 @@ class RegistrationInterfaceCommand : public itk::Command // for the previous level. This will guarantee the continuity of the path // taken by the optimizer through the parameter space. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet OptimizerPointer optimizer = static_cast< OptimizerPointer >(registration->GetModifiableOptimizer() ); std::cout << "-------------------------------------" << std::endl; @@ -231,20 +192,15 @@ class RegistrationInterfaceCommand : public itk::Command optimizer->GetMinimumStepLength() * 0.1 ); } } - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // Another version of the \code{Execute()} method accepting a \code{const} // input object is also required since this method is defined as pure virtual // in the base class. This version simply returns without taking any action. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet - void Execute(const itk::Object * , const itk::EventObject & ) + void Execute(const itk::Object * , const itk::EventObject & ) override { return; } }; -// Software Guide : EndCodeSnippet // The following section of code implements an observer @@ -284,8 +240,10 @@ class CommandIterationUpdate : public itk::Command }; +#include "itkTestDriverIncludeRequiredIOFactories.h" int main( int argc, const char *argv[] ) { + RegisterRequiredFactories(); if( argc < 4 ) { std::cerr << "Missing Parameters " << std::endl; @@ -314,7 +272,6 @@ int main( int argc, const char *argv[] ) using FixedImageType = itk::Image< PixelType, Dimension >; using MovingImageType = itk::Image< PixelType, Dimension >; - // Software Guide : BeginLatex // // The fixed and moving image types are defined as in previous // examples. Due to the recursive nature of the process by which the @@ -322,19 +279,13 @@ int main( int argc, const char *argv[] ) // images are required to have real pixel types. We declare this internal // image type to be \code{InternalPixelType}: // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using InternalPixelType = float; using InternalImageType = itk::Image< InternalPixelType, Dimension >; - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The types for the registration components are then derived using // the internal image type. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using TransformType = itk::TranslationTransform< double, Dimension >; using OptimizerType = itk::RegularStepGradientDescentOptimizer; using InterpolatorType = itk::LinearInterpolateImageFunction< @@ -348,7 +299,6 @@ int main( int argc, const char *argv[] ) InternalImageType >; // Software Guide: EndCodeSnippet - // Software Guide : BeginLatex // // In the multi-resolution framework, a // \doxygen{MultiResolutionPyramidImageFilter} is used to create a pyramid @@ -358,8 +308,6 @@ int main( int argc, const char *argv[] ) // Section \ref{sec:ImagePyramids}. For this example, we will simply use // the default schedules. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using FixedImagePyramidType = itk::MultiResolutionPyramidImageFilter< InternalImageType, InternalImageType >; using MovingImagePyramidType = itk::MultiResolutionPyramidImageFilter< @@ -399,14 +347,11 @@ int main( int argc, const char *argv[] ) movingImageReader->SetFileName( movingImageFile ); - // Software Guide : BeginLatex // // The fixed and moving images are read from a file. Before connecting // these images to the registration we need to cast them to the internal // image type using \doxygen{CastImageFilters}. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using FixedCastFilterType = itk::CastImageFilter< FixedImageType, InternalImageType >; using MovingCastFilterType = itk::CastImageFilter< @@ -414,22 +359,17 @@ int main( int argc, const char *argv[] ) FixedCastFilterType::Pointer fixedCaster = FixedCastFilterType::New(); MovingCastFilterType::Pointer movingCaster = MovingCastFilterType::New(); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // The output of the readers is connected as input to the cast // filters. The inputs to the registration method are taken from the // cast filters. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet fixedCaster->SetInput( fixedImageReader->GetOutput() ); movingCaster->SetInput( movingImageReader->GetOutput() ); registration->SetFixedImage( fixedCaster->GetOutput() ); registration->SetMovingImage( movingCaster->GetOutput() ); - // Software Guide : EndCodeSnippet fixedCaster->Update(); @@ -462,7 +402,6 @@ int main( int argc, const char *argv[] ) } - // Software Guide : BeginLatex // // Given that the Mattes Mutual Information metric uses a random iterator in // order to collect the samples from the images, it is usually convenient to @@ -470,11 +409,8 @@ int main( int argc, const char *argv[] ) // // \index{itk::Mattes\-Mutual\-Information\-Image\-To\-Image\-Metric!ReinitializeSeed()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet metric->ReinitializeSeed( 76926294 ); - // Software Guide : EndCodeSnippet if( argc > 7 ) @@ -497,21 +433,16 @@ int main( int argc, const char *argv[] ) optimizer->AddObserver( itk::IterationEvent(), observer ); - // Software Guide : BeginLatex // // Once all the registration components are in place we can create // an instance of our interface command and connect it to the // registration object using the \code{AddObserver()} method. // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet using CommandType = RegistrationInterfaceCommand; CommandType::Pointer command = CommandType::New(); registration->AddObserver( itk::IterationEvent(), command ); - // Software Guide : EndCodeSnippet - // Software Guide : BeginLatex // // We set the number of multi-resolution levels to three and trigger the // registration process by calling \code{Update()}. @@ -519,9 +450,7 @@ int main( int argc, const char *argv[] ) // \index{itk::Multi\-Resolution\-Image\-Registration\-Method!SetNumberOfLevels()} // \index{itk::Multi\-Resolution\-Image\-Registration\-Method!Update()} // - // Software Guide : EndLatex - // Software Guide : BeginCodeSnippet registration->SetNumberOfLevels( 3 ); try @@ -537,7 +466,6 @@ int main( int argc, const char *argv[] ) std::cout << err << std::endl; return EXIT_FAILURE; } - // Software Guide : EndCodeSnippet ParametersType finalParameters = registration->GetLastTransformParameters(); @@ -558,7 +486,6 @@ int main( int argc, const char *argv[] ) std::cout << " Metric value = " << bestValue << std::endl; - // Software Guide : BeginLatex // // Let's execute this example using the following images // @@ -600,7 +527,6 @@ int main( int argc, const char *argv[] ) // These values are a close match to the true misalignment of $(13,17)$ // introduced in the moving image. // - // Software Guide : EndLatex using ResampleFilterType = itk::ResampleImageFilter< MovingImageType, @@ -687,7 +613,6 @@ int main( int argc, const char *argv[] ) writer->Update(); } - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -705,9 +630,7 @@ int main( int argc, const char *argv[] ) // right images of the figure depict a checkerboard composite of the fixed // and moving images before and after registration. // - // Software Guide : EndLatex - // Software Guide : BeginLatex // // \begin{figure} // \center @@ -730,7 +653,6 @@ int main( int argc, const char *argv[] ) // \ref{sec:MultiModalityRegistrationMattes}, where 24 iterations were // required as more conservative optimization parameters had to be used. // - // Software Guide : EndLatex return EXIT_SUCCESS; diff --git a/Examples/RegistrationITKv3/test/Baseline/BSplineWarping1Test.png.md5 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/BSplineWarping1Test.png.md5 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/BSplineWarping1Test.png.md5 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/BSplineWarping1Test.png.md5 diff --git a/Examples/RegistrationITKv3/test/Baseline/BSplineWarping1Test.png.sha512 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/BSplineWarping1Test.png.sha512 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/BSplineWarping1Test.png.sha512 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/BSplineWarping1Test.png.sha512 diff --git a/Examples/RegistrationITKv3/test/Baseline/DeformableRegistration12Test.png.md5 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration12Test.png.md5 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/DeformableRegistration12Test.png.md5 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration12Test.png.md5 diff --git a/Examples/RegistrationITKv3/test/Baseline/DeformableRegistration12Test.png.sha512 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration12Test.png.sha512 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/DeformableRegistration12Test.png.sha512 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration12Test.png.sha512 diff --git a/Examples/RegistrationITKv3/test/Baseline/DeformableRegistration13Test.png.md5 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration13Test.png.md5 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/DeformableRegistration13Test.png.md5 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration13Test.png.md5 diff --git a/Examples/RegistrationITKv3/test/Baseline/DeformableRegistration13Test.png.sha512 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration13Test.png.sha512 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/DeformableRegistration13Test.png.sha512 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration13Test.png.sha512 diff --git a/Examples/RegistrationITKv3/test/Baseline/DeformableRegistration1v4Test.png.md5 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration1v4Test.png.md5 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/DeformableRegistration1v4Test.png.md5 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration1v4Test.png.md5 diff --git a/Examples/RegistrationITKv3/test/Baseline/DeformableRegistration1v4Test.png.sha512 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration1v4Test.png.sha512 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/DeformableRegistration1v4Test.png.sha512 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration1v4Test.png.sha512 diff --git a/Examples/RegistrationITKv3/test/Baseline/DeformableRegistration6TestPixelCentered.png.md5 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration6TestPixelCentered.png.md5 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/DeformableRegistration6TestPixelCentered.png.md5 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration6TestPixelCentered.png.md5 diff --git a/Examples/RegistrationITKv3/test/Baseline/DeformableRegistration6TestPixelCentered.png.sha512 b/Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration6TestPixelCentered.png.sha512 similarity index 100% rename from Examples/RegistrationITKv3/test/Baseline/DeformableRegistration6TestPixelCentered.png.sha512 rename to Modules/Registration/Common/test/RegistrationITKv3/test/Baseline/DeformableRegistration6TestPixelCentered.png.sha512 diff --git a/Modules/Registration/Common/test/RegistrationITKv3/test/CMakeLists.txt b/Modules/Registration/Common/test/RegistrationITKv3/test/CMakeLists.txt new file mode 100644 index 00000000000..356bc8d9525 --- /dev/null +++ b/Modules/Registration/Common/test/RegistrationITKv3/test/CMakeLists.txt @@ -0,0 +1,542 @@ +set(ITK_TEST_DRIVER itkTestDriver) + +set(BASELINE ${ITK_DATA_ROOT}/Baseline/Registration) +set(TEMP ${ITK_BINARY_DIR}/Testing/Temporary) + +itk_add_test(NAME ITKv3ImageRegistration1Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration1TestPixelCentered.png} + ${TEMP}/ImageRegistration1TestPixelCentered.png + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceShifted13x17y.png + ${TEMP}/ImageRegistration1TestPixelCentered.png + ${TEMP}/ImageRegistration1DifferenceAfterTestPixelCentered.png + ${TEMP}/ImageRegistration1DifferenceBeforeTestPixelCentered.png +) + +itk_add_test(NAME ITKv3ImageRegistration3Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration3TestPixelCentered.png} + ${TEMP}/ImageRegistration3TestPixelCentered.png + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceShifted13x17y.png + ${TEMP}/ImageRegistration3TestPixelCentered.png +) + +itk_add_test(NAME ITKv3ImageRegistration4Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ITKv3ImageRegistration4Test.png} + ${TEMP}/ImageRegistration4Test.png + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainT1SliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceShifted13x17y.png + ${TEMP}/ImageRegistration4Test.png 0 + ${TEMP}/ImageRegistration4BeforeTest.png + ${TEMP}/ImageRegistration4AfterTest.png + 24 10000 1 +) + +itk_add_test(NAME ITKv3ImageRegistration4Test2 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ITKv3ImageRegistration4Test.png} + ${TEMP}/ImageRegistration4Test2.png + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainT1SliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceShifted13x17y.png + ${TEMP}/ImageRegistration4Test2.png 0 + ${TEMP}/ImageRegistration4BeforeTest.png + ${TEMP}/ImageRegistration4AfterTest.png + 24 10000 0 +) + +itk_add_test(NAME ITKv3ImageRegistration4Test3 COMMAND ${ITK_TEST_DRIVER} + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20Mask.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20Mask.png + ${TEMP}/ImageRegistration4Test3.png 0 + ${TEMP}/ImageRegistration4BeforeTest3.png + ${TEMP}/ImageRegistration4AfterTest3.png + 5 10000 0 +) + +itk_add_test(NAME ITKv3ImageRegistration5Test1 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration5Test1PixelCentered.png} + ${TEMP}/ImageRegistration5Test1PixelCentered.png + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceRotated10.png + ${TEMP}/ImageRegistration5Test1PixelCentered.png +) + +itk_add_test(NAME ITKv3ImageRegistration5Test2 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ITKv3ImageRegistration5Test2PixelCentered.png} + ${TEMP}/ImageRegistration5Test2PixelCentered.png + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${TEMP}/ImageRegistration5Test2PixelCentered.png +) + +itk_add_test(NAME ITKv3ImageRegistration6Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration6TestPixelCentered.png} + ${TEMP}/ImageRegistration6TestPixelCentered.png + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${TEMP}/ImageRegistration6TestPixelCentered.png +) + +itk_add_test(NAME ITKv3ImageRegistration7Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration7TestPixelCentered.png} + ${TEMP}/ImageRegistration7TestPixelCentered.png + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17S12.png + ${TEMP}/ImageRegistration7TestPixelCentered.png + ${TEMP}/ImageRegistration7BeforeTestPixelCentered.png + ${TEMP}/ImageRegistration7AfterTestPixelCentered.png + 1.0 1.0 0.0 +) + +if(ITK_USE_BRAINWEB_DATA) + +## A test needed to prepare for making the latex documentation. +itk_add_test(NAME ITKv3ITKv3ConfidenceConnected3DTest COMMAND ${ITK_TEST_DRIVER} + $ + DATA{../../Data/BrainWeb/brainweb165a10f17.mha} + ${TEMP}/WhiteMatterSegmentation.mhd +) + +itk_add_test(NAME ITKv3ImageRegistration8Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration8RegisteredSlice.png} + ${TEMP}/ImageRegistration8v3RegisteredSlice.png + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + DATA{../../Data/BrainWeb/brainweb1e1a10f20Rot10Tx15.mha} + ${TEMP}/ImageRegistration8v3Output.mhd + ${TEMP}/ImageRegistration8v3DifferenceBefore.mhd + ${TEMP}/ImageRegistration8v3DifferenceAfter.mhd + ${TEMP}/ImageRegistration8v3Output.png + ${TEMP}/ImageRegistration8v3DifferenceBefore.png + ${TEMP}/ImageRegistration8v3DifferenceAfter.png + ${TEMP}/ImageRegistration8v3RegisteredSlice.png +) + +endif() + +itk_add_test(NAME ITKv3ImageRegistration9Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration9TestPixelCentered.png} + ${TEMP}/ImageRegistration9TestPixelCentered.png + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${TEMP}/ImageRegistration9TestPixelCentered.png +) + +itk_add_test(NAME ITKv3ImageRegistration13Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} + ${TEMP}/ImageRegistration13TestPixelCentered.png + --compareNumberOfPixelsTolerance 5 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${TEMP}/ImageRegistration13TestPixelCentered.png +) + +itk_add_test(NAME ITKv3ImageRegistration13Test2 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} + ${TEMP}/ImageRegistration13Test2PixelCentered.png + --compareNumberOfPixelsTolerance 10 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${TEMP}/ImageRegistration13Test2PixelCentered.png + 0 0 +) + +itk_add_test(NAME ITKv3ImageRegistration13Test3 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} + ${TEMP}/ImageRegistration13Test3PixelCentered.png + --compareNumberOfPixelsTolerance 10 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${TEMP}/ImageRegistration13Test3PixelCentered.png + 0 1 +) + +itk_add_test(NAME ITKv3ImageRegistration13Test4 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} + ${TEMP}/ImageRegistration13Test4PixelCentered.png + --compareNumberOfPixelsTolerance 5 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${TEMP}/ImageRegistration13Test4PixelCentered.png + 1 0 +) + +itk_add_test(NAME ITKv3ImageRegistration13Test5 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration13TestPixelCentered.png} + ${TEMP}/ImageRegistration13Test5PixelCentered.png + --compareNumberOfPixelsTolerance 5 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${TEMP}/ImageRegistration13Test5PixelCentered.png + 1 1 +) + +itk_add_test(NAME ITKv3ImageRegistration14Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration14Test.png,:} + ${TEMP}/ImageRegistration14Test.png + --compareNumberOfPixelsTolerance 2000 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${TEMP}/ImageRegistration14Test.png 32 0.01 0.1 0.15 10.0 14.0 +) +set_property(TEST ITKv3ImageRegistration14Test APPEND PROPERTY LABELS RUNS_LONG) + +itk_add_test(NAME ITKv3MultiResImageRegistration1Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/MultiResImageRegistration1Test.png,:} + ${TEMP}/MultiResImageRegistration1Test.png + --compareNumberOfPixelsTolerance 10 + --compareIntensityTolerance 7 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainT1SliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceShifted13x17y.png + ${TEMP}/MultiResImageRegistration1Test.png 100 + ${TEMP}/MultiResImageRegistration1CheckerBoardBeforeTest.png + ${TEMP}/MultiResImageRegistration1CheckerBoardAfterTest.png +) +set_property(TEST ITKv3MultiResImageRegistration1Test APPEND PROPERTY LABELS RUNS_LONG) + +itk_add_test(NAME ITKv3MultiResImageRegistration1Test2 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/MultiResImageRegistration1Test.png,:} + ${TEMP}/MultiResImageRegistration1Test2.png + --compareNumberOfPixelsTolerance 10 + --compareIntensityTolerance 7 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainT1SliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceShifted13x17y.png + ${TEMP}/MultiResImageRegistration1Test2.png 100 + ${TEMP}/MultiResImageRegistration1CheckerBoardBeforeTest2.png + ${TEMP}/MultiResImageRegistration1CheckerBoardAfterTest2.png + 0 +) +set_property(TEST ITKv3MultiResImageRegistration1Test2 APPEND PROPERTY LABELS RUNS_LONG) + +itk_add_test(NAME ITKv3DeformableRegistration12Test1 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{Baseline/DeformableRegistration12Test.png} + ${TEMP}/DeformableRegistration12Test1.png + --compareNumberOfPixelsTolerance 600 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + DATA{Baseline/BSplineWarping1Test.png} + ${TEMP}/DeformableRegistration12Test1.png + ${TEMP}/DeformableRegistration12Test1DifferenceAfter.png + ${TEMP}/DeformableRegistration12Test1DifferenceBefore.png + ${TEMP}/DeformableRegistration12Test1DisplacementField.mhd + 0 0 + ${TEMP}/DeformableRegistration12Test1FinalTransformParameters.txt +) +set_property(TEST ITKv3DeformableRegistration12Test1 APPEND PROPERTY LABELS RUNS_LONG) + +itk_add_test(NAME ITKv3DeformableRegistration12Test2 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{Baseline/DeformableRegistration12Test.png} + ${TEMP}/DeformableRegistration12Test2.png + --compareNumberOfPixelsTolerance 600 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + DATA{Baseline/BSplineWarping1Test.png} + ${TEMP}/DeformableRegistration12Test2.png + ${TEMP}/DeformableRegistration12Test2DifferenceAfter.png + ${TEMP}/DeformableRegistration12Test2DifferenceBefore.png + ${TEMP}/DeformableRegistration12Test2DisplacementField.mhd + 0 1 + ${TEMP}/DeformableRegistration12Test2FinalTransformParameters.txt +) + +itk_add_test(NAME ITKv3DeformableRegistration12Test3 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{Baseline/DeformableRegistration12Test.png} + ${TEMP}/DeformableRegistration12Test3.png + --compareNumberOfPixelsTolerance 600 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + DATA{Baseline/BSplineWarping1Test.png} + ${TEMP}/DeformableRegistration12Test3.png + ${TEMP}/DeformableRegistration12Test3DifferenceAfter.png + ${TEMP}/DeformableRegistration12Test3DifferenceBefore.png + ${TEMP}/DeformableRegistration12Test3DisplacementField.mhd + 1 0 + ${TEMP}/DeformableRegistration12Test3FinalTransformParameters.txt +) +set_property(TEST ITKv3DeformableRegistration12Test3 APPEND PROPERTY LABELS RUNS_LONG) + +itk_add_test(NAME ITKv3DeformableRegistration12Test4 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{Baseline/DeformableRegistration12Test.png} + ${TEMP}/DeformableRegistration12Test4.png + --compareNumberOfPixelsTolerance 600 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + DATA{Baseline/BSplineWarping1Test.png} + ${TEMP}/DeformableRegistration12Test4.png + ${TEMP}/DeformableRegistration12Test4DifferenceAfter.png + ${TEMP}/DeformableRegistration12Test4DifferenceBefore.png + ${TEMP}/DeformableRegistration12Test4DisplacementField.mhd + 1 1 + ${TEMP}/DeformableRegistration12Test4FinalTransformParameters.txt +) + +if( ITK_USE_BRAINWEB_DATA ) + + set( NUMBER_OF_BSPLINE_GRID_NODES 5 ) + + if( DART_TESTING_TIMEOUT GREATER 3000 ) + + itk_add_test(NAME ITKv3DeformableRegistration8Test1 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/DeformableRegistration8Test1.mhd + --compareNumberOfPixelsTolerance 700000 + --compareIntensityTolerance 15 + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test1.mhd + ${TEMP}/DeformableRegistration8Test1DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test1DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test1DisplacementField.mhd + 0 0 + ${TEMP}/DeformableRegistration8Test1FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ${ITK_EXAMPLE_DATA_ROOT}/IdentityTransform.tfm + ) + set_property(TEST ITKv3DeformableRegistration8Test1 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test1 APPEND PROPERTY LABELS RUNS_LONG) + + itk_add_test(NAME ITKv3DeformableRegistration8Test2 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/DeformableRegistration8Test2.mhd + --compareNumberOfPixelsTolerance 700000 + --compareIntensityTolerance 15 + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test2.mhd + ${TEMP}/DeformableRegistration8Test2DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test2DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test2DisplacementField.mhd + 1 0 + ${TEMP}/DeformableRegistration8Test2FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ${ITK_EXAMPLE_DATA_ROOT}/IdentityTransform.tfm + ) + set_property(TEST ITKv3DeformableRegistration8Test2 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test2 APPEND PROPERTY LABELS RUNS_LONG) + + itk_add_test(NAME ITKv3DeformableRegistration8Test3 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/DeformableRegistration8Test3.mhd + --compareNumberOfPixelsTolerance 700000 + --compareIntensityTolerance 15 + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test3.mhd + ${TEMP}/DeformableRegistration8Test3DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test3DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test3DisplacementField.mhd + 0 1 + ${TEMP}/DeformableRegistration8Test3FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ${ITK_EXAMPLE_DATA_ROOT}/IdentityTransform.tfm + ) + set_property(TEST ITKv3DeformableRegistration8Test3 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test3 APPEND PROPERTY LABELS RUNS_LONG) + + itk_add_test(NAME ITKv3DeformableRegistration8Test4 COMMAND ${ITK_TEST_DRIVER} + --compare DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/DeformableRegistration8Test4.mhd + --compareNumberOfPixelsTolerance 700000 + --compareIntensityTolerance 15 + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test4.mhd + ${TEMP}/DeformableRegistration8Test4DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test4DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test4DisplacementField.mhd + 1 1 + ${TEMP}/DeformableRegistration8Test4FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ${ITK_EXAMPLE_DATA_ROOT}/IdentityTransform.tfm + ) + set_property(TEST ITKv3DeformableRegistration8Test4 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test4 APPEND PROPERTY LABELS RUNS_LONG) + + endif() # DART_TESTING_TIMEOUT GREATER 3000 + + if( "${ITK_COMPUTER_MEMORY_SIZE}" GREATER 6 ) + + set(NUMBER_OF_BSPLINE_GRID_NODES 32) + itk_add_test(NAME ITKv3DeformableRegistration8Test5 COMMAND ${ITK_TEST_DRIVER} + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test5.mhd + ${TEMP}/DeformableRegistration8Test5DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test5DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test5DisplacementField.mhd + 0 0 + ${TEMP}/DeformableRegistration8Test5FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ) + set_property(TEST ITKv3DeformableRegistration8Test5 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test5 APPEND PROPERTY LABELS RUNS_LONG) + + itk_add_test(NAME ITKv3DeformableRegistration8Test6 COMMAND ${ITK_TEST_DRIVER} + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test6.mhd + ${TEMP}/DeformableRegistration8Test6DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test6DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test6DisplacementField.mhd + 0 1 + ${TEMP}/DeformableRegistration8Test6FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ) + set_property(TEST ITKv3DeformableRegistration8Test6 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test6 APPEND PROPERTY LABELS RUNS_LONG) + + itk_add_test(NAME ITKv3DeformableRegistration8Test7 COMMAND ${ITK_TEST_DRIVER} + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test7.mhd + ${TEMP}/DeformableRegistration8Test7DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test7DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test7DisplacementField.mhd + 1 0 + ${TEMP}/DeformableRegistration8Test7FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ) + set_property(TEST ITKv3DeformableRegistration8Test7 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test7 APPEND PROPERTY LABELS RUNS_LONG) + + itk_add_test(NAME ITKv3DeformableRegistration8Test8 COMMAND ${ITK_TEST_DRIVER} + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test8.mhd + ${TEMP}/DeformableRegistration8Test8DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test8DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test8DisplacementField.mhd + 1 1 + ${TEMP}/DeformableRegistration8Test8FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ) + set_property(TEST ITKv3DeformableRegistration8Test8 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test8 APPEND PROPERTY LABELS RUNS_LONG) + + set(NUMBER_OF_BSPLINE_GRID_NODES 100) + itk_add_test(NAME ITKv3DeformableRegistration8Test9 COMMAND ${ITK_TEST_DRIVER} + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test9.mhd + ${TEMP}/DeformableRegistration8Test9DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test9DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test9DisplacementField.mhd + 0 0 + ${TEMP}/DeformableRegistration8Test9FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ) + set_property(TEST ITKv3DeformableRegistration8Test9 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test9 APPEND PROPERTY LABELS RUNS_LONG) + + itk_add_test(NAME ITKv3DeformableRegistration8Test10 COMMAND ${ITK_TEST_DRIVER} + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test10.mhd + ${TEMP}/DeformableRegistration8Test10DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test10DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test10DisplacementField.mhd + 0 1 + ${TEMP}/DeformableRegistration8Test10FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ) + set_property(TEST ITKv3DeformableRegistration8Test10 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test10 APPEND PROPERTY LABELS RUNS_LONG) + + # Due to the large memory requirements this tests must be run one by one + set_tests_properties( + DeformableRegistration8Test5 + DeformableRegistration8Test6 + DeformableRegistration8Test7 + DeformableRegistration8Test8 + DeformableRegistration8Test9 + DeformableRegistration8Test10 + PROPERTIES + RESOURCE_LOCK MEMORY_SIZE + ) + + if( "${ITK_COMPUTER_MEMORY_SIZE}" GREATER 16 ) + + itk_add_test(NAME ITKv3DeformableRegistration8Test11 COMMAND ${ITK_TEST_DRIVER} + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test11.mhd + ${TEMP}/DeformableRegistration8Test11DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test11DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test11DisplacementField.mhd + 1 0 + ${TEMP}/DeformableRegistration8Test11FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ) + set_property(TEST ITKv3DeformableRegistration8Test11 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test11 APPEND PROPERTY LABELS RUNS_LONG) + + itk_add_test(NAME ITKv3DeformableRegistration8Test12 COMMAND ${ITK_TEST_DRIVER} + $ + DATA{../../Data/BrainWeb/brainweb1e1a10f20.mha} + ${TEMP}/BSplineWarping2Test.mhd + ${TEMP}/DeformableRegistration8Test12.mhd + ${TEMP}/DeformableRegistration8Test12DifferenceAfter.mhd + ${TEMP}/DeformableRegistration8Test12DifferenceBefore.mhd + ${TEMP}/DeformableRegistration8Test12DisplacementField.mhd + 1 1 + ${TEMP}/DeformableRegistration8Test12FinalTransformParameters.txt + ${NUMBER_OF_BSPLINE_GRID_NODES} + ) + set_property(TEST ITKv3DeformableRegistration8Test12 PROPERTY DEPENDS BSplineWarping2Test) + set_property(TEST ITKv3DeformableRegistration8Test12 APPEND PROPERTY LABELS RUNS_LONG) + + # Due to the large memory requirements this tests lock the memory size resource + set_tests_properties( + DeformableRegistration8Test11 + DeformableRegistration8Test12 + PROPERTIES + RESOURCE_LOCK MEMORY_SIZE + ) + endif() # ITK_COMPUTER_MEMORY_SIZE GREATER 16 + + endif() # ITK_COMPUTER_MEMORY_SIZE GREATER 6 + +endif() # ITK_USE_BRAINWEB_DATA + +# This example in getting stuck and timing out, likely due to spatial +# object changes. +if (TEST_DISABLED) +itk_add_test(NAME ITKv3ImageRegistration12Test COMMAND ${ITK_TEST_DRIVER} + --compare DATA{${BASELINE}/ImageRegistration12TestPixelCentered.png} + ${TEMP}/ImageRegistration12TestPixelCentered.png + --compareNumberOfPixelsTolerance 2 + $ + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceR10X13Y17.png + ${ITK_EXAMPLE_DATA_ROOT}/BrainProtonDensitySliceBorder20Mask.png + ${TEMP}/ImageRegistration12TestPixelCentered.png +) +endif()