Skip to content

Commit

Permalink
ENH: new tests to verify streaming capabilities of itkResampleImageFi…
Browse files Browse the repository at this point in the history
…lter

Squashed commit of the following:

commit e5d421f
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Thu Jan 24 10:28:29 2019 +0100

    ENH: new test are expected to fail as long as:

    itkResampleFilter does not support streaming for linear transforms GH PR InsightSoftwareConsortium#82

commit 6067a02
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Wed Jan 23 14:45:46 2019 +0100

    ENH: improvements suggested by @jhlegarreta:

    see InsightSoftwareConsortium#84 (review)

commit 4118d20
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Tue Oct 23 08:26:39 2018 +0200

    ENH: mark resample as modified to enforce re-execution of filter chain

commit 375eac5
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Wed Jan 23 13:17:00 2019 +0100

    ENH: test for comparing output with stream driven imaging (SDI) and without

    based on itkWarpImageFilterTest2.cxx and itkResampleImageTest.cxx

commit a7f066a
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Mon Oct 22 15:24:04 2018 +0200

    ENH: plain copy of itkResampleImageTest4.cxx and its cmake

commit a7fbd1c
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Mon Oct 22 13:51:59 2018 +0200

    ENH: verify streaming is not possible for non-linear case

commit 21771f8
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Tue Sep 25 15:16:55 2018 +0200

    ENH: verify streaming for linear case

commit 1c66653
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Tue Sep 25 15:05:58 2018 +0200

    TEST: demand streaming and employ where possible

commit 89fd06c
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Wed Sep 26 15:05:43 2018 +0200

    TEST: write MHAs (which support streaming) instead of PNGs

commit 18efabd
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Tue Sep 25 14:57:59 2018 +0200

    TEST: employ itkResampleImageTest2s, still the same as itkResampleImageTest2

commit c4d64b5
Author: Roman Grothausmann <romangrothausmann@users.noreply.github.com>
Date:   Tue Sep 25 14:54:50 2018 +0200

    ENH: plain copy of itkResampleImageTest2.cxx and its cmake
  • Loading branch information
