diff --git a/CMakeLists.txt b/CMakeLists.txt index ec355d9a9510d0d968a5e95d38296e604f04b1ec..a50193ad594d9bb936e834a77c47dc9b5a60c8b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ include( "${CMAKE_CURRENT_SOURCE_DIR}/CMake/elxRequiredITKModules.cmake" ) option( ELASTIX_BUILD_TESTING "Enable building tests." OFF ) if( ELASTIX_BUILD_TESTING ) + option( ELASTIX_BUILD_BENCHMARKING "Enable building benchmarks." OFF ) enable_testing() add_subdirectory( Testing ) endif() diff --git a/SuperBuild/CMakeLists.txt b/SuperBuild/CMakeLists.txt index 12a9ed5a81673f264179d485fe593116bf538361..15dd3d89cc2f18552308fb78f3b85534d2485a52 100644 --- a/SuperBuild/CMakeLists.txt +++ b/SuperBuild/CMakeLists.txt @@ -29,8 +29,7 @@ option( ELASTIX_BUILD_EXAMPLES "Enable building examples." ON ) option( ELASTIX_BUILD_TESTING "Enable building tests." ON ) if( ELASTIX_BUILD_TESTING ) - mark_as_advanced( ELASTIX_BUILD_CTESTS ) - option( ELASTIX_BUILD_CTESTS "Enable CTests." OFF ) + option( ELASTIX_BUILD_BENCHMARKING "Enable building benchmarks." ON ) endif() #--------------------------------------------------------------------- diff --git a/SuperBuild/Elastix.cmake b/SuperBuild/Elastix.cmake index 130f5595e11ee400642750827c814c3604e48761..6afad9403207d2074137c492e6a54bb2d37c28d7 100644 --- a/SuperBuild/Elastix.cmake +++ b/SuperBuild/Elastix.cmake @@ -8,7 +8,7 @@ ExternalProject_Add( ${proj} CMAKE_ARGS --no-warn-unused-cli -DELASTIX_BUILD_TESTING:BOOL=${ELASTIX_BUILD_TESTING} - -DELASTIX_BUILD_CTESTS:BOOL=${ELASTIX_BUILD_CTESTS} + -DELASTIX_BUILD_BENCHMARKING:BOOL=${ELASTIX_BUILD_BENCHMARKING} -DITK_DIR:PATH=${ITK_DIR} DEPENDS ${ELASTIX_DEPENDENCIES} INSTALL_COMMAND "" diff --git a/Testing/Benchmark/BSplineRegistration.cxx b/Testing/Benchmark/BSplineRegistration.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8a8a73b44e539e6ffb30806b08346f47a92256dd --- /dev/null +++ b/Testing/Benchmark/BSplineRegistration.cxx @@ -0,0 +1,137 @@ +/** + * 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 new file mode 100644 index 0000000000000000000000000000000000000000..3004ccdf3e61caabdafab9c49e78855cd53ab8e7 --- /dev/null +++ b/Testing/Benchmark/CMakeLists.txt @@ -0,0 +1,37 @@ +# +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 7343cdc14ac9e8409922e978b081018ef3f539b8..30ddd1ec093b16e0242510cb49da8395166adebc 100644 --- a/Testing/CMakeLists.txt +++ b/Testing/CMakeLists.txt @@ -20,14 +20,6 @@ set( TEST_LIBRARIES gtest_main ) -#--------------------------------------------------------------------- -# To add a test to the build system, append it to the list below. -# Any GoogleTests in these files are automatically added to CTest. - -set( ElastixUnitTestSource - elxExampleTest.cxx -) - #--------------------------------------------------------------------- # Setup ExternalData @@ -42,26 +34,10 @@ list( APPEND ExternalData_URL_TEMPLATES ) #--------------------------------------------------------------------- -# To add data to a tests, create a list "${filename}Data" (without -# the filename extension) and add data to this list. - -set( elxExampleTestData - DATA{Data/Input/BrainProtonDensitySliceR10X13Y17.png} -) - -#--------------------------------------------------------------------- -# Build test executables - -foreach( ElastixUnitTestFilename ${ElastixUnitTestSource} ) - string( REPLACE ".cxx" "" ElastixUnitTest ${ElastixUnitTestFilename} ) - add_executable( ${ElastixUnitTest} ${ElastixUnitTestFilename} ) - target_link_libraries( ${ElastixUnitTest} ${ELASTIX_LIBRARIES} ${ITK_LIBRARIES} ${TEST_LIBRARIES} ) - - ExternalData_Add_Test( "${ElastixUnitTest}ExternalDataTarget" - NAME ${ElastixUnitTest} - COMMAND ${ElastixUnitTest} ${${ElastixUnitTest}Data} - ) - - ExternalData_Add_Target( "${ElastixUnitTest}ExternalDataTarget"} ) -endforeach() +# Include tests +add_subdirectory( Unit ) +# Include benchmarks +if( ${ELASTIX_BUILD_BENCHMARKING} ) + add_subdirectory( Benchmark ) +endif() diff --git a/Testing/Data/Input/BrainProtonDensitySlice.png.md5 b/Testing/Data/Input/BrainProtonDensitySlice.png.md5 new file mode 100644 index 0000000000000000000000000000000000000000..317f8a125578f6b03363ddc5c3ff4ce81209960e --- /dev/null +++ b/Testing/Data/Input/BrainProtonDensitySlice.png.md5 @@ -0,0 +1 @@ +073df8eb397d1746d2343c78dd4bd964 \ No newline at end of file diff --git a/Testing/Unit/CMakeLists.txt b/Testing/Unit/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..964055b2590a407b7ae5928b51025faf9cc563bb --- /dev/null +++ b/Testing/Unit/CMakeLists.txt @@ -0,0 +1,31 @@ +#--------------------------------------------------------------------- +# To add a test to the build system, append it to the list below. +# Any GoogleTests in these files are automatically added to CTest. + +set( ElastixUnitTestSource + elxExampleUnitTest.cxx +) + +#--------------------------------------------------------------------- +# To add data to a tests, create a list "${filename}Data" (without +# the filename extension) and add data to this list. + +set( elxExampleTestData + DATA{${CMAKE_BINARY_DIR}/Testing/Data/Input/BrainProtonDensitySliceR10X13Y17.png} +) + +#--------------------------------------------------------------------- +# Build test executables + +foreach( ElastixUnitTestFilename ${ElastixUnitTestSource} ) + string( REPLACE ".cxx" "" ElastixUnitTest ${ElastixUnitTestFilename} ) + add_executable( ${ElastixUnitTest} ${ElastixUnitTestFilename} ) + target_link_libraries( ${ElastixUnitTest} ${ELASTIX_LIBRARIES} ${ITK_LIBRARIES} ${TEST_LIBRARIES} ) + + ExternalData_Add_Test( "${ElastixUnitTest}ExternalDataTarget" + NAME ${ElastixUnitTest} + COMMAND ${ElastixUnitTest} ${${ElastixUnitTest}Data} + ) + + ExternalData_Add_Target( "${ElastixUnitTest}ExternalDataTarget"} ) +endforeach() \ No newline at end of file diff --git a/Testing/elxExampleTest.cxx b/Testing/Unit/elxExampleUnitTest.cxx similarity index 100% rename from Testing/elxExampleTest.cxx rename to Testing/Unit/elxExampleUnitTest.cxx