From 99cd8dd7b4e408705b457605c0b7298d414c44bb Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Thu, 30 Aug 2018 13:05:31 +0200 Subject: [PATCH 01/11] ENH: Method to compute InputRequestedRegion in itkResampleImageFilter based on suggestions from: https://discourse.itk.org/t/why-resampleimagefilter-is-slow/1217/14 https://itk.org/pipermail/insight-users/2015-April/051877.html and code from itkImageAlgorithm of v4.13.1 (based on commit 8510db2df6606837126486c47aba58f0c278b801) --- .../include/itkResampleImageFilter.hxx | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx b/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx index f678a1cbfdd..6f15f182a92 100644 --- a/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx +++ b/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx @@ -495,7 +495,65 @@ ResampleImageFilter< TInputImage, TOutputImage, TInterpolatorPrecisionType, TTra InputImagePointer inputPtr = const_cast< TInputImage * >( this->GetInput() ); - // Determining the actual input region is non-trivial, especially + + // Check whether the input or the output is a + // SpecialCoordinatesImage. If either are, then we cannot use the + // fast path since index mapping will definitely not be linear. + typedef SpecialCoordinatesImage< PixelType, ImageDimension > OutputSpecialCoordinatesImageType; + typedef SpecialCoordinatesImage< InputPixelType, InputImageDimension > InputSpecialCoordinatesImageType; + + const bool isSpecialCoordinatesImage = ( dynamic_cast< const InputSpecialCoordinatesImageType * >( this->GetInput() ) + || dynamic_cast< const OutputSpecialCoordinatesImageType * >( this->GetOutput() ) ); + + OutputImageType *outputPtr = this->GetOutput(); + // Get the input transform + const TransformType *transformPtr = this->GetTransform(); + + // Check whether we can use upstream streaming for resampling. Upstream streaming + // can be used if the transformation is linear. Transform respond + // to the IsLinear() call. + if ( !isSpecialCoordinatesImage && transformPtr->GetTransformCategory() == TransformType::Linear ) + { + typename TOutputImage::RegionType outputLargestPossibleRegion; + outputLargestPossibleRegion = outputPtr->GetRequestedRegion(); + + // Define a few indices that will be used to translate from an input pixel + // to an output pixel + PointType outputPoint; // Coordinates of current output pixel + PointType inputPoint; // Coordinates of current input pixel + + ContinuousInputIndexType contInputIndex; + + typename TInputImage::RegionType inputRequestedRegion; + typename TInputImage::IndexType inputIndex; + + // Determine the floor of the current output index + outputPtr->TransformIndexToPhysicalPoint(outputLargestPossibleRegion.GetIndex(), outputPoint); + // Compute corresponding input pixel position + inputPoint = transformPtr->TransformPoint(outputPoint); + inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, contInputIndex); + for (unsigned int dim=0; dim < OutputImageType::ImageDimension; ++dim) + { + inputIndex[dim] = Math::Floor( contInputIndex[dim] ); + } + inputRequestedRegion.SetIndex( inputIndex ); + + // Determine the ceil of the current output upper index + outputPtr->TransformIndexToPhysicalPoint(outputLargestPossibleRegion.GetUpperIndex(), outputPoint); + // Compute corresponding input pixel position + inputPoint = transformPtr->TransformPoint(outputPoint); + inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, contInputIndex); + for (unsigned int dim=0; dim < OutputImageType::ImageDimension; ++dim) + { + inputIndex[dim] = Math::Ceil( contInputIndex[dim] ); + } + inputRequestedRegion.SetUpperIndex( inputIndex ); + + inputPtr->SetRequestedRegion( inputRequestedRegion ); + return; + } + + // Otherwise, determining the actual input region is non-trivial, especially // when we cannot assume anything about the transform being used. // So we do the easy thing and request the entire input image. // From 9b435b9dd5a970b89361842627c7880f00c20228 Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Tue, 25 Sep 2018 14:07:50 +0200 Subject: [PATCH 02/11] ENH: use ImageAlgorithm::EnlargeRegionOverBox instead --- .../include/itkResampleImageFilter.hxx | 43 +++---------------- 1 file changed, 7 insertions(+), 36 deletions(-) diff --git a/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx b/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx index 6f15f182a92..ebb0c65ccbb 100644 --- a/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx +++ b/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx @@ -26,6 +26,7 @@ #include "itkImageScanlineIterator.h" #include "itkSpecialCoordinatesImage.h" #include "itkDefaultConvertPixelTraits.h" +#include "itkImageAlgorithm.h" namespace itk { @@ -492,8 +493,8 @@ ResampleImageFilter< TInputImage, TOutputImage, TInterpolatorPrecisionType, TTra } // Get pointers to the input and output - InputImagePointer inputPtr = - const_cast< TInputImage * >( this->GetInput() ); + InputImageType * inputPtr = + const_cast< InputImageType * >( this->GetInput() ); // Check whether the input or the output is a @@ -505,7 +506,7 @@ ResampleImageFilter< TInputImage, TOutputImage, TInterpolatorPrecisionType, TTra const bool isSpecialCoordinatesImage = ( dynamic_cast< const InputSpecialCoordinatesImageType * >( this->GetInput() ) || dynamic_cast< const OutputSpecialCoordinatesImageType * >( this->GetOutput() ) ); - OutputImageType *outputPtr = this->GetOutput(); + const OutputImageType *outputPtr = this->GetOutput(); // Get the input transform const TransformType *transformPtr = this->GetTransform(); @@ -514,40 +515,10 @@ ResampleImageFilter< TInputImage, TOutputImage, TInterpolatorPrecisionType, TTra // to the IsLinear() call. if ( !isSpecialCoordinatesImage && transformPtr->GetTransformCategory() == TransformType::Linear ) { - typename TOutputImage::RegionType outputLargestPossibleRegion; - outputLargestPossibleRegion = outputPtr->GetRequestedRegion(); - - // Define a few indices that will be used to translate from an input pixel - // to an output pixel - PointType outputPoint; // Coordinates of current output pixel - PointType inputPoint; // Coordinates of current input pixel - - ContinuousInputIndexType contInputIndex; - typename TInputImage::RegionType inputRequestedRegion; - typename TInputImage::IndexType inputIndex; - - // Determine the floor of the current output index - outputPtr->TransformIndexToPhysicalPoint(outputLargestPossibleRegion.GetIndex(), outputPoint); - // Compute corresponding input pixel position - inputPoint = transformPtr->TransformPoint(outputPoint); - inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, contInputIndex); - for (unsigned int dim=0; dim < OutputImageType::ImageDimension; ++dim) - { - inputIndex[dim] = Math::Floor( contInputIndex[dim] ); - } - inputRequestedRegion.SetIndex( inputIndex ); - - // Determine the ceil of the current output upper index - outputPtr->TransformIndexToPhysicalPoint(outputLargestPossibleRegion.GetUpperIndex(), outputPoint); - // Compute corresponding input pixel position - inputPoint = transformPtr->TransformPoint(outputPoint); - inputPtr->TransformPhysicalPointToContinuousIndex(inputPoint, contInputIndex); - for (unsigned int dim=0; dim < OutputImageType::ImageDimension; ++dim) - { - inputIndex[dim] = Math::Ceil( contInputIndex[dim] ); - } - inputRequestedRegion.SetUpperIndex( inputIndex ); + inputRequestedRegion = ImageAlgorithm::EnlargeRegionOverBox(outputPtr->GetRequestedRegion(), + outputPtr, + inputPtr); inputPtr->SetRequestedRegion( inputRequestedRegion ); return; From 38255381e1ab62477d2a4060b7d0fdbe50a0b9dd Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Thu, 27 Sep 2018 12:45:50 +0200 Subject: [PATCH 03/11] add transform to ImageAlgorithm::EnlargeRegionOverBox --- Modules/Core/Common/include/itkImageAlgorithm.h | 3 ++- Modules/Core/Common/include/itkImageAlgorithm.hxx | 12 ++++++++++-- Modules/Core/Common/test/itkImageTest.cxx | 5 +++++ .../ImageGrid/include/itkResampleImageFilter.hxx | 1 + .../ImageGrid/include/itkWarpImageFilter.hxx | 5 +++++ 5 files changed, 23 insertions(+), 3 deletions(-) diff --git a/Modules/Core/Common/include/itkImageAlgorithm.h b/Modules/Core/Common/include/itkImageAlgorithm.h index c678f041361..42a57315eff 100644 --- a/Modules/Core/Common/include/itkImageAlgorithm.h +++ b/Modules/Core/Common/include/itkImageAlgorithm.h @@ -138,9 +138,10 @@ struct ImageAlgorithm * the physical space covered by the input * region of the input image */ - template + template static typename OutputImageType::RegionType EnlargeRegionOverBox(const typename InputImageType::RegionType & inputRegion, + const TransformType* transformPtr, const InputImageType* inputImage, const OutputImageType* outputImage); diff --git a/Modules/Core/Common/include/itkImageAlgorithm.hxx b/Modules/Core/Common/include/itkImageAlgorithm.hxx index 1cf1d8ec759..fa81daa9bc1 100644 --- a/Modules/Core/Common/include/itkImageAlgorithm.hxx +++ b/Modules/Core/Common/include/itkImageAlgorithm.hxx @@ -167,9 +167,10 @@ void ImageAlgorithm::DispatchedCopy( const InputImageType *inImage, } } -template +template typename OutputImageType::RegionType ImageAlgorithm::EnlargeRegionOverBox(const typename InputImageType::RegionType & inputRegion, + const TransformType* transformPtr, const InputImageType* inputImage, const OutputImageType* outputImage) { @@ -217,7 +218,14 @@ ImageAlgorithm::EnlargeRegionOverBox(const typename InputImageType::RegionType & typedef Point< SpacePrecisionType, OutputImageType::ImageDimension > PointType; PointType point; - inputImage->TransformContinuousIndexToPhysicalPoint(currentCornerIndex, point); + if ( transformPtr == ITK_NULLPTR) + { + inputImage->TransformContinuousIndexToPhysicalPoint(currentCornerIndex, point); + } + else + { + point = transformPtr->TransformPoint(currentCornerIndex); + } outputImage->TransformPhysicalPointToContinuousIndex(point, corners[count]); } diff --git a/Modules/Core/Common/test/itkImageTest.cxx b/Modules/Core/Common/test/itkImageTest.cxx index 4551a3965c6..4f2922f662c 100644 --- a/Modules/Core/Common/test/itkImageTest.cxx +++ b/Modules/Core/Common/test/itkImageTest.cxx @@ -20,6 +20,7 @@ #include "itkImage.h" #include "itkFixedArray.h" #include "itkImageAlgorithm.h" +#include "itkIdentityTransform.h" int itkImageTest(int, char* [] ) { @@ -121,7 +122,11 @@ int itkImageTest(int, char* [] ) regionRef.SetSize(sizeRef); imageRef->SetRegions(regionRef); + typedef itk::IdentityTransform< double, Image::ImageDimension > IdentityTransformType; + IdentityTransformType* it = IdentityTransformType::New(); + Image::RegionType boxRegion = itk::ImageAlgorithm::EnlargeRegionOverBox(image->GetLargestPossibleRegion(), + it, image.GetPointer(), imageRef.GetPointer()); Image::IndexType correctIndex; correctIndex.Fill(0); diff --git a/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx b/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx index ebb0c65ccbb..6016d08519a 100644 --- a/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx +++ b/Modules/Filtering/ImageGrid/include/itkResampleImageFilter.hxx @@ -517,6 +517,7 @@ ResampleImageFilter< TInputImage, TOutputImage, TInterpolatorPrecisionType, TTra { typename TInputImage::RegionType inputRequestedRegion; inputRequestedRegion = ImageAlgorithm::EnlargeRegionOverBox(outputPtr->GetRequestedRegion(), + transformPtr, outputPtr, inputPtr); diff --git a/Modules/Filtering/ImageGrid/include/itkWarpImageFilter.hxx b/Modules/Filtering/ImageGrid/include/itkWarpImageFilter.hxx index 192dce7de98..d232f1cde1f 100644 --- a/Modules/Filtering/ImageGrid/include/itkWarpImageFilter.hxx +++ b/Modules/Filtering/ImageGrid/include/itkWarpImageFilter.hxx @@ -27,6 +27,8 @@ #include "itkProgressReporter.h" #include "itkContinuousIndex.h" #include "itkMath.h" +#include "itkIdentityTransform.h" + namespace itk { /** @@ -438,8 +440,11 @@ WarpImageFilter< TInputImage, TOutputImage, TDisplacementField > else { typedef typename TDisplacementField::RegionType DisplacementRegionType; + typedef itk::IdentityTransform< SpacePrecisionType, OutputImageType::ImageDimension > IdentityTransformType; + IdentityTransformType* it = IdentityTransformType::New(); DisplacementRegionType fieldRequestedRegion = ImageAlgorithm::EnlargeRegionOverBox(outputPtr->GetRequestedRegion(), + it, outputPtr, fieldPtr); fieldPtr->SetRequestedRegion( fieldRequestedRegion ); From 9ece4e2baac6adb84c1fa207afaa3cab4fec7570 Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Fri, 28 Sep 2018 11:55:28 +0200 Subject: [PATCH 04/11] BUG: use ITK_NULLPTR instead of identityTransform --- Modules/Core/Common/test/itkImageTest.cxx | 7 +++---- Modules/Filtering/ImageGrid/include/itkWarpImageFilter.hxx | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/Modules/Core/Common/test/itkImageTest.cxx b/Modules/Core/Common/test/itkImageTest.cxx index 4f2922f662c..6f46b1a1e5c 100644 --- a/Modules/Core/Common/test/itkImageTest.cxx +++ b/Modules/Core/Common/test/itkImageTest.cxx @@ -20,7 +20,7 @@ #include "itkImage.h" #include "itkFixedArray.h" #include "itkImageAlgorithm.h" -#include "itkIdentityTransform.h" +#include "itkTransform.h" int itkImageTest(int, char* [] ) { @@ -122,11 +122,10 @@ int itkImageTest(int, char* [] ) regionRef.SetSize(sizeRef); imageRef->SetRegions(regionRef); - typedef itk::IdentityTransform< double, Image::ImageDimension > IdentityTransformType; - IdentityTransformType* it = IdentityTransformType::New(); + typedef itk::Transform< double, Image::ImageDimension, Image::ImageDimension > TransformType; Image::RegionType boxRegion = itk::ImageAlgorithm::EnlargeRegionOverBox(image->GetLargestPossibleRegion(), - it, + static_cast< TransformType *>(ITK_NULLPTR), image.GetPointer(), imageRef.GetPointer()); Image::IndexType correctIndex; correctIndex.Fill(0); diff --git a/Modules/Filtering/ImageGrid/include/itkWarpImageFilter.hxx b/Modules/Filtering/ImageGrid/include/itkWarpImageFilter.hxx index d232f1cde1f..9052fc435da 100644 --- a/Modules/Filtering/ImageGrid/include/itkWarpImageFilter.hxx +++ b/Modules/Filtering/ImageGrid/include/itkWarpImageFilter.hxx @@ -27,7 +27,7 @@ #include "itkProgressReporter.h" #include "itkContinuousIndex.h" #include "itkMath.h" -#include "itkIdentityTransform.h" +#include "itkTransform.h" namespace itk { @@ -440,11 +440,10 @@ WarpImageFilter< TInputImage, TOutputImage, TDisplacementField > else { typedef typename TDisplacementField::RegionType DisplacementRegionType; - typedef itk::IdentityTransform< SpacePrecisionType, OutputImageType::ImageDimension > IdentityTransformType; - IdentityTransformType* it = IdentityTransformType::New(); + typedef itk::Transform< SpacePrecisionType, OutputImageType::ImageDimension, OutputImageType::ImageDimension > TransformType; DisplacementRegionType fieldRequestedRegion = ImageAlgorithm::EnlargeRegionOverBox(outputPtr->GetRequestedRegion(), - it, + static_cast< TransformType *>(ITK_NULLPTR), outputPtr, fieldPtr); fieldPtr->SetRequestedRegion( fieldRequestedRegion ); From 0a0d9a10b65a90814018f58a6a3dc30856090c8e Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Tue, 25 Sep 2018 14:54:50 +0200 Subject: [PATCH 05/11] TEST: plain copy of itkResampleImageTest.cxx and its cmake --- .../Filtering/ImageGrid/test/CMakeLists.txt | 16 ++ .../ImageGrid/test/itkResampleImageTest2s.cxx | 248 ++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx diff --git a/Modules/Filtering/ImageGrid/test/CMakeLists.txt b/Modules/Filtering/ImageGrid/test/CMakeLists.txt index bd7bd4bfea2..5d680bd6145 100644 --- a/Modules/Filtering/ImageGrid/test/CMakeLists.txt +++ b/Modules/Filtering/ImageGrid/test/CMakeLists.txt @@ -223,6 +223,22 @@ itk_add_test(NAME itkResampleImageTest2 ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2b.png ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2c.png ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.png) +itk_add_test(NAME itkResampleImageTest2 + COMMAND ITKImageGridTestDriver + --compare DATA{${ITK_DATA_ROOT}/Baseline/BasicFilters/ResampleImageTest2.png} + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2a.png + --compare DATA{${ITK_DATA_ROOT}/Baseline/BasicFilters/ResampleImageTest2.png} + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2b.png + --compare DATA{Baseline/ResampleImageTest2NearestExtrapolate.png} + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2c.png + --compare DATA{Baseline/ResampleImageTest2NearestExtrapolate.png} + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.png + itkResampleImageTest2 DATA{${ITK_DATA_ROOT}/Input/cthead1.png} + DATA{${ITK_DATA_ROOT}/Input/circle.png} + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2a.png + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2b.png + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2c.png + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.png) itk_add_test(NAME itkResampleImageTest3 COMMAND ITKImageGridTestDriver --compare DATA{Baseline/ResampleImageTest3.png} diff --git a/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx b/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx new file mode 100644 index 00000000000..09e18f4efd4 --- /dev/null +++ b/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx @@ -0,0 +1,248 @@ +/*========================================================================= + * + * 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 + +#include "itkAffineTransform.h" +#include "itkImageFileReader.h" +#include "itkImageFileWriter.h" +#include "itkResampleImageFilter.h" +#include "itkNearestNeighborExtrapolateImageFunction.h" +#include "itkTestingMacros.h" + +/* Further testing of itkResampleImageFilter + * Output is compared with baseline image using the cmake itk_add_test + * '--compare' option. + */ + +namespace { + +template +class NonlinearAffineTransform: + public itk::AffineTransform +{ +public: + /** Standard class typedefs. */ + typedef NonlinearAffineTransform Self; + typedef itk::AffineTransform< TCoordRepType, NDimensions > Superclass; + typedef itk::SmartPointer< Self > Pointer; + typedef itk::SmartPointer< const Self > ConstPointer; + + /** New macro for creation of through a smart pointer. */ + itkSimpleNewMacro(Self); + + /** Run-time type information (and related methods). */ + itkTypeMacro(NonlinearAffineTransform, AffineTransform); + + /** Override this. See test below. */ + virtual bool IsLinear() const ITK_OVERRIDE { return false; } +}; +} + +int itkResampleImageTest2(int argc, char * argv [] ) +{ + + if( argc < 5 ) + { + std::cerr << "Missing arguments ! " << std::endl; + std::cerr << "Usage : " << std::endl; + std::cerr << argv[0] << "inputImage referenceImage " + << "resampledImageLinear resampledImageNonLinear " + << "resampledImageLinearNearestExtrapolate" + << "resampledImageNonLinearNearestExtrapolate"; + std::cerr << std::endl; + return EXIT_FAILURE; + } + + const unsigned int NDimensions = 2; + + typedef unsigned char PixelType; + typedef itk::Image ImageType; + typedef double CoordRepType; + + typedef itk::AffineTransform + AffineTransformType; + typedef NonlinearAffineTransform + NonlinearAffineTransformType; + typedef itk::LinearInterpolateImageFunction + InterpolatorType; + typedef itk::NearestNeighborExtrapolateImageFunction + ExtrapolatorType; + + typedef itk::ImageFileReader< ImageType > ReaderType; + typedef itk::ImageFileWriter< ImageType > WriterType; + + ReaderType::Pointer reader1 = ReaderType::New(); + ReaderType::Pointer reader2 = ReaderType::New(); + ReaderType::Pointer reader3 = ReaderType::New(); + ReaderType::Pointer reader4 = ReaderType::New(); + + WriterType::Pointer writer1 = WriterType::New(); + WriterType::Pointer writer2 = WriterType::New(); + WriterType::Pointer writer3 = WriterType::New(); + WriterType::Pointer writer4 = WriterType::New(); + + reader1->SetFileName( argv[1] ); + reader2->SetFileName( argv[2] ); + reader3->SetFileName( argv[3] ); + reader4->SetFileName( argv[4] ); + + writer1->SetFileName( argv[3] ); + writer2->SetFileName( argv[4] ); + writer3->SetFileName( argv[5] ); + writer4->SetFileName( argv[6] ); + + // Create an affine transformation + AffineTransformType::Pointer affineTransform = AffineTransformType::New(); + affineTransform->Scale(2.0); + + // Create a linear interpolation image function + InterpolatorType::Pointer interpolator = InterpolatorType::New(); + + // Create a nearest neighbor extrapolate image function + ExtrapolatorType::Pointer extrapolator = ExtrapolatorType::New(); + + // Create and configure a resampling filter + typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleFilterType; + + ResampleFilterType::Pointer resample = ResampleFilterType::New(); + + EXERCISE_BASIC_OBJECT_METHODS( resample, ResampleImageFilter, ImageToImageFilter ); + + resample->SetInput( reader1->GetOutput() ); + TEST_SET_GET_VALUE( reader1->GetOutput(), resample->GetInput() ); + + resample->SetReferenceImage( reader2->GetOutput() ); + TEST_SET_GET_VALUE( reader2->GetOutput(), resample->GetReferenceImage() ); + + resample->UseReferenceImageOn(); + TEST_EXPECT_TRUE( resample->GetUseReferenceImage() ); + + resample->SetTransform( affineTransform ); + TEST_SET_GET_VALUE( affineTransform, resample->GetTransform() ); + + resample->SetInterpolator( interpolator ); + TEST_SET_GET_VALUE( interpolator, resample->GetInterpolator() ); + + writer1->SetInput( resample->GetOutput() ); + + // Check GetReferenceImage + if( resample->GetReferenceImage() != reader2->GetOutput() ) + { + std::cerr << "GetReferenceImage() failed ! " << std::endl; + return EXIT_FAILURE; + } + + // Run the resampling filter with the normal, linear, affine transform. + // This will use ResampleImageFilter::LinearThreadedGenerateData(). + std::cout << "Test with normal AffineTransform." << std::endl; + try + { + writer1->Update(); + } + catch( itk::ExceptionObject & excp ) + { + std::cerr << excp << std::endl; + return EXIT_FAILURE; + } + + // Assign an affine transform that returns + // false for IsLinear() instead of true, to force + // the filter to use the NonlinearThreadedGenerateData method + // instead of LinearThreadedGenerateData. This will test that + // we get the same results for both methods. + std::cout << "Test with NonlinearAffineTransform." << std::endl; + NonlinearAffineTransformType::Pointer nonlinearAffineTransform = + NonlinearAffineTransformType::New(); + + nonlinearAffineTransform->Scale(2.0); + resample->SetTransform( nonlinearAffineTransform ); + writer2->SetInput( resample->GetOutput() ); + try + { + writer2->Update(); + } + catch( itk::ExceptionObject & excp ) + { + std::cerr << excp << std::endl; + return EXIT_FAILURE; + } + + // Instead of using the default pixel when sampling outside the input image, + // we use a nearest neighbor extrapolator. + resample->SetTransform( affineTransform ); + resample->SetExtrapolator( extrapolator ); + writer3->SetInput( resample->GetOutput() ); + std::cout << "Test with nearest neighbor extrapolator, affine transform." << std::endl; + try + { + writer3->Update(); + } + catch( itk::ExceptionObject & excp ) + { + std::cerr << excp << std::endl; + return EXIT_FAILURE; + } + + // Instead of using the default pixel when sampling outside the input image, + // we use a nearest neighbor extrapolator. + resample->SetTransform( nonlinearAffineTransform ); + writer4->SetInput( resample->GetOutput() ); + std::cout << "Test with nearest neighbor extrapolator, nonlinear transform." << std::endl; + try + { + writer4->Update(); + } + catch( itk::ExceptionObject & excp ) + { + std::cerr << excp << std::endl; + return EXIT_FAILURE; + } + + // Check UseReferenceImage methods + resample->UseReferenceImageOff(); + if( resample->GetUseReferenceImage() ) + { + std::cerr << "GetUseReferenceImage() or UseReferenceImageOff() failed ! "; + std::cerr << std::endl; + return EXIT_FAILURE; + } + + // Check UseReferenceImage methods + resample->UseReferenceImageOn(); + if( !resample->GetUseReferenceImage() ) + { + std::cerr << "GetUseReferenceImage() or UseReferenceImageOn() failed ! "; + std::cerr << std::endl; + return EXIT_FAILURE; + } + + // Check UseReferenceImage methods + resample->SetUseReferenceImage( false ); + if( resample->GetUseReferenceImage() ) + { + std::cerr << "GetUseReferenceImage() or SetUseReferenceImage() failed ! "; + std::cerr << std::endl; + return EXIT_FAILURE; + } + + + std::cout << "Test passed." << std::endl; + return EXIT_SUCCESS; + +} From f768f4daec8c9728e213efe67e534a12aede1942 Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Tue, 25 Sep 2018 14:57:59 +0200 Subject: [PATCH 06/11] TEST: employ itkResampleImageTest2s, still the same as itkResampleImageTest2 --- Modules/Filtering/ImageGrid/test/CMakeLists.txt | 5 +++-- Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Modules/Filtering/ImageGrid/test/CMakeLists.txt b/Modules/Filtering/ImageGrid/test/CMakeLists.txt index 5d680bd6145..1d256fb09fc 100644 --- a/Modules/Filtering/ImageGrid/test/CMakeLists.txt +++ b/Modules/Filtering/ImageGrid/test/CMakeLists.txt @@ -45,6 +45,7 @@ itkWrapPadImageTest.cxx itkMirrorPadImageTest.cxx itkResampleImageTest.cxx itkResampleImageTest2.cxx +itkResampleImageTest2s.cxx itkResampleImageTest3.cxx itkResampleImageTest4.cxx itkResampleImageTest5.cxx @@ -223,7 +224,7 @@ itk_add_test(NAME itkResampleImageTest2 ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2b.png ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2c.png ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.png) -itk_add_test(NAME itkResampleImageTest2 +itk_add_test(NAME itkResampleImageTest2s COMMAND ITKImageGridTestDriver --compare DATA{${ITK_DATA_ROOT}/Baseline/BasicFilters/ResampleImageTest2.png} ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2a.png @@ -233,7 +234,7 @@ itk_add_test(NAME itkResampleImageTest2 ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2c.png --compare DATA{Baseline/ResampleImageTest2NearestExtrapolate.png} ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.png - itkResampleImageTest2 DATA{${ITK_DATA_ROOT}/Input/cthead1.png} + itkResampleImageTest2s DATA{${ITK_DATA_ROOT}/Input/cthead1.png} DATA{${ITK_DATA_ROOT}/Input/circle.png} ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2a.png ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2b.png diff --git a/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx b/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx index 09e18f4efd4..b291dbed00c 100644 --- a/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx +++ b/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx @@ -54,7 +54,7 @@ class NonlinearAffineTransform: }; } -int itkResampleImageTest2(int argc, char * argv [] ) +int itkResampleImageTest2s(int argc, char * argv [] ) { if( argc < 5 ) From 320411724a895c8a423d497ac67675f3b2eb02b1 Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Wed, 26 Sep 2018 15:05:43 +0200 Subject: [PATCH 07/11] TEST: write MHAs (which support streaming) instead of PNGs --- .../Baseline/ResampleImageTest2.mha.sha512 | 1 + ...pleImageTest2NearestExtrapolate.mha.sha512 | 1 + .../Filtering/ImageGrid/test/CMakeLists.txt | 24 +++++++++---------- 3 files changed, 14 insertions(+), 12 deletions(-) create mode 100644 Modules/Filtering/ImageGrid/test/Baseline/ResampleImageTest2.mha.sha512 create mode 100644 Modules/Filtering/ImageGrid/test/Baseline/ResampleImageTest2NearestExtrapolate.mha.sha512 diff --git a/Modules/Filtering/ImageGrid/test/Baseline/ResampleImageTest2.mha.sha512 b/Modules/Filtering/ImageGrid/test/Baseline/ResampleImageTest2.mha.sha512 new file mode 100644 index 00000000000..3d8c0b91c51 --- /dev/null +++ b/Modules/Filtering/ImageGrid/test/Baseline/ResampleImageTest2.mha.sha512 @@ -0,0 +1 @@ +6dcda44ce36e39fb6a792e26c8cd93830bab8edbe9f33385dc59b24bd6b40c99bbadf9b6ada967b1d1b6624e986f1161960d86db63b2d6b71da58eec0a2b911c diff --git a/Modules/Filtering/ImageGrid/test/Baseline/ResampleImageTest2NearestExtrapolate.mha.sha512 b/Modules/Filtering/ImageGrid/test/Baseline/ResampleImageTest2NearestExtrapolate.mha.sha512 new file mode 100644 index 00000000000..b4c87795633 --- /dev/null +++ b/Modules/Filtering/ImageGrid/test/Baseline/ResampleImageTest2NearestExtrapolate.mha.sha512 @@ -0,0 +1 @@ +bbc1a32a82e88334df11c79f54ba4260ea291f8316c882d6360e7546739eb92109a169cc07abe32250a4e12e49a4bb8bad22c45580ccb78c4ee482fa68675e4f diff --git a/Modules/Filtering/ImageGrid/test/CMakeLists.txt b/Modules/Filtering/ImageGrid/test/CMakeLists.txt index 1d256fb09fc..f2045babe8d 100644 --- a/Modules/Filtering/ImageGrid/test/CMakeLists.txt +++ b/Modules/Filtering/ImageGrid/test/CMakeLists.txt @@ -226,20 +226,20 @@ itk_add_test(NAME itkResampleImageTest2 ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.png) itk_add_test(NAME itkResampleImageTest2s COMMAND ITKImageGridTestDriver - --compare DATA{${ITK_DATA_ROOT}/Baseline/BasicFilters/ResampleImageTest2.png} - ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2a.png - --compare DATA{${ITK_DATA_ROOT}/Baseline/BasicFilters/ResampleImageTest2.png} - ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2b.png - --compare DATA{Baseline/ResampleImageTest2NearestExtrapolate.png} - ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2c.png - --compare DATA{Baseline/ResampleImageTest2NearestExtrapolate.png} - ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.png + --compare DATA{Baseline/ResampleImageTest2.mha} + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2a.mha + --compare DATA{Baseline/ResampleImageTest2.mha} + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2b.mha + --compare DATA{Baseline/ResampleImageTest2NearestExtrapolate.mha} + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2c.mha + --compare DATA{Baseline/ResampleImageTest2NearestExtrapolate.mha} + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.mha itkResampleImageTest2s DATA{${ITK_DATA_ROOT}/Input/cthead1.png} DATA{${ITK_DATA_ROOT}/Input/circle.png} - ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2a.png - ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2b.png - ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2c.png - ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.png) + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2a.mha + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2b.mha + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2c.mha + ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2d.mha) itk_add_test(NAME itkResampleImageTest3 COMMAND ITKImageGridTestDriver --compare DATA{Baseline/ResampleImageTest3.png} From a44c9675935d83f07d6ebc8fc1741a8b07fb2d10 Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Tue, 25 Sep 2018 15:05:58 +0200 Subject: [PATCH 08/11] TEST: demand streaming and employ where possible --- Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx b/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx index b291dbed00c..ebd95c76732 100644 --- a/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx +++ b/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx @@ -153,6 +153,7 @@ int itkResampleImageTest2s(int argc, char * argv [] ) std::cout << "Test with normal AffineTransform." << std::endl; try { + writer1->SetNumberOfStreamDivisions(8); //split into 8 pieces for streaming. writer1->Update(); } catch( itk::ExceptionObject & excp ) @@ -175,6 +176,7 @@ int itkResampleImageTest2s(int argc, char * argv [] ) writer2->SetInput( resample->GetOutput() ); try { + writer2->SetNumberOfStreamDivisions(8); //demand splitting into 8 pieces for streaming, but faked non-linearity will disable streaming writer2->Update(); } catch( itk::ExceptionObject & excp ) @@ -191,6 +193,7 @@ int itkResampleImageTest2s(int argc, char * argv [] ) std::cout << "Test with nearest neighbor extrapolator, affine transform." << std::endl; try { + writer3->SetNumberOfStreamDivisions(8); //split into 8 pieces for streaming. writer3->Update(); } catch( itk::ExceptionObject & excp ) @@ -206,6 +209,7 @@ int itkResampleImageTest2s(int argc, char * argv [] ) std::cout << "Test with nearest neighbor extrapolator, nonlinear transform." << std::endl; try { + writer4->SetNumberOfStreamDivisions(8); //demand splitting into 8 pieces for streaming, but faked non-linearity will disable streaming writer4->Update(); } catch( itk::ExceptionObject & excp ) From 5d765b4d881335f973ad007ca4dcb0fca1cdc174 Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Tue, 25 Sep 2018 15:16:55 +0200 Subject: [PATCH 09/11] TEST: verify streaming for linear case --- .../ImageGrid/test/itkResampleImageTest2s.cxx | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx b/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx index ebd95c76732..f4ce5734bd7 100644 --- a/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx +++ b/Modules/Filtering/ImageGrid/test/itkResampleImageTest2s.cxx @@ -23,6 +23,7 @@ #include "itkImageFileWriter.h" #include "itkResampleImageFilter.h" #include "itkNearestNeighborExtrapolateImageFunction.h" +#include "itkPipelineMonitorImageFilter.h" #include "itkTestingMacros.h" /* Further testing of itkResampleImageFilter @@ -122,6 +123,10 @@ int itkResampleImageTest2s(int argc, char * argv [] ) ResampleFilterType::Pointer resample = ResampleFilterType::New(); + typedef itk::PipelineMonitorImageFilter< ImageType > MonitorFilter; + + MonitorFilter::Pointer monitor = MonitorFilter::New(); + EXERCISE_BASIC_OBJECT_METHODS( resample, ResampleImageFilter, ImageToImageFilter ); resample->SetInput( reader1->GetOutput() ); @@ -139,7 +144,8 @@ int itkResampleImageTest2s(int argc, char * argv [] ) resample->SetInterpolator( interpolator ); TEST_SET_GET_VALUE( interpolator, resample->GetInterpolator() ); - writer1->SetInput( resample->GetOutput() ); + monitor->SetInput( resample->GetOutput() ); + writer1->SetInput( monitor->GetOutput() ); // Check GetReferenceImage if( resample->GetReferenceImage() != reader2->GetOutput() ) @@ -161,6 +167,15 @@ int itkResampleImageTest2s(int argc, char * argv [] ) std::cerr << excp << std::endl; return EXIT_FAILURE; } + + // this verifies that the pipeline was executed as expected along + // with correct region propagation and output information + if (!monitor->VerifyAllInputCanStream(8)) + { + std::cout << "Streaming failed to execute as expected!" << std::endl; + std::cout << monitor; + return EXIT_FAILURE; + } // Assign an affine transform that returns // false for IsLinear() instead of true, to force From 9cd71e9b3a460fab730520d23072da6690b6471a Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Mon, 22 Oct 2018 15:24:04 +0200 Subject: [PATCH 10/11] TEST: itkResampleImageTest7.cxx for comparing output of stream driven imaging (SDI) and without SDI --- .../Filtering/ImageGrid/test/CMakeLists.txt | 3 + .../ImageGrid/test/itkResampleImageTest7.cxx | 169 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 Modules/Filtering/ImageGrid/test/itkResampleImageTest7.cxx diff --git a/Modules/Filtering/ImageGrid/test/CMakeLists.txt b/Modules/Filtering/ImageGrid/test/CMakeLists.txt index f2045babe8d..e0754b605f2 100644 --- a/Modules/Filtering/ImageGrid/test/CMakeLists.txt +++ b/Modules/Filtering/ImageGrid/test/CMakeLists.txt @@ -50,6 +50,7 @@ itkResampleImageTest3.cxx itkResampleImageTest4.cxx itkResampleImageTest5.cxx itkResampleImageTest6.cxx +itkResampleImageTest7.cxx itkResamplePhasedArray3DSpecialCoordinatesImageTest.cxx itkPushPopTileImageFilterTest.cxx itkShrinkImageStreamingTest.cxx @@ -258,6 +259,8 @@ itk_add_test(NAME itkResampleImageTest6 --compare DATA{Baseline/ResampleImageTest6.png} ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest6.png itkResampleImageTest6 10 ${ITK_TEST_OUTPUT_DIR}/ResampleImageTest6.png) +itk_add_test(NAME itkResampleImageTest7 + COMMAND ITKImageGridTestDriver itkResampleImageTest7) itk_add_test(NAME itkResamplePhasedArray3DSpecialCoordinatesImageTest COMMAND ITKImageGridTestDriver itkResamplePhasedArray3DSpecialCoordinatesImageTest) itk_add_test(NAME itkPushPopTileImageFilterTest diff --git a/Modules/Filtering/ImageGrid/test/itkResampleImageTest7.cxx b/Modules/Filtering/ImageGrid/test/itkResampleImageTest7.cxx new file mode 100644 index 00000000000..9bb2636dfed --- /dev/null +++ b/Modules/Filtering/ImageGrid/test/itkResampleImageTest7.cxx @@ -0,0 +1,169 @@ +/*========================================================================= + * + * 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 + +#include "itkAffineTransform.h" +#include "itkResampleImageFilter.h" +#include "itkPipelineMonitorImageFilter.h" +#include "itkStreamingImageFilter.h" +#include "itkTestingMacros.h" +#include "itkMath.h" + +/* itkResampleImageFilter output compared to streamed output + */ + +int itkResampleImageTest7( int argc, char * argv [] ) +{ + + if (argc > 1) + { + std::cout << "Usage: " << argv[0] + << " noParams" << std::endl; + return EXIT_FAILURE; + } + + const unsigned int NDimensions = 2; + + typedef unsigned char PixelType; + typedef itk::Image ImageType; + typedef ImageType::IndexType ImageIndexType; + typedef ImageType::Pointer ImagePointerType; + typedef ImageType::RegionType ImageRegionType; + typedef ImageType::SizeType ImageSizeType; + typedef double CoordRepType; + + typedef itk::AffineTransform + AffineTransformType; + + // Create and configure an image + ImagePointerType image = ImageType::New(); + ImageIndexType index = {{0, 0}}; + ImageSizeType size = {{64,64}}; + ImageRegionType region; + region.SetSize ( size ); + region.SetIndex( index ); + image->SetLargestPossibleRegion( region ); + image->SetBufferedRegion( region ); + image->Allocate(); + + // Fill image with a ramp + std::cout << "init image..." << std::flush; + itk::ImageRegionIteratorWithIndex iter(image, region); + PixelType value; + for (iter.GoToBegin(); !iter.IsAtEnd(); ++iter) + { + index = iter.GetIndex(); + value = index[0] + index[1]; + iter.Set(value); + } + std::cout << "Done." << std::endl; + + // Create an affine transformation + AffineTransformType::Pointer affineTransform = AffineTransformType::New(); + affineTransform->Scale(2.0); + + // Create and configure a resampling filter + typedef itk::ResampleImageFilter< ImageType, ImageType > ResampleFilterType; + ResampleFilterType::Pointer resample = ResampleFilterType::New(); + + typedef itk::PipelineMonitorImageFilter< ImageType > MonitorFilter; + MonitorFilter::Pointer monitor = MonitorFilter::New(); + + typedef itk::StreamingImageFilter StreamerType; + StreamerType::Pointer streamer = StreamerType::New(); + + std::cout << "Test with normal AffineTransform." << std::endl; + resample->SetInput( image ); + resample->SetTransform( affineTransform ); + monitor->SetInput( resample->GetOutput() ); + streamer->SetInput( monitor->GetOutput() ); + + unsigned char numStreamDiv; + + // Run the resampling filter without streaming, i.e. 1 StreamDivisions + numStreamDiv= 1; // do not split, i.e. do not stream + try + { + streamer->SetNumberOfStreamDivisions(numStreamDiv); + streamer->Update(); + } + catch( itk::ExceptionObject & excp ) + { + std::cerr << excp << std::endl; + return EXIT_FAILURE; + } + + if (!monitor->VerifyAllInputCanStream(numStreamDiv)) + { + std::cout << "Avoiding streaming failed to execute as expected!" << std::endl; + std::cout << monitor; + return EXIT_FAILURE; + } + + ImagePointerType outputNoSDI= streamer->GetOutput(); + outputNoSDI->DisconnectPipeline(); + + // Run the resampling filter with streaming + numStreamDiv= 8; // split into numStream pieces for streaming. + try + { + streamer->SetNumberOfStreamDivisions(numStreamDiv); + streamer->Update(); + } + catch( itk::ExceptionObject & excp ) + { + std::cerr << excp << std::endl; + return EXIT_FAILURE; + } + + if (!monitor->VerifyAllInputCanStream(numStreamDiv)) + { + std::cout << "Streaming failed to execute as expected!" << std::endl; + std::cout << monitor; + return EXIT_FAILURE; + } + + ImagePointerType outputSDI= streamer->GetOutput(); + outputSDI->DisconnectPipeline(); + + itk::ImageRegionIterator + itNoSDI(outputNoSDI, outputNoSDI->GetLargestPossibleRegion()), + itSDI(outputSDI, outputSDI->GetLargestPossibleRegion()); + for(itNoSDI.GoToBegin(), itSDI.GoToBegin(); + !itNoSDI.IsAtEnd() && !itSDI.IsAtEnd(); + ++itNoSDI, ++itSDI) + { + if(itk::Math::NotAlmostEquals( itNoSDI.Value(), itSDI.Value() )) + { + std::cout << "Pixels differ " + << itNoSDI.Value() << " " + << itSDI.Value() << std::endl; + return EXIT_FAILURE; + } + } + if(itNoSDI.IsAtEnd() != itSDI.IsAtEnd()) + { + std::cout << "Iterators don't agree on end of image" << std::endl; + return EXIT_FAILURE; + } + + std::cout << "Test passed." << std::endl; + return EXIT_SUCCESS; + +} From 0f962c5c30ec28d96b950f64ed3cdce8fa0887f3 Mon Sep 17 00:00:00 2001 From: Roman Grothausmann Date: Tue, 23 Oct 2018 08:26:39 +0200 Subject: [PATCH 11/11] mark resample as modified to enforce re-execution of filter chain --- Modules/Filtering/ImageGrid/test/itkResampleImageTest7.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/Filtering/ImageGrid/test/itkResampleImageTest7.cxx b/Modules/Filtering/ImageGrid/test/itkResampleImageTest7.cxx index 9bb2636dfed..2f471a88953 100644 --- a/Modules/Filtering/ImageGrid/test/itkResampleImageTest7.cxx +++ b/Modules/Filtering/ImageGrid/test/itkResampleImageTest7.cxx @@ -121,6 +121,7 @@ int itkResampleImageTest7( int argc, char * argv [] ) // Run the resampling filter with streaming numStreamDiv= 8; // split into numStream pieces for streaming. + resample->Modified(); try { streamer->SetNumberOfStreamDivisions(numStreamDiv);