diff --git a/CMake/elxWinConfig.cmake b/CMake/elxWinConfig.cmake index c9a8eb734b8260f259e95fa5be4f6dd3605ea79d..6e2408335a8f8040c6f40e532f4d2286dc8e7760 100644 --- a/CMake/elxWinConfig.cmake +++ b/CMake/elxWinConfig.cmake @@ -1,19 +1,23 @@ # Visual Studio complains if paths are too long -string( LENGTH "${CMAKE_CURRENT_SOURCE_DIR}" n ) -if( n GREATER 50 ) -message( - FATAL_ERROR - "ITK source code directory path length is too long (${n} > 50)." - "Please move the ITK source code directory to a directory with a shorter path." - ) -endif() +if( MSVC ) + string( LENGTH "${CMAKE_CURRENT_SOURCE_DIR}" n ) + if( n GREATER 50 ) + message( + FATAL_ERROR + "ITK source code directory path length is too long for MSVC (${n} > 50)." + ) + endif() + + string( LENGTH "${CMAKE_CURRENT_BINARY_DIR}" n ) + if( n GREATER 50 ) + message( + FATAL_ERROR + "ITK build directory path length is too long for MSVC (${n} > 50)." + ) + endif() -string( LENGTH "${CMAKE_CURRENT_BINARY_DIR}" n ) -if( n GREATER 50 ) -message( - FATAL_ERROR - "ITK build directory path length is too long (${n} > 50)." - "Please set the ITK build directory to a directory with a shorter path." - ) + set( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /bigobj" ) + set( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /bigobj" ) + set( CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /bigobj" ) endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index c5a3e96f42343649c90a9bd5889ca4b03d978616..5f8add9d1a7234d12336d0a83aa682e1ac8ba748 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,46 +1,65 @@ cmake_minimum_required( VERSION 2.8 ) +# Explicitly add INCREMENTAL linking option to command lines. +# http://www.cmake.org/pipermail/cmake/2010-February/035174.html +set( MSVC_INCREMENTAL_DEFAULT ON ) + +# --------------------------------------------------------------------- +project( Elastix ) + # Include SuperElastix CMake scripts -list( APPEND CMAKE_MODULE_PATH - "${CMAKE_CURRENT_SOURCE_DIR}/CMake" +list( APPEND CMAKE_MODULE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/CMake" ) -if( CMAKE_HOST_WIN32 ) +if( ${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC" ) include( elxWinConfig.cmake ) endif() -#--------------------------------------------------------------------- -project( Elastix ) - -#--------------------------------------------------------------------- +# --------------------------------------------------------------------- # ITK find_package( ITK REQUIRED ) -set( ITK_NO_IO_FACTORY_REGISTER_MANAGER 1 ) include( ${ITK_USE_FILE} ) include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/elxITKRequiredModules.cmake" ) -#--------------------------------------------------------------------- +# --------------------------------------------------------------------- # Build Elastix -#--------------------------------------------------------------------- -# Testing +set( ELASTIX_COMMON_INCLUDE_DIRECTORIES + ${CMAKE_SOURCE_DIR}/Modules/Core/Common/include +) -# Build tests by default -option( ELASTIX_BUILD_TESTING "Enable building tests." ON ) +set( ELASTIX_CORE_INCLUDE_DIRECTORIES + ${CMAKE_SOURCE_DIR}/Modules/Core/Blueprints/include +) + +set( ELASTIX_INCLUDE_DIRECTORIES + ${ELASTIX_COMMON_INCLUDE_DIRECTORIES} + ${ELASTIX_CORE_INCLUDE_DIRECTORIES} +) + +include_directories( ${ELASTIX_INCLUDE_DIRECTORIES} ) +add_subdirectory( Modules ) + +# --------------------------------------------------------------------- +# Testing -# ExternalData module requires newer CMake versions +# Testing requires CMake version 2.8.11 to download test data if( CMAKE_VERSION VERSION_LESS 2.8.11 ) - set( ELASTIX_BUILD_TESTING OFF FORCE ) - message( STATUS "ELASTIX_BUILD_TESTING was set to OFF because CMake version is less than 2.8.11") + set( ELASTIX_BUILD_TESTING_DEFAULT OFF ) + message( STATUS "ELASTIX_BUILD_TESTING is set to OFF because CMake version is less than 2.8.11" ) +else() + set( ELASTIX BUILD_TESTING_DEFAULT ON ) endif() -if( ELASTIX_BUILD_TESTING ) +option( ELASTIX_BUILD_TESTING "Enable building tests." ${ELASTIX_BUILD_TESTING_DEFAULT} ) +if( ${ELASTIX_BUILD_TESTING} ) enable_testing() add_subdirectory( Testing ) endif() -#--------------------------------------------------------------------- +# --------------------------------------------------------------------- # Build Documentation mark_as_advanced( ELASTIX_BUILD_DOXYGEN ) diff --git a/Modules/CMakeLists.txt b/Modules/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3c6212d3542a67000d0091ff33a596e2e739a74c --- /dev/null +++ b/Modules/CMakeLists.txt @@ -0,0 +1,3 @@ +add_subdirectory( + Core +) diff --git a/Modules/Core/Blueprints/CMakeLists.txt b/Modules/Core/Blueprints/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Modules/Core/CMakeLists.txt b/Modules/Core/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..84c12fcb3aba7189c16706bc6a7affdded2175ca --- /dev/null +++ b/Modules/Core/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory( Common ) +add_subdirectory( Blueprints ) diff --git a/Modules/Core/Common/CMakeLists.txt b/Modules/Core/Common/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b83cfce3b85bc48c4c713194051c1e70655c7a95 --- /dev/null +++ b/Modules/Core/Common/CMakeLists.txt @@ -0,0 +1 @@ +include_directories( include ) diff --git a/Modules/Core/Common/include/elxMacro.h b/Modules/Core/Common/include/elxMacro.h new file mode 100644 index 0000000000000000000000000000000000000000..15f63f9ee33b2af82f4136af788092f07e9e3095 --- /dev/null +++ b/Modules/Core/Common/include/elxMacro.h @@ -0,0 +1,15 @@ +#ifndef __elxMacro_h +#define __elxMacro_h + +/** + * Register class with the object factory and set RTTI (Run-Time Type + * Information) + */ +#define elxNewMacro( className, superClassName ) \ + typedef className Self; \ + typedef itk::SmartPointer< Self > Pointer; \ + typedef itk::SmartPointer< const Self > ConstPointer; \ + itkNewMacro( Self ); \ + itkTypeMacro( Self, superClassName ); \ + +#endif // __elxMacro_h \ No newline at end of file diff --git a/Testing/Benchmark/BSplineRegistration.cxx b/Testing/Benchmark/BSplineRegistration.cxx deleted file mode 100644 index 8a8a73b44e539e6ffb30806b08346f47a92256dd..0000000000000000000000000000000000000000 --- a/Testing/Benchmark/BSplineRegistration.cxx +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Benchmarking multi-resolution non-rigid b-spline registration - * with mutual information in ITK, Elastix and ANTs - */ - -#include "itkImage.h" -#include "itkImageFileReader.h" -#include "itkImageFileWriter.h" - -// DeformableRegistration1 -#include "itkRescaleIntensityImageFilter.h" -#include "itkHistogramMatchingImageFilter.h" -#include "itkFEMRegistrationFilter.h" - -#include "gtest/gtest.h" - -class itkExamples : public ::testing::Test -{ -protected: - - virtual void SetUp() - { - const char *fixedImageName, *movingImageName; - if ( argc < 2 ) - { - std::cout << "Image filenames missing." << std::endl; - std::cout << "Usage: " << argv[0] << " fixedImageFilename movingImageFilename" - << std::endl; - return EXIT_FAILURE; - } - else - { - fixedImageFilename = argv[1]; - movingImageFilename = argv[2]; - } - } - -}; - -TEST_F( BSplineRegistration, ITK ) { - - const unsigned int ImageDimension = 2; - typedef unsigned char PixelType; - typedef itk::Image< PixelType, ImageDimension > ImageType; - - const unsigned int SplineOrder = 3; - typedef double CoordinateRepType; - - // Transform - typedef itk::BSplineDeformableTransform< CoordinateRepType, - SpaceDimension, - SplineOrder > TransformType; - - typedef TransformType::RegionType RegionType; - RegionType bsplineRegion; - RegionType::SizeType gridSizeOnImage; - RegionType::SizeType gridBorderSize; - RegionType::SizeType totalGridSize; - - gridSizeOnImage.Fill( 5 ); - gridBorderSize.Fill( 3 ); // Border for spline order = 3 ( 1 lower, 2 upper ) - totalGridSize = gridSizeOnImage + gridBorderSize; - - bsplineRegion.SetSize( totalGridSize ); - - typedef TransformType::SpacingType SpacingType; - SpacingType spacing = fixedImage->GetSpacing(); - - typedef TransformType::OriginType OriginType; - OriginType origin = fixedImage->GetOrigin(); - - ImageType::SizeType fixedImageSize = fixedRegion.GetSize(); - - for(unsigned int r=0; r<ImageDimension; r++) - { - spacing[r] *= static_cast<double>(fixedImageSize[r] - 1) / - static_cast<double>(gridSizeOnImage[r] - 1); - } - - ImageType::DirectionType gridDirection = fixedImage->GetDirection(); - SpacingType gridOriginOffset = gridDirection * spacing; - - OriginType gridOrigin = origin - gridOriginOffset; - - transform->SetGridSpacing( spacing ); - transform->SetGridOrigin( gridOrigin ); - transform->SetGridRegion( bsplineRegion ); - transform->SetGridDirection( gridDirection ); - - typedef TransformType::ParametersType ParametersType; - const unsigned int numberOfParameters = transform->GetNumberOfParameters(); - ParametersType parameters( numberOfParameters ); - parameters.Fill( 0.0 ); - transform->SetParameters( parameters ); - - // Optimizer - typedef itk::LBFGSOptimizer OptimizerType; - - optimizer->SetGradientConvergenceTolerance( 0.05 ); - optimizer->SetLineSearchAccuracy( 0.9 ); - optimizer->SetDefaultStepLength( .5 ); - optimizer->TraceOn(); - optimizer->SetMaximumNumberOfFunctionEvaluations( 1024 ); - - // Metric - typedef itk::MeanSquaresImageToImageMetric< ImageType, - ImageType > MetricType; - - // Interpolator - typedef itk:: LinearInterpolateImageFunction< ImageType, - double > InterpolatorType; - - // Setup the registration - typedef itk::ImageRegistrationMethod< ImageType, - ImageType > RegistrationType; - - RegistrationType::Pointer registration = RegistrationType::New(); - registration->SetNumberOfThreads( 1 ); - registration->SetMetric( MetricType::New() ); - registration->SetOptimizer( OptimizerType::New() ); - registration->SetInterpolator( InterpolatorType::New() ); - - TransformType::Pointer transform = TransformType::New(); - registration->SetTransform( transform ); - - registration->SetFixedImage( fixedImage ); - registration->SetMovingImage( movingImage ); - - ImageType::RegionType fixedRegion = fixedImage->GetBufferedRegion(); - registration->SetFixedImageRegion( fixedRegion ); - - registration->SetInitialTransformParameters( transform->GetParameters() ); - - // Execute - EXPECT_NO_THROW( registration->Update() ); - -} \ No newline at end of file diff --git a/Testing/Benchmark/CMakeLists.txt b/Testing/Benchmark/CMakeLists.txt deleted file mode 100644 index 3004ccdf3e61caabdafab9c49e78855cd53ab8e7..0000000000000000000000000000000000000000 --- a/Testing/Benchmark/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -# -set( GTEST_OPTIONS - -gtest_output -) - -#--------------------------------------------------------------------- -# To add a benchmark to the build system, append it to the list below. -# Any GoogleTests in these files are automatically added to CTest. - -set( ElastixBenchmarkSource - elxExampleBenchmark.cxx -) - -#--------------------------------------------------------------------- -# To add data to a benchmark, create a list "${filename}Data" (without -# the filename extension) and add data to this list. - -set( elxExampleBenchmarkData - DATA{Testing/Data/Input/BrainProtonDensitySlice.png} - DATA{Testing/Data/Input/BrainProtonDensitySliceR10X13Y17.png} -) - -#--------------------------------------------------------------------- -# Build executables - -foreach( ElastixBenchmarkFilename ${ElastixBenchmarkSource} ) - string( REPLACE ".cxx" "" ElastixBenchmark ${ElastixBenchmarkFilename} ) - add_executable( ${ElastixBenchmark} ${ElastixBenchmarkFilename} ) - target_link_libraries( ${ElastixBenchmark} ${ELASTIX_LIBRARIES} ${ITK_LIBRARIES} ${TEST_LIBRARIES} ) - - ExternalData_Add_Test( "${ElastixBenchmark}ExternalDataTarget" - NAME ${ElastixBenchmark} - COMMAND "${ElastixBenchmark} ${${ElastixBenchmarkTest}Data} ${GTEST_OPTIONS}" - ) - - ExternalData_Add_Target( "${ElastixBenchmark}ExternalDataTarget"} ) -endforeach() diff --git a/Testing/CMakeLists.txt b/Testing/CMakeLists.txt index ea6d3697c6ed80937d7202666712bfc5954c3ad1..9598ac8c17113e6a582022ec82d0d1b53eef530e 100644 --- a/Testing/CMakeLists.txt +++ b/Testing/CMakeLists.txt @@ -30,7 +30,7 @@ endforeach() ExternalData_Add_Target( ElastixData ) # --------------------------------------------------------------------- -# Setup GoogleTest +# Add GoogleTest find_package( Git ) if( NOT EXISTS "${CMAKE_SOURCE_DIR}/Testing/GoogleTest/.git" AND GIT_EXECUTABLE ) @@ -70,7 +70,6 @@ add_subdirectory( Unit ) # Benchmarks option( ELASTIX_BUILD_BENCHMARKING "Enable building benchmarks." OFF ) - if( ${ELASTIX_BUILD_BENCHMARKING} ) add_subdirectory( Benchmark ) endif() diff --git a/Testing/Dashboard/CMakeLists.txt b/Testing/Dashboard/CMakeLists.txt index 244b8d862e71723c82cb1539df163350ade6a0fe..202478325aeea62261d1c8dd11773e54eb1ba132 100644 --- a/Testing/Dashboard/CMakeLists.txt +++ b/Testing/Dashboard/CMakeLists.txt @@ -8,24 +8,23 @@ mark_as_advanced( ELASTIX_DASHBOARD_BINARY_DIR ) set( ELASTIX_DASHBOARD_BINARY_DIR "${CMAKE_BINARY_DIR}/Testing/Dashboard" ) mark_as_advanced( ELASTIX_DASHBOARD_LOGSTASH_CERTIFICATE ) -set( ELASTIX_DASHBOARD_LOGSTASH_CERTIFICATE "elxLogstashForwarder.crt" ) +set( ELASTIX_DASHBOARD_LOGSTASH_CERTIFICATE "elxLogstash.crt" ) mark_as_advanced( ELASTIX_DASHBOARD_LOGSTASH_RSA_PRIVATE_KEY ) -set( ELASTIX_DASHBOARD_LOGSTASH_RSA_PRIVATE_KEY "elxLogstashForwarder.key" ) +set( ELASTIX_DASHBOARD_LOGSTASH_RSA_PRIVATE_KEY "elxLogstash.key" ) mark_as_advanced( ELASTIX_DASHBOARD_VOLUME ) -set( ELASTIX_DASHBOARD_VOLUME "${ELASTIX_DASHBOARD_BINARY_DIR}/Data" ) - if( NOT EXISTS "${ELASTIX_DASHBOARD_VOLUME}" ) message( STATUS - "ELASTIX_DASHBOARD_VOLUME points to the default ${CMAKE_BINARY_DIR}/Testing/Dashboard/Data path in your build directory. In production you should point this variable to a safe directory outside the build tree." + "ELASTIX_DASHBOARD_VOLUME points to the folder ${CMAKE_BINARY_DIR}/Testing/Dashboard/Data in your build directory. In production you should point this variable to a safe directory outside the build tree." ) - + + set( ELASTIX_DASHBOARD_VOLUME "${ELASTIX_DASHBOARD_BINARY_DIR}/Data" ) file( MAKE_DIRECTORY "${ELASTIX_DASHBOARD_VOLUME}" ) endif() # Test/Benchmark results will be forwarded to this IP. You will probably -# have change this in order to match docker settings on your own machine. +# have change this in order to match docker settings on your own machine. mark_as_advanced( ELASTIX_DASHBOARD_IP ) set( ELASTIX_DASHBOARD_IP "192.168.59.103" ) diff --git a/Testing/Dashboard/elxLogstashForwarder.crt b/Testing/Dashboard/elxLogstash.crt similarity index 100% rename from Testing/Dashboard/elxLogstashForwarder.crt rename to Testing/Dashboard/elxLogstash.crt diff --git a/Testing/Dashboard/elxLogstashForwarder.key b/Testing/Dashboard/elxLogstash.key similarity index 100% rename from Testing/Dashboard/elxLogstashForwarder.key rename to Testing/Dashboard/elxLogstash.key diff --git a/Testing/Unit/CMakeLists.txt b/Testing/Unit/CMakeLists.txt index 17d66ca7225d3a1e017d817ac8d8e7c40d11be70..152463661b386eebef9985f5071fa38a1f427f9e 100644 --- a/Testing/Unit/CMakeLists.txt +++ b/Testing/Unit/CMakeLists.txt @@ -24,19 +24,24 @@ if( NOT EXISTS ${ELASTIX_UNITTEST_OUTPUT_DATA_DIR} ) ) endif() +# --------------------------------------------------------------------- +# Build test data manager configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/elxDataDirectories.h.in - ${CMAKE_CURRENT_SOURCE_DIR}/elxDataDirectories.h + ${CMAKE_CURRENT_BINARY_DIR}/elxDataDirectories.h ESCAPE_QUOTES ) -# Build tests +include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) + add_library( DataManager elxDataManager.cxx ) list( APPEND TEST_LIBRARIES DataManager ) +# --------------------------------------------------------------------- +# Build tests foreach( ElastixUnitTestFilename ${ElastixUnitTestFilenames} ) # Build tests executables string( REPLACE ".cxx" "" ElastixUnitTest ${ElastixUnitTestFilename} ) diff --git a/Testing/Unit/elxDataDirectories.h.in b/Testing/Unit/elxDataDirectories.h.in index 835845d15b56febeb9f8d8ca19b81b8a344555b3..2081964057c33d7647da456782aff3e956135efd 100644 --- a/Testing/Unit/elxDataDirectories.h.in +++ b/Testing/Unit/elxDataDirectories.h.in @@ -1,5 +1,5 @@ -#ifndef __elxTestDataDirectories_h -#define __elxTestDataDirectories_h +#ifndef __elxDataDirectories_h +#define __elxDataDirectories_h #define ELASTIX_UNITTEST_INPUT_DATA_DIR "@ELASTIX_UNITTEST_INPUT_DATA_DIR@" #define ELASTIX_UNITTEST_OUTPUT_DATA_DIR "@ELASTIX_UNITTEST_OUTPUT_DATA_DIR@" diff --git a/Testing/Unit/elxDataManager.cxx b/Testing/Unit/elxDataManager.cxx index e9aa4e4afd6f58cc26420fdd947bfbc29817cae9..6b7da8aa318a592f9ff654404d5412f93d829dd5 100644 --- a/Testing/Unit/elxDataManager.cxx +++ b/Testing/Unit/elxDataManager.cxx @@ -1,29 +1,30 @@ #ifndef __DataManager_cxx #define __DataManager_cxx +#include <itkSimpleDataObjectDecorator.h> #include "elxDataManager.h" -std::string +const std::string DataManager -::GetInput( const std::string filename ) const +::GetInputFullPath( const std::string filename ) const { - const std::string path = this->GetInputDirectory() + this->GetPathSeparator() + filename; + const std::string path = this->GetInputDirectory() + this->GetFolderSeparator() + filename; return path; } -std::string +const std::string DataManager -::GetOutput( const std::string filename ) const +::GetOutputFullPath( const std::string filename ) const { - const std::string path = this->GetOutputDirectory() + this->GetPathSeparator() + filename; + const std::string path = this->GetOutputDirectory() + this->GetFolderSeparator() + filename; return path; } -std::string +const std::string DataManager -::GetBaseline( const std::string filename ) const +::GetBaselineFullPath( const std::string filename ) const { - const std::string path = this->GetBaselineDirectory() + this->GetPathSeparator() + filename; + const std::string path = this->GetBaselineDirectory() + this->GetFolderSeparator() + filename; return path; } diff --git a/Testing/Unit/elxDataManager.h b/Testing/Unit/elxDataManager.h index 61d4dcade79545c7c85210f663d9ca07390e3f5c..fc85a65c4a30c00d979a10aa6b7a464ba2481937 100644 --- a/Testing/Unit/elxDataManager.h +++ b/Testing/Unit/elxDataManager.h @@ -2,16 +2,19 @@ #define __DataManager_h #include <string> +#include <itkSimpleDataObjectDecorator.h> -#include "itkMacro.h" -#include "itkProcessObject.h" - +#include "elxMacro.h" +#include "itkObjectFactory.h" +#include "itkLightObject.h" #include "elxDataDirectories.h" -class DataManager +class DataManager : public itk::LightObject { public: + elxNewMacro( DataManager, itk::LightObject ); + DataManager() { this->m_InputDirectory = ELASTIX_UNITTEST_INPUT_DATA_DIR; @@ -20,16 +23,25 @@ public: } std::string GetInputDirectory( void ) const { return this->m_InputDirectory; }; - std::string GetOutputDirectory( void ) const { return this->m_InputDirectory; }; - std::string GetBaselineDirectory( void ) const { return this->m_InputDirectory; }; + std::string GetOutputDirectory( void ) const { return this->m_OutputDirectory; }; + std::string GetBaselineDirectory( void ) const { return this->m_BaselineDirectory; }; + + const std::string GetInputFullPath( const std::string filename ) const; + const std::string GetOutputFullPath( const std::string filename ) const; + const std::string GetBaselineFullPath( const std::string filename ) const; - std::string GetInput( const std::string filename ) const; - std::string GetOutput( const std::string filename ) const; - std::string GetBaseline( const std::string filename ) const; + std::string GetFolderSeparator() const + { +#ifdef _WIN32 + return "\\"; +#else + return "/"; +#endif + } std::string GetPathSeparator () const { -#ifdef WIN32 +#ifdef _WIN32 return ";"; #else return ":"; diff --git a/Testing/Unit/itkRegistration.cxx b/Testing/Unit/itkRegistration.cxx index 449ed7bd286373d1d15e2d5769b6ccf9b16d3715..3988f3089daaff475b4d1a4b359286d75eb6995d 100644 --- a/Testing/Unit/itkRegistration.cxx +++ b/Testing/Unit/itkRegistration.cxx @@ -3,27 +3,84 @@ #include "elxDataManager.h" #include "gtest/gtest.h" +#include "itkImageRegistrationMethod.h" +#include "itkTranslationTransform.h" +#include "itkMeanSquaresImageToImageMetric.h" +#include "itkLinearInterpolateImageFunction.h" +#include "itkRegularStepGradientDescentOptimizer.h" +#include "itkImage.h" +#include "itkImageFileReader.h" +#include "itkResampleImageFilter.h" +#include "itkCastImageFilter.h" + class itkRegistration : public ::testing::Test { public: virtual void SetUp() { - DataManager dataManager; - typedef itk::ImageFileReader< ImageType > ReaderType; + // TODO: Loading images here result in segfault + } - ReaderType::Pointer reader = ReaderType::New(); - reader->SetFileName( dataManager.GetInput( "BrainProtonDensitySliceR10X13Y17.png" ) ); - inputImage = reader->GetOutput(); + typedef itk::Image< unsigned short, 2 > ImageType; - reader->SetFileName( dataManager.GetBaseline( "BrainProtonDensitySlice.png" ) ); - baselineImage = reader->GetOutput(); - } + typedef itk::ImageFileReader< ImageType > FixedImageReaderType; + typedef itk::ImageFileReader< ImageType > MovingImageReaderType; + + FixedImageReaderType::Pointer fixedImageReader; + MovingImageReaderType::Pointer movingImageReader; - typedef itk::Image< unsigned int, 2 > ImageType; - ImageType::Pointer inputImage; - ImageType::Pointer baselineImage; }; -TEST_F( itkRegistration, Affine2D ) -{ - ASSERT_TRUE( true ); +TEST_F( itkRegistration, ImageRegistration3 ) +{ + + typedef itk::TranslationTransform< double, ImageType::ImageDimension > TransformType; + typedef itk::RegularStepGradientDescentOptimizer OptimizerType; + typedef itk::LinearInterpolateImageFunction< ImageType, double > InterpolatorType; + typedef itk::ImageRegistrationMethod< ImageType, ImageType > RegistrationType; + + + typedef itk::MeanSquaresImageToImageMetric< ImageType, ImageType > MetricType; + + 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->SetMetric( metric ); + registration->SetOptimizer( optimizer ); + registration->SetTransform( transform ); + registration->SetInterpolator( interpolator ); + + FixedImageReaderType::Pointer fixedImageReader = FixedImageReaderType::New(); + MovingImageReaderType::Pointer movingImageReader = MovingImageReaderType::New(); + + DataManager::Pointer dataManager = DataManager::New(); + + fixedImageReader->SetFileName( dataManager->GetInputFullPath( "BrainProtonDensitySlice.png" ) ); + movingImageReader->SetFileName( dataManager->GetInputFullPath( "BrainProtonDensitySliceR10X13Y17.png" ) ); + + registration->SetFixedImage( fixedImageReader->GetOutput() ); + registration->SetMovingImage( movingImageReader->GetOutput() ); + + fixedImageReader->Update(); // This is needed to make the BufferedRegion valid. + registration->SetFixedImageRegion( fixedImageReader->GetOutput()->GetBufferedRegion() ); + + typedef RegistrationType::ParametersType 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->SetNumberOfIterations( 200 ); + + optimizer->MaximizeOff(); + + EXPECT_NO_THROW( registration->Update() ); + RecordProperty( "MetricValue", optimizer->GetValue() ); } +