From f8b93ba7e5fb15a793e216100dfd401c7e1461b9 Mon Sep 17 00:00:00 2001
From: Guillaume Pasero <guillaume.pasero@c-s.fr>
Date: Mon, 1 Oct 2012 17:05:48 +0200
Subject: [PATCH] BUG: 552: add a second pass to mask pixels outside the
 deformation grid

---
 ...reorectificationDeformationFieldSource.txx |  4 +-
 .../otbStreamingWarpImageFilter.h             | 11 +++++
 .../otbStreamingWarpImageFilter.txx           | 46 +++++++++++++++++++
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/Code/DisparityMap/otbStereorectificationDeformationFieldSource.txx b/Code/DisparityMap/otbStereorectificationDeformationFieldSource.txx
index 666c57c3d0..c99cb0c98d 100644
--- a/Code/DisparityMap/otbStereorectificationDeformationFieldSource.txx
+++ b/Code/DisparityMap/otbStereorectificationDeformationFieldSource.txx
@@ -260,8 +260,8 @@ StereorectificationDeformationFieldSource<TInputImage, TOutputImage>
 
   // And also the size of the deformation field
   SizeType outputSize;
-  outputSize[0] = (m_RectifiedImageSize[0] / m_GridStep + 1 );
-  outputSize[1] = (m_RectifiedImageSize[1] / m_GridStep + 1);
+  outputSize[0] = (m_RectifiedImageSize[0] / m_GridStep + 2 );
+  outputSize[1] = (m_RectifiedImageSize[1] / m_GridStep + 2);
 
   // Build the output largest region
   RegionType outputLargestRegion;
diff --git a/Code/DisparityMap/otbStreamingWarpImageFilter.h b/Code/DisparityMap/otbStreamingWarpImageFilter.h
index 8bd89ac3eb..c17bff92cc 100644
--- a/Code/DisparityMap/otbStreamingWarpImageFilter.h
+++ b/Code/DisparityMap/otbStreamingWarpImageFilter.h
@@ -64,10 +64,15 @@ public:
   typedef TInputImage                              InputImageType;
   typedef typename  InputImageType::Pointer        InputImagePointerType;
   typedef TOutputImage                             OutputImageType;
+  typedef typename OutputImageType::PointType      PointType;
+  typedef typename OutputImageType::IndexType      IndexType;
+  typedef typename OutputImageType::PixelType      PixelType;
   typedef typename OutputImageType::Pointer        OutputImagePointerType;
+  typedef typename OutputImageType::RegionType     OutputImageRegionType;
   typedef TDeformationField                        DeformationFieldType;
   typedef typename DeformationFieldType::PixelType DeformationValueType;
   typedef typename DeformationFieldType::Pointer   DeformationFieldPointerType;
+  typedef typename DeformationFieldType::RegionType DeformationFieldRegionType;
 
   /** Accessors */
   itkSetMacro(MaximumDeformation, DeformationValueType);
@@ -85,6 +90,12 @@ protected:
    * produce its output. As such, we need to overload the GenerateInputRequestedRegion() method.
    */
   virtual void GenerateInputRequestedRegion();
+  
+  /**
+   * Re-implement the method ThreadedGenerateData to mask area outside the deformation grid
+   */
+  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread,
+                            int threadId );
 
 private:
   StreamingWarpImageFilter(const Self &); //purposely not implemented
diff --git a/Code/DisparityMap/otbStreamingWarpImageFilter.txx b/Code/DisparityMap/otbStreamingWarpImageFilter.txx
index b2d063193f..1fd9f1982a 100644
--- a/Code/DisparityMap/otbStreamingWarpImageFilter.txx
+++ b/Code/DisparityMap/otbStreamingWarpImageFilter.txx
@@ -202,6 +202,52 @@ StreamingWarpImageFilter<TInputImage, TOutputImage, TDeformationField>
     }
  }
 
+
+template<class TInputImage, class TOutputImage, class TDeformationField>
+void
+StreamingWarpImageFilter<TInputImage, TOutputImage, TDeformationField>
+::ThreadedGenerateData(
+  const OutputImageRegionType& outputRegionForThread,
+  int threadId )
+  {
+  // the superclass itk::WarpImageFilter is doing the actual warping
+  Superclass::ThreadedGenerateData(outputRegionForThread,threadId);
+  
+  // second pass on the thread region to mask pixels outside the deformation grid
+  const PixelType paddingValue = this->GetEdgePaddingValue();
+  OutputImagePointerType outputPtr = this->GetOutput();
+  DeformationFieldPointerType fieldPtr = this->GetDeformationField();
+  
+  DeformationFieldRegionType defRegion = fieldPtr->GetLargestPossibleRegion();
+  
+  itk::ImageRegionIteratorWithIndex<OutputImageType> outputIt(
+    outputPtr, outputRegionForThread );
+  IndexType currentIndex;
+  PointType currentPoint;
+  itk::ContinuousIndex<double,DeformationFieldType::ImageDimension> contiIndex;
+  
+  while(!outputIt.IsAtEnd())
+    {
+    // get the output image index
+    currentIndex = outputIt.GetIndex();
+    outputPtr->TransformIndexToPhysicalPoint(currentIndex,currentPoint);
+    fieldPtr->TransformPhysicalPointToContinuousIndex(currentPoint,contiIndex);
+    
+    for (unsigned int dim = 0; dim<DeformationFieldType::ImageDimension; ++dim)
+      {
+      if (contiIndex[dim] < static_cast<double>(defRegion.GetIndex(dim)) || 
+          contiIndex[dim] > static_cast<double>(defRegion.GetIndex(dim)+defRegion.GetSize(dim)-1))
+        {
+        outputIt.Set(paddingValue);
+        break;
+        }
+      }
+    ++outputIt;
+    }
+  
+  }
+
+
 template<class TInputImage, class TOutputImage, class TDeformationField>
 void
 StreamingWarpImageFilter<TInputImage, TOutputImage, TDeformationField>
-- 
GitLab