From 95aab86b94ff957bfbc8d36f301a960a7522bd42 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ga=C3=ABlle=20USSEGLIO?= <gaelle.usseglio@cnes.fr>
Date: Wed, 22 Apr 2020 15:27:11 +0000
Subject: [PATCH] BUG : Correction for Correlation Bug Memory (protection into
 correlation applications)

---
 app/otbSARCorrelationGrid.cxx                 | 38 ++++++++++-----
 app/otbSARCorrelationRough.cxx                | 48 ++++++++-----------
 app/otbSARFineDeformationGrid.cxx             |  3 ++
 ...bSARStreamingMaximumMinimumImageFilter.txx |  5 --
 4 files changed, 48 insertions(+), 46 deletions(-)

diff --git a/app/otbSARCorrelationGrid.cxx b/app/otbSARCorrelationGrid.cxx
index ca3c8b4..27bf362 100644
--- a/app/otbSARCorrelationGrid.cxx
+++ b/app/otbSARCorrelationGrid.cxx
@@ -21,9 +21,10 @@
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
 
+#include "itkMacro.h"
 #include "itkFFTNormalizedCorrelationImageFilter.h"
-#include "itkMinimumMaximumImageCalculator.h"
 
+#include "otbSARStreamingMaximumMinimumImageFilter.h"
 #include "otbSARTemporalCorrelationGridImageFilter.h"
 
 #include <iostream>
@@ -46,7 +47,7 @@ public:
 
   // Filters
   typedef itk::FFTNormalizedCorrelationImageFilter<FloatImageType, FloatImageType>          CorFilterType;
-  typedef itk::MinimumMaximumImageCalculator< FloatImageType>			            MinMaxCalculatorType;
+  typedef otb::SARStreamingMaximumMinimumImageFilter< FloatImageType>		   MinMaxFilterType;
   typedef otb::SARTemporalCorrelationGridImageFilter<FloatImageType, FloatVectorImageType>  CorGridFilterType;
   
 
@@ -134,28 +135,41 @@ void DoExecute() override
   otbAppLogINFO(<<"ML Factor on range : "<<factorML_ran);
   otbAppLogINFO(<<"Grid Step for range : "<<grid_step_ran);
   otbAppLogINFO(<<"Grid Step for azimut : "<<grid_step_azi);
-
+ 
   // Get master and slave image
   FloatImageType::Pointer MasterPtr = GetParameterFloatImage("inmaster");
   FloatImageType::Pointer SlavePtr = GetParameterFloatImage("inslave");
    
-  
+  // Check input size (Master size) to protect memory. 
+  // If size > 15000 raise an exception and indicate more appropriate ml factors
+  if (MasterPtr->GetLargestPossibleRegion().GetSize()[0] > 15000 || 
+      MasterPtr->GetLargestPossibleRegion().GetSize()[1] > 15000)
+    {
+      // integer divisions
+      int intermediate_mlran = MasterPtr->GetLargestPossibleRegion().GetSize()[0]/15000 + 1;
+      int intermediate_mlazi = MasterPtr->GetLargestPossibleRegion().GetSize()[1]/15000 + 1;
+
+      otbAppLogCRITICAL(<<"ML Factors are not appropriate for these estimations. Please use other factors such as : "<< intermediate_mlran << " x " << intermediate_mlazi );
+
+      itkExceptionMacro(<<"ML Factors are not appropriate for these estimations");
+    }
+
   // Correlation Filter
   CorFilterType::Pointer correlationFilter = CorFilterType::New();
   m_Ref.push_back(correlationFilter.GetPointer());
   correlationFilter->SetFixedImage(MasterPtr);
   correlationFilter->SetMovingImage(SlavePtr);
-  correlationFilter->Update();
-
-  // Min/Max calculator
-  MinMaxCalculatorType::Pointer minMaxFilter = MinMaxCalculatorType::New();
-  minMaxFilter->SetImage(correlationFilter->GetOutput());
-  minMaxFilter->ComputeMaximum();
+  
+  MinMaxFilterType::Pointer minMaxFilter = MinMaxFilterType::New();
+  minMaxFilter->SetInput(correlationFilter->GetOutput());
+  // Adapt streaming with ram parameter (default 256 MB)
+  minMaxFilter->GetStreamer()->SetAutomaticStrippedStreaming(GetParameterInt("ram"));
+  minMaxFilter->Update();
 
   float shiftML_range = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2.)-