romangrothausmann committed Feb 5, 2019
1 parent a1bd683 commit 4566b74
Show file tree
Hide file tree
Showing 5 changed files with 417 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6dcda44ce36e39fb6a792e26c8cd93830bab8edbe9f33385dc59b24bd6b40c99bbadf9b6ada967b1d1b6624e986f1161960d86db63b2d6b71da58eec0a2b911c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bbc1a32a82e88334df11c79f54ba4260ea291f8316c882d6360e7546739eb92109a169cc07abe32250a4e12e49a4bb8bad22c45580ccb78c4ee482fa68675e4f
14 changes: 14 additions & 0 deletions Modules/Filtering/ImageGrid/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ itkMirrorPadImageTest.cxx
itkMirrorPadImageFilterTest.cxx
itkResampleImageTest.cxx
itkResampleImageTest2.cxx
itkResampleImageTest2Streaming.cxx
itkResampleImageTest3.cxx
itkResampleImageTest4.cxx
itkResampleImageTest5.cxx
itkResampleImageTest6.cxx
itkResampleImageTest7.cxx
itkResamplePhasedArray3DSpecialCoordinatesImageTest.cxx
itkPushPopTileImageFilterTest.cxx
itkShrinkImageStreamingTest.cxx
Expand Down Expand Up @@ -266,6 +268,15 @@ itk_add_test(NAME itkResampleImageTest2UseRefImageOn
${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2cUseRefImageOn.png
${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2dUseRefImageOn.png
1)
itk_add_test(NAME itkResampleImageTest2Streaming
COMMAND ITKImageGridTestDriver
itkResampleImageTest2Streaming DATA{Input/cthead1.mha}
DATA{Input/cthead1.mha}
${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2aStreaming.mha
${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2bStreaming.mha
${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2cStreaming.mha
${ITK_TEST_OUTPUT_DIR}/ResampleImageTest2dStreaming.mha)
set_tests_properties(itkResampleImageTest2Streaming PROPERTIES WILL_FAIL TRUE) # should fail as long as itkResampleFilter does not support streaming for linear transforms GH PR #82
itk_add_test(NAME itkResampleImageTest3
COMMAND ITKImageGridTestDriver
--compare DATA{Baseline/ResampleImageTest3.png}
Expand All @@ -284,6 +295,9 @@ 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)
set_tests_properties(itkResampleImageTest7 PROPERTIES WILL_FAIL TRUE) # should fail as long as itkResampleFilter does not support streaming for linear transforms GH PR #82
itk_add_test(NAME itkResamplePhasedArray3DSpecialCoordinatesImageTest
COMMAND ITKImageGridTestDriver itkResamplePhasedArray3DSpecialCoordinatesImageTest)
itk_add_test(NAME itkPushPopTileImageFilterTest
Expand Down
215 changes: 215 additions & 0 deletions Modules/Filtering/ImageGrid/test/itkResampleImageTest2Streaming.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/*=========================================================================
*
* 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 <iostream>

#include "itkAffineTransform.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkResampleImageFilter.h"
#include "itkNearestNeighborExtrapolateImageFunction.h"
#include "itkPipelineMonitorImageFilter.h"
#include "itkTestingMacros.h"

/* Further testing of itkResampleImageFilter
* Output is compared with baseline image using the cmake itk_add_test
* '--compare' option.
*/

namespace {

template<typename TCoordRepType, unsigned int NDimensions>
class NonlinearAffineTransform:
public itk::AffineTransform<TCoordRepType,NDimensions>
{
public:
/** Standard class type aliases. */
using Self = NonlinearAffineTransform;
using Superclass = itk::AffineTransform< TCoordRepType, NDimensions >;
using Pointer = itk::SmartPointer< Self >;
using ConstPointer = itk::SmartPointer< const Self >;

/** 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. */
bool IsLinear() const override { return false; }
};
}

int itkResampleImageTest2s(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;
}

constexpr unsigned int NDimensions = 2;

using PixelType = unsigned char;
using ImageType = itk::Image<PixelType, NDimensions>;
using CoordRepType = double;

using AffineTransformType =
itk::AffineTransform<CoordRepType,NDimensions>;
using NonlinearAffineTransformType =
NonlinearAffineTransform<CoordRepType,NDimensions>;
using InterpolatorType =
itk::LinearInterpolateImageFunction<ImageType,CoordRepType>;
using ExtrapolatorType =
itk::NearestNeighborExtrapolateImageFunction<ImageType,CoordRepType>;

using ReaderType = itk::ImageFileReader< ImageType >;
using WriterType = itk::ImageFileWriter< ImageType >;

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
using ResampleFilterType = itk::ResampleImageFilter< ImageType, ImageType >;

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() );
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() );

monitor->SetInput( resample->GetOutput() );
writer1->SetInput( monitor->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;
writer1->SetNumberOfStreamDivisions(8); //split into 8 pieces for streaming.
TRY_EXPECT_NO_EXCEPTION( writer1->Update() );

// this verifies that the pipeline was executed as expected along
// with correct region propagation and output information
if (!monitor->VerifyAllInputCanStream(8))
{
std::cerr << "Streaming failed to execute as expected!" << std::endl;
std::cerr << monitor;
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( monitor->GetOutput() );
writer2->SetNumberOfStreamDivisions(8); //demand splitting into 8 pieces for streaming, but faked non-linearity will disable streaming
TRY_EXPECT_NO_EXCEPTION( writer2->Update() );

// check that streaming is not possible for non-linear case
if (!monitor->VerifyAllInputCanStream(1))
{
std::cerr << "Streaming succeded for non-linear transform which should not be the case!" << std::endl;
std::cerr << monitor;
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;
writer3->SetNumberOfStreamDivisions(8); //split into 8 pieces for streaming.
TRY_EXPECT_NO_EXCEPTION( writer3->Update() );

// 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;
writer4->SetNumberOfStreamDivisions(8); //demand splitting into 8 pieces for streaming, but faked non-linearity will disable streaming
TRY_EXPECT_NO_EXCEPTION( writer4->Update() );

std::cout << "Test passed." << std::endl;
return EXIT_SUCCESS;

}
Loading

0 comments on commit 4566b74

Please sign in to comment.