Skip to content
Snippets Groups Projects
otbSARESDOffsetsImageFilter.txx 5.24 KiB
/*
 * Copyright (C) 2005-2018 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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
 *
 * 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.
 */

#ifndef otbSARESDOffsetsImageFilter_txx
#define otbSARESDOffsetsImageFilter_txx

#include "otbSARESDOffsetsImageFilter.h"

#include "itkImageScanlineConstIterator.h"
#include "itkImageScanlineIterator.h"
#include "itkProgressReporter.h"
#include "itkNumericTraitsPointPixel.h"

#include <cmath>
#include <algorithm>

namespace otb
{
  /** 
   * Constructor with default initialization
   */
  template <class TImage> 
  SARESDOffsetsImageFilter< TImage >::SARESDOffsetsImageFilter()
    :  m_PhaseDiffMean(0), m_AziTimeInt(0), m_FirstEstimation(true)
  {
    // Inputs required and/or needed
    this->SetNumberOfRequiredInputs(2);
  }
    
  /** 
   * Destructor
   */
  template <class TImage> 
  SARESDOffsetsImageFilter< TImage >::~SARESDOffsetsImageFilter()
  {
   
  }

  /**
   * Print
   */
  template<class TImage>
  void
  SARESDOffsetsImageFilter< TImage >
  ::PrintSelf(std::ostream & os, itk::Indent indent) const
  {
    Superclass::PrintSelf(os, indent);
  }

   /**
   * Set Image 1 (Dop Centroid 1)
   */ 
  template<class TImage>
  void
  SARESDOffsetsImageFilter< TImage >
  ::SetInput1(const ImageType* image )
  {
    // Process object is not const-correct so the const casting is required.
    this->SetNthInput(0, const_cast<ImageType *>(image));
  }

  /**
   * Set Image 2 (Dop Centroid 2)
   */ 
  template<class TImage>
  void
  SARESDOffsetsImageFilter< TImage >
  ::SetInput2(const ImageType* image)
  {
    // Process object is not const-correct so the const casting is required.
    this->SetNthInput(1, const_cast<ImageType *>(image));
  }

  /**
   * Get Image 1 (Dop Centroid 1)
   */ 
  template<class TImage>
  const typename SARESDOffsetsImageFilter< TImage >::ImageType *
  SARESDOffsetsImageFilter< TImage >
  ::GetInput1() const
  {
    if (this->GetNumberOfInputs()<1)
      {
	return 0;
      }
    return static_cast<const ImageType *>(this->itk::ProcessObject::GetInput(0));
  }

  /**
   * Get Image 2 (Dop Centroid 2)
   */ 
  template<class TImage>
  const typename SARESDOffsetsImageFilter< TImage >::ImageType *
  SARESDOffsetsImageFilter< TImage >
  ::GetInput2() const
  {
    if (this->GetNumberOfInputs()<2)
      {
	return 0;
      }
    return static_cast<const ImageType *>(this->itk::ProcessObject::GetInput(1));
  }

  
  /** 
   * Method GenerateInputRequestedRegion
   */
  template<class TImage>
  void
  SARESDOffsetsImageFilter< TImage >
  ::GenerateInputRequestedRegion()
  {
    // call the superclass' implementation of this method
    Superclass::GenerateInputRequestedRegion();
    
    // Get Output requested region
    ImageRegionType outputRequestedRegion = this->GetOutput()->GetRequestedRegion();

     ///////////// For Input images same region  /////////////
    ImagePointer  input1Ptr = const_cast< ImageType * >( this->GetInput1() );
    input1Ptr->SetRequestedRegion(outputRequestedRegion);

    ImagePointer  input2Ptr = const_cast< ImageType * >( this->GetInput2() );
    input2Ptr->SetRequestedRegion(outputRequestedRegion);
  }
  
  /**
   * Method ThreadedGenerateData
   */
  template<class TImage>
  void
  SARESDOffsetsImageFilter<TImage>
  ::ThreadedGenerateData(const ImageRegionType & outputRegionForThread,
			 itk::ThreadIdType /*threadId*/)
  {
    // Compute corresponding input region for master and slave cartesian mean
    ImageRegionType inputRegionForThread = outputRegionForThread;

    // Iterator on output
    OutputIterator OutIt(this->GetOutput(), outputRegionForThread);
    OutIt.GoToBegin();

    // Iterator on inputs
    InputIterator  In1It(this->GetInput1(), inputRegionForThread);
    InputIterator  In2It(this->GetInput2(), inputRegionForThread);
    In1It.GoToBegin();
    In2It.GoToBegin();

    // For each line
    while (!OutIt.IsAtEnd() && !In1It.IsAtEnd() && !In2It.IsAtEnd())
      {
	OutIt.GoToBeginOfLine();
	In1It.GoToBeginOfLine();
	In2It.GoToBeginOfLine();

	// For each colunm
	while (!OutIt.IsAtEndOfLine() && !In1It.IsAtEndOfLine() && !In2It.IsAtEndOfLine()) 
	  {
	    double diff_DopCentroid = In1It.Get() - In2It.Get();

	    // Shift for azimut dimension
	    ImagePixelType azimut_shift = static_cast<ImagePixelType>(0);

	    if(std::abs(diff_DopCentroid) > 1e-5)
	      {
		azimut_shift = static_cast<ImagePixelType>(m_PhaseDiffMean/
							   (m_AziTimeInt*2*M_PI*diff_DopCentroid));
	      }
   	    
	    //////////// Assign Output ////////////
	    OutIt.Set(azimut_shift);

	    // Increment iterators
	    ++OutIt;
	    ++In1It;
	    ++In2It;
	  } // End colunms (ouput)

	// Next Line
	OutIt.NextLine();
	In1It.NextLine();
	In2It.NextLine();
      } // End lines (ouput)
  }


} /*namespace otb*/

#endif