-			  minMaxFilter->GetIndexOfMaximum()[0]);
+			  minMaxFilter->GetIndexOfMax()[0]);
   float shiftML_azimut = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[1]/2.)
-  -minMaxFilter->GetIndexOfMaximum()[1]);
+			   -minMaxFilter->GetIndexOfMax()[1]);
 
   // Correlation Grid Filter 
   CorGridFilterType::Pointer filterCorrelationGrid = CorGridFilterType::New();
diff --git a/app/otbSARCorrelationRough.cxx b/app/otbSARCorrelationRough.cxx
index 5d9f4fa..36f6668 100644
--- a/app/otbSARCorrelationRough.cxx
+++ b/app/otbSARCorrelationRough.cxx
@@ -21,8 +21,8 @@
 #include "otbWrapperApplication.h"
 #include "otbWrapperApplicationFactory.h"
 
+#include "itkMacro.h"
 #include "itkFFTNormalizedCorrelationImageFilter.h"
-#include "itkMinimumMaximumImageCalculator.h"
 
 #include "otbSARStreamingMaximumMinimumImageFilter.h"
 
@@ -44,10 +44,9 @@ public:
   itkNewMacro(Self);
   itkTypeMacro(SARCorrelationRough, otb::Wrapper::Application);
 
-// Filters
-typedef itk::FFTNormalizedCorrelationImageFilter<FloatImageType, FloatImageType> CorFilterType;
-typedef itk::MinimumMaximumImageCalculator< FloatImageType>			    MinMaxCalculatorType;
-typedef otb::SARStreamingMaximumMinimumImageFilter< FloatImageType>			    MinMaxFilterType;
+  // Filters
+  typedef itk::FFTNormalizedCorrelationImageFilter<FloatImageType, FloatImageType> CorFilterType;
+  typedef otb::SARStreamingMaximumMinimumImageFilter< FloatImageType>		   MinMaxFilterType;
 
 private:
   void DoInit() override
@@ -132,21 +131,27 @@ void DoExecute() override
   // Get master and slave image
   FloatImageType::Pointer MasterPtr = GetParameterFloatImage("inmaster");
   FloatImageType::Pointer SlavePtr = GetParameterFloatImage("inslave");
-   
+  
+  // Check input size (Master size) to protect memory. 
+  // If size > 15000 raise an exception and indicate more appropriate ml factors
+  if (MasterPtr->GetLargestPossibleRegion().GetSize()[0] > 15000 || 
+      MasterPtr->GetLargestPossibleRegion().GetSize()[1] > 15000)
+    {
+      // integer divisions
+      int intermediate_mlran = MasterPtr->GetLargestPossibleRegion().GetSize()[0]/15000 + 1;
+      int intermediate_mlazi = MasterPtr->GetLargestPossibleRegion().GetSize()[1]/15000 + 1;
+
+      otbAppLogCRITICAL(<<"ML Factors are not appropriate for these estimations. Please use other factors such as : "<< intermediate_mlran << " x " << intermediate_mlazi );
+
+      itkExceptionMacro(<<"ML Factors are not appropriate for these estimations");
+    }
+ 
   
   // Correlation Filter
   CorFilterType::Pointer correlationFilter = CorFilterType::New();
   m_Ref.push_back(correlationFilter.GetPointer());
   correlationFilter->SetFixedImage(MasterPtr);
   correlationFilter->SetMovingImage(SlavePtr);
-  //correlationFilter->Update();
-
-  // Min/Max calculator
-  // MinMaxCalculatorType::Pointer minMaxFilter = MinMaxCalculatorType::New();
-  // minMaxFilter->SetImage(correlationFilter->GetOutput());
-  // minMaxFilter->ComputeMaximum();
-
-
 
   MinMaxFilterType::Pointer minMaxFilter = MinMaxFilterType::New();
   minMaxFilter->SetInput(correlationFilter->GetOutput());
@@ -154,21 +159,6 @@ void DoExecute() override
   minMaxFilter->GetStreamer()->SetAutomaticStrippedStreaming(GetParameterInt("ram"));
   minMaxFilter->Update();
 
-  
-  std::cout << "minMaxFilter->GetIndexOfMax() : " << minMaxFilter->GetIndexOfMax() << std::endl;
-  std::cout << "minMaxFilter->GetMax() : " << minMaxFilter->GetMax() << std::endl;
-
-  
-  // float shiftSLC_range = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2.)-
-  // 		       minMaxFilter->GetIndexOfMaximum()[0]) * static_cast<float>(factorML_ran);
-  // float shiftSLC_azimut = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[1]/2.)
-  // 			-minMaxFilter->GetIndexOfMaximum()[1]) * static_cast<float>(factorML_azi);
-
-  // float shiftML_range = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2.)-
-  // 			  minMaxFilter->GetIndexOfMaximum()[0]);
-  // float shiftML_azimut = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[1]/2.)
-  // 			   -minMaxFilter->GetIndexOfMaximum()[1]);
-
 
   float shiftSLC_range = ((correlationFilter->GetOutput()->GetLargestPossibleRegion().GetSize()[0]/2.)-
 		       minMaxFilter->GetIndexOfMax()[0]) * static_cast<float>(factorML_ran);
diff --git a/app/otbSARFineDeformationGrid.cxx b/app/otbSARFineDeformationGrid.cxx
index cbbe0cb..b65d7e9 100644
--- a/app/otbSARFineDeformationGrid.cxx
+++ b/app/otbSARFineDeformationGrid.cxx
@@ -193,6 +193,7 @@ private:
     GetInternalApplication("CorGridApp")->SetParameterInt("mlazi", factor_azi);
     GetInternalApplication("CorGridApp")->SetParameterInt("gridsteprange", grid_step_ran);
     GetInternalApplication("CorGridApp")->SetParameterInt("gridstepazimut", grid_step_azi);
+    GetInternalApplication("CorGridApp")->SetParameterInt("ram", GetParameterInt("ram"));
     //if (demGridToFavor)
       {
 	GetInternalApplication("CorGridApp")->SetParameterInt("nooffset", 1);
@@ -215,6 +216,7 @@ private:
     GetInternalApplication("DEMGridApp")->SetParameterInt("mlazi", factor_azi);
     GetInternalApplication("DEMGridApp")->SetParameterInt("gridsteprange", grid_step_ran);
     GetInternalApplication("DEMGridApp")->SetParameterInt("gridstepazimut", grid_step_azi);
+    GetInternalApplication("DEMGridApp")->SetParameterInt("ram", GetParameterInt("ram"));
     ExecuteInternal("DEMGridApp");
     
     // Third (and last) application : SARMultiLook
@@ -225,6 +227,7 @@ private:
     GetInternalApplication("CorrectionGridApp")->SetParameterFloat("threshold", threshold);
     GetInternalApplication("CorrectionGridApp")->SetParameterFloat("gap", gap);
     GetInternalApplication("CorrectionGridApp")->SetParameterString("advantage", advantage);
+    GetInternalApplication("CorrectionGridApp")->SetParameterInt("ram", GetParameterInt("ram"));
     ExecuteInternal("CorrectionGridApp");
     
     // Retrive the output of CorrectionGridApp
diff --git a/include/otbSARStreamingMaximumMinimumImageFilter.txx b/include/otbSARStreamingMaximumMinimumImageFilter.txx
index 1a5840e..033d539 100644
--- a/include/otbSARStreamingMaximumMinimumImageFilter.txx
+++ b/include/otbSARStreamingMaximumMinimumImageFilter.txx
@@ -245,11 +245,6 @@ PersistentMaximumMinimumImageFilter<TInputImage>
   this->GetIndexOfMaxOutput()->Set(maxIndex);
   this->GetMinOutput()->Set(minValue);
   this->GetMaxOutput()->Set(maxValue);
-
-  std::cout << "maxValue : " << maxValue << std::endl;
-  std::cout << "this->GetMax() : " << this->GetMax() << std::endl;
-  
-
 }
 
 template<class TInputImage>
-- 
GitLab