diff --git a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.hxx b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.hxx index dcd43c075fe385163904dc59014297722b57abf6..405b2eca95864a9956a8f98bb3235e306c3d385a 100644 --- a/Modules/Core/Transform/include/otbStreamingWarpImageFilter.hxx +++ b/Modules/Core/Transform/include/otbStreamingWarpImageFilter.hxx @@ -232,21 +232,29 @@ StreamingWarpImageFilter<TInputImage, TOutputImage, TDisplacementField> } else { + // In this case we need to generate an empty region compatible + // with cropping by input largest possible region. - inputFinalSize.Fill(0); - inputRequestedRegion.SetSize(inputFinalSize); - inputFinalIndex.Fill(0); - inputRequestedRegion.SetIndex(inputFinalIndex); - // store what we tried to request (prior to trying to crop) - inputPtr->SetRequestedRegion(inputRequestedRegion); + for(auto dim = 0U; dim < InputImageType::ImageDimension; ++dim) + { + auto largestInputRegion = inputPtr->GetLargestPossibleRegion(); + + if(largestInputRegion.GetSize()[dim]>1) + { + inputFinalIndex[dim] = largestInputRegion.GetIndex()[dim]+1; + inputFinalSize[dim] = 0; + } + else + { + inputFinalIndex[dim] = largestInputRegion.GetIndex()[dim]; + inputFinalSize[dim] = largestInputRegion.GetSize()[dim]; + } + } -// // build an exception -// itk::InvalidRequestedRegionError e(__FILE__, __LINE__); -// e.SetLocation(ITK_LOCATION); -// e.SetDescription("Requested region is (at least partially) outside the largest possible region."); -// e.SetDataObject(inputPtr); -// throw e; + inputRequestedRegion.SetSize(inputFinalSize); + inputRequestedRegion.SetIndex(inputFinalIndex); + inputPtr->SetRequestedRegion(inputRequestedRegion); } } diff --git a/Modules/Core/Transform/test/CMakeLists.txt b/Modules/Core/Transform/test/CMakeLists.txt index dba05dea7f4adbb698e8eced27fca5478edb4dd0..5dadf5549888e9f75a261e1231e75478d3670a74 100644 --- a/Modules/Core/Transform/test/CMakeLists.txt +++ b/Modules/Core/Transform/test/CMakeLists.txt @@ -126,6 +126,8 @@ otb_add_test(NAME dmTvStreamingWarpImageFilter COMMAND otbTransformTestDriver 5 ) +otb_add_test(NAME dmTvStreamingWarpImageFilterEmtpyRegion COMMAND otbTransformTestDriver + otbStreamingWarpImageFilterEmptyRegion) # Forward / Backward projection consistency checking set(FWDBWDChecking_INPUTS diff --git a/Modules/Core/Transform/test/otbStreamingWarpImageFilter.cxx b/Modules/Core/Transform/test/otbStreamingWarpImageFilter.cxx index dc089e7998d0294aa122663b2bcdab4c78d66bf7..050fb694726d6225fa62ee6c0faec9e45d6b9e22 100644 --- a/Modules/Core/Transform/test/otbStreamingWarpImageFilter.cxx +++ b/Modules/Core/Transform/test/otbStreamingWarpImageFilter.cxx @@ -25,6 +25,17 @@ #include "otbImageFileWriter.h" #include "otbStreamingWarpImageFilter.h" +// Images definition +const unsigned int Dimension = 2; +typedef double PixelType; +typedef otb::Image<PixelType, Dimension> ImageType; +typedef itk::Vector<PixelType, 2> DisplacementValueType; +typedef otb::Image<DisplacementValueType, Dimension> DisplacementFieldType; + + // Warper + typedef otb::StreamingWarpImageFilter<ImageType, ImageType, DisplacementFieldType> ImageWarperType; + + int otbStreamingWarpImageFilter(int argc, char* argv[]) { if (argc != 5) @@ -39,20 +50,11 @@ int otbStreamingWarpImageFilter(int argc, char* argv[]) const char * outfname = argv[3]; const double maxdef = atoi(argv[4]); - // Images definition - const unsigned int Dimension = 2; - typedef double PixelType; - typedef otb::Image<PixelType, Dimension> ImageType; - typedef itk::Vector<PixelType, 2> DisplacementValueType; - typedef otb::Image<DisplacementValueType, Dimension> DisplacementFieldType; // Change default output origin ImageType::PointType origin; origin.Fill(0.5); - // Warper - typedef otb::StreamingWarpImageFilter<ImageType, ImageType, DisplacementFieldType> ImageWarperType; - // Reader/Writer typedef otb::ImageFileReader<ImageType> ReaderType; typedef otb::ImageFileReader<DisplacementFieldType> DisplacementReaderType; @@ -83,3 +85,72 @@ int otbStreamingWarpImageFilter(int argc, char* argv[]) return EXIT_SUCCESS; } + +int otbStreamingWarpImageFilterEmptyRegion(int itkNotUsed(argc), char * itkNotUsed(argv) []) +{ + ImageType:: Pointer inputPtr = ImageType::New(); + + ImageType::RegionType largestRegion; + ImageType::SizeType largestSize = {{10,10}}; + ImageType::IndexType largestIndex = {{1,1}}; + + largestRegion.SetIndex(largestIndex); + largestRegion.SetSize(largestSize); + + inputPtr->SetRegions(largestRegion); + + ImageType::RegionType emptyRegion; + ImageType::SizeType emptySize = {{0,0}}; + ImageType::IndexType emptyIndex = {{0,0}}; + emptyRegion.SetSize(emptySize); + emptyRegion.SetIndex(emptyIndex); + + inputPtr->SetRequestedRegion(emptyRegion); + inputPtr->SetBufferedRegion(emptyRegion); + + DisplacementFieldType::Pointer dispPtr = DisplacementFieldType::New(); + dispPtr->SetRegions(largestRegion); + dispPtr->Allocate(); + + DisplacementValueType v; + v[0]=-100; + v[1]=-100; + dispPtr->FillBuffer(v); + + ImageWarperType::Pointer warper = ImageWarperType::New(); + + warper->SetDisplacementField(dispPtr); + warper->SetInput(inputPtr); + + ImageType::PointType outputOrigin; + outputOrigin.Fill(0); + warper->SetOutputOrigin(outputOrigin); + + // requested region for full output is completely outside largest + // possible region of input + warper->GetOutput()->UpdateOutputInformation(); + + // Before bugfix this would lead to famous ITK exception outside of + // largest possible region + warper->GetOutput()->PropagateRequestedRegion(); + + // After requested region has been propagated, we need to be sure + // that requested region can be cropped by largest region + auto requestedRegion = inputPtr->GetRequestedRegion(); + + if (! requestedRegion.Crop(inputPtr->GetLargestPossibleRegion()) ) + { + std::cerr<<"Requested region can not be cropped by largest region"<<std::endl; + return EXIT_FAILURE; + } + + // And we also need to check that requested region is not largest + // region + if( inputPtr->GetRequestedRegion().GetNumberOfPixels() != 0) + { + std::cerr<<"Requested region should have {{0, 0}} size"<<std::endl; + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/Modules/Core/Transform/test/otbTransformTestDriver.cxx b/Modules/Core/Transform/test/otbTransformTestDriver.cxx index 484f563d6fea7afb127897fcf128b736a6303849..7ec077d49281a53ec316d5f38eef289e6fd4d042 100644 --- a/Modules/Core/Transform/test/otbTransformTestDriver.cxx +++ b/Modules/Core/Transform/test/otbTransformTestDriver.cxx @@ -31,6 +31,7 @@ void RegisterTests() REGISTER_TEST(otbCreateProjectionWithOTB); REGISTER_TEST(otbGenericMapProjection); REGISTER_TEST(otbStreamingWarpImageFilter); + REGISTER_TEST(otbStreamingWarpImageFilterEmptyRegion); REGISTER_TEST(otbInverseLogPolarTransform); REGISTER_TEST(otbInverseLogPolarTransformResample); REGISTER_TEST(otbStreamingResampleImageFilterWithAffineTransform);