<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$


  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.


     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef __otbTextureFunctorBase_h
#define __otbTextureFunctorBase_h

#include "otbMath.h"
#include "itkMacro.h"
#include "itkNumericTraits.h"
#include "itkNeighborhood.h"


namespace otb
{
namespace Functor
{
/** \class TextureFunctorBase
 *  \brief This functor ius the base for all texture functors.
 *
 *  It uses a neighborhood and an offset (m_Offset)  to compute texture.
 *  It computes the mean, standard deviation of the two areas and the joint histogram using
 *  Scott formula for the bins lengths computation.
 *  TIterInput is an iterator, TOutput is a PixelType.
 *
 *  \ingroup Functor 
 *  \ingroup Statistics
 */

template <class TIterInput, class TOutput>
class TextureFunctorBase
{
public:
  TextureFunctorBase()
  {
    m_Offset.Fill(1);
    m_Mini = itk::NumericTraits<double>::max();
    m_MiniOff = itk::NumericTraits<double>::max();
    m_Maxi = itk::NumericTraits<double>::NonpositiveMin();
    m_MaxiOff = itk::NumericTraits<double>::NonpositiveMin();
    m_Mean = 0.;
    m_MeanOff = 0.;
    m_Std = 0.;
    m_StdOff = 0.;
    m_NeighBinLength = 0;
    m_OffsetBinLength = 0;
    m_Histo.clear();
  };
  virtual ~TextureFunctorBase() {};

  typedef TIterInput                           IterType;
  typedef TOutput                              OutputType;
  typedef typename IterType::OffsetType        OffsetType;
  typedef typename IterType::RadiusType        RadiusType;
  typedef typename OutputType::ValueType       OutputPixelType;
  typedef typename IterType::InternalPixelType InternalPixelType;
  typedef typename IterType::ImageType         ImageType;
  typedef itk::Neighborhood<InternalPixelType, ::itk::GetImageDimension<ImageType>::ImageDimension>    NeighborhoodType;
  typedef std::vector<double>                   DoubleVectorType;
  typedef std::vector<int>                      IntVectorType;
  typedef std::vector<IntVectorType>            IntVectorVectorType;


  void SetOffset(OffsetType off){ m_Offset=off; };
  OffsetType GetOffset(){ return m_Offset; };
  double GetMaxi(){ return m_Maxi; };
  double GetMini(){ return m_Mini; };
  double GetMaxiOff(){ return m_MaxiOff; };
  double GetMiniOff(){ return m_MiniOff; };
  double GetMean(){ return m_Mean; };
  double GetMeanOff(){ return m_MeanOff; };
  double GetStd(){ return m_Std; };
  double GetStdOff(){ return m_StdOff;};
  double GetNeighBinLength(){ return m_NeighBinLength; };
  double GetOffsetBinLength(){ return m_OffsetBinLength; };
  IntVectorVectorType GetHisto(){ return m_Histo; };

 /** Computes the histogram bins using Scott formula, plus min/max, means, stds */
  void StatComputation(const NeighborhoodType &neigh, const NeighborhoodType &neighOff)
    {
      double binLength    = 0;
      double binLengthOff =0;
      m_Mean = 0.;
      m_MeanOff = 0.;
      m_Std = 0.;
      m_StdOff = 0.;
      RadiusType radius = neigh.GetRadius();
      m_Mini = itk::NumericTraits<double>::max();
      m_MiniOff = itk::NumericTraits<double>::max();
      m_Maxi = itk::NumericTraits<double>::NonpositiveMin();
      m_MaxiOff = itk::NumericTraits<double>::NonpositiveMin();
      double area = static_cast<double>(neigh.GetSize()[0]*neigh.GetSize()[1]);
      double areaInv = 1/area;
      double scottCoef =  3.5 /(vcl_pow(area, 1/3) );
      
      OffsetType offset;
      offset.Fill(0);
      OffsetType offsetOff;
      OffsetType offsetOffInit;
      
      offsetOffInit[0] = -radius[0]+this->GetOffset()[0]-1;
      offsetOffInit[1] = -radius[1]+this->GetOffset()[1]-1;
      
      offsetOff = offsetOffInit;
      for ( int l = -static_cast<int>(radius[0]); l <= static_cast<int>(radius[0]); l++ )
	{
	  offsetOff[0]++;
	  offsetOff[1] = offsetOffInit[1];
	  offset[0] = l;
	  for ( int k = -static_cast<int>(radius[1]); k <= static_cast<int>(radius[1]); k++)
	    {
	      offsetOff[1]++;
	      offset[1] = k;
	      m_Mean += static_cast<double>(neigh[offset]);
	      m_MeanOff += static_cast<double>(neighOff[offsetOff]);
	    
	      m_Mini    = std::min(static_cast<double>(neigh[offset]),      m_Mini);
	      m_Maxi    = std::max(static_cast<double>(neigh[offset]),      m_Maxi);
	      m_MiniOff = std::min(static_cast<double>(neighOff[offsetOff]),m_MiniOff);
	      m_MaxiOff = std::max(static_cast<double>(neighOff[offsetOff]),m_MaxiOff);
	    }
	}
      m_Mean *= areaInv;
      m_MeanOff *= areaInv;
    
      offsetOff = offsetOffInit;
 
      for( int l = -static_cast<int>(radius[0]); l <= static_cast<int>(radius[0]); l++ )
	{
	  offsetOff[0]++;
	  offsetOff[1] = offsetOffInit[1];  
	  offset[0] = l;
	  for( int k = -static_cast<int>(radius[1]); k <= static_cast<int>(radius[1]); k++)
	    {
	      offsetOff[1]++;
	      offset[1] = k;
	      binLength += vcl_pow( (m_Mean-static_cast<double>(neigh[offset])), 2);
	      binLengthOff += vcl_pow( (m_MeanOff-static_cast<double>(neighOff[offsetOff])), 2);
	    }
	}
    
      binLength *= areaInv;
      binLength = vcl_sqrt( binLength );
      binLengthOff *= areaInv;
      binLengthOff = vcl_sqrt( binLengthOff );
      m_Std = binLength;
      m_StdOff = binLengthOff;

      m_NeighBinLength = scottCoef*binLength;
      m_OffsetBinLength = scottCoef*binLengthOff;     
    }

  inline TOutput operator()(const IterType &itOff)
    { 
      RadiusType radiusOff = itOff.GetRadius();
      OutputType outPix;
      outPix.SetSize( itOff.GetCenterPixel().GetSize() );
      outPix.Fill(0);
      OffsetType offset;
      offset.Fill(0);
      RadiusType radius;
      radius[0] = 0.5*( itOff.GetSize()[0] - 1 ) - vcl_abs(m_Offset[0]);
      radius[1] = 0.5*( itOff.GetSize()[1] - 1 ) - vcl_abs(m_Offset[1]);
  
      for ( unsigned int i=0; i<itOff.GetCenterPixel().GetSize(); i++ )
	{
	  NeighborhoodType inNeigh;
	  inNeigh.SetRadius(radius);
	  NeighborhoodType offNeigh;
	  offNeigh.SetRadius(radiusOff);
	  
	  for ( int l = -static_cast<int>(radius[0]); l <= static_cast<int>(radius[0]); l++ )
	    {
	      offset[0] = l;
	      for ( int k = -static_cast<int>(radius[1]); k <= static_cast<int>(radius[1]); k++)
		{
		  offset[1] = k;
		  inNeigh[offset] = itOff.GetPixel(offset)[i];
		}
	    }
	  offset.Fill(0);
	  for ( int l = -static_cast<int>(radiusOff[0]); l <= static_cast<int>(radiusOff[0]); l++ )
	    {
	      offset[0] = l;
	      for ( int k = -static_cast<int>(radiusOff[1]); k <= static_cast<int>(radiusOff[1]); k++)
		{
		  offset[1] = k;
		  offNeigh[offset] = itOff.GetPixel(offset)[i];<commit_msg>WRG : cast<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$


  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.


     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef __otbTextureFunctorBase_h
#define __otbTextureFunctorBase_h

#include "otbMath.h"
#include "itkMacro.h"
#include "itkNumericTraits.h"
#include "itkNeighborhood.h"


namespace otb
{
namespace Functor
{
/** \class TextureFunctorBase
 *  \brief This functor ius the base for all texture functors.
 *
 *  It uses a neighborhood and an offset (m_Offset)  to compute texture.
 *  It computes the mean, standard deviation of the two areas and the joint histogram using
 *  Scott formula for the bins lengths computation.
 *  TIterInput is an iterator, TOutput is a PixelType.
 *
 *  \ingroup Functor 
 *  \ingroup Statistics
 */

template <class TIterInput, class TOutput>
class TextureFunctorBase
{
public:
  TextureFunctorBase()
  {
    m_Offset.Fill(1);
    m_Mini = itk::NumericTraits<double>::max();
    m_MiniOff = itk::NumericTraits<double>::max();
    m_Maxi = itk::NumericTraits<double>::NonpositiveMin();
    m_MaxiOff = itk::NumericTraits<double>::NonpositiveMin();
    m_Mean = 0.;
    m_MeanOff = 0.;
    m_Std = 0.;
    m_StdOff = 0.;
    m_NeighBinLength = 0;
    m_OffsetBinLength = 0;
    m_Histo.clear();
  };
  virtual ~TextureFunctorBase() {};

  typedef TIterInput                           IterType;
  typedef TOutput                              OutputType;
  typedef typename IterType::OffsetType        OffsetType;
  typedef typename IterType::RadiusType        RadiusType;
  typedef typename OutputType::ValueType       OutputPixelType;
  typedef typename IterType::InternalPixelType InternalPixelType;
  typedef typename IterType::ImageType         ImageType;
  typedef itk::Neighborhood<InternalPixelType, ::itk::GetImageDimension<ImageType>::ImageDimension>    NeighborhoodType;
  typedef std::vector<double>                   DoubleVectorType;
  typedef std::vector<int>                      IntVectorType;
  typedef std::vector<IntVectorType>            IntVectorVectorType;


  void SetOffset(OffsetType off){ m_Offset=off; };
  OffsetType GetOffset(){ return m_Offset; };
  double GetMaxi(){ return m_Maxi; };
  double GetMini(){ return m_Mini; };
  double GetMaxiOff(){ return m_MaxiOff; };
  double GetMiniOff(){ return m_MiniOff; };
  double GetMean(){ return m_Mean; };
  double GetMeanOff(){ return m_MeanOff; };
  double GetStd(){ return m_Std; };
  double GetStdOff(){ return m_StdOff;};
  double GetNeighBinLength(){ return m_NeighBinLength; };
  double GetOffsetBinLength(){ return m_OffsetBinLength; };
  IntVectorVectorType GetHisto(){ return m_Histo; };

 /** Computes the histogram bins using Scott formula, plus min/max, means, stds */
  void StatComputation(const NeighborhoodType &neigh, const NeighborhoodType &neighOff)
    {
      double binLength    = 0;
      double binLengthOff =0;
      m_Mean = 0.;
      m_MeanOff = 0.;
      m_Std = 0.;
      m_StdOff = 0.;
      RadiusType radius = neigh.GetRadius();
      m_Mini = itk::NumericTraits<double>::max();
      m_MiniOff = itk::NumericTraits<double>::max();
      m_Maxi = itk::NumericTraits<double>::NonpositiveMin();
      m_MaxiOff = itk::NumericTraits<double>::NonpositiveMin();
      double area = static_cast<double>(neigh.GetSize()[0]*neigh.GetSize()[1]);
      double areaInv = 1/area;
      double scottCoef =  3.5 /(vcl_pow(area, 1/3) );
      
      OffsetType offset;
      offset.Fill(0);
      OffsetType offsetOff;
      OffsetType offsetOffInit;
      
      offsetOffInit[0] = -radius[0]+this->GetOffset()[0]-1;
      offsetOffInit[1] = -radius[1]+this->GetOffset()[1]-1;
      
      offsetOff = offsetOffInit;
      for ( int l = -static_cast<int>(radius[0]); l <= static_cast<int>(radius[0]); l++ )
	{
	  offsetOff[0]++;
	  offsetOff[1] = offsetOffInit[1];
	  offset[0] = l;
	  for ( int k = -static_cast<int>(radius[1]); k <= static_cast<int>(radius[1]); k++)
	    {
	      offsetOff[1]++;
	      offset[1] = k;
	      m_Mean += static_cast<double>(neigh[offset]);
	      m_MeanOff += static_cast<double>(neighOff[offsetOff]);
	    
	      m_Mini    = std::min(static_cast<double>(neigh[offset]),      m_Mini);
	      m_Maxi    = std::max(static_cast<double>(neigh[offset]),      m_Maxi);
	      m_MiniOff = std::min(static_cast<double>(neighOff[offsetOff]),m_MiniOff);
	      m_MaxiOff = std::max(static_cast<double>(neighOff[offsetOff]),m_MaxiOff);
	    }
	}
      m_Mean *= areaInv;
      m_MeanOff *= areaInv;
    
      offsetOff = offsetOffInit;
 
      for( int l = -static_cast<int>(radius[0]); l <= static_cast<int>(radius[0]); l++ )
	{
	  offsetOff[0]++;
	  offsetOff[1] = offsetOffInit[1];  
	  offset[0] = l;
	  for( int k = -static_cast<int>(radius[1]); k <= static_cast<int>(radius[1]); k++)
	    {
	      offsetOff[1]++;
	      offset[1] = k;
	      binLength += vcl_pow( (m_Mean-static_cast<double>(neigh[offset])), 2);
	      binLengthOff += vcl_pow( (m_MeanOff-static_cast<double>(neighOff[offsetOff])), 2);
	    }
	}
    
      binLength *= areaInv;
      binLength = vcl_sqrt( binLength );
      binLengthOff *= areaInv;
      binLengthOff = vcl_sqrt( binLengthOff );
      m_Std = binLength;
      m_StdOff = binLengthOff;

      m_NeighBinLength = scottCoef*binLength;
      m_OffsetBinLength = scottCoef*binLengthOff;     
    }

  inline TOutput operator()(const IterType &itOff)
    { 
      RadiusType radiusOff = itOff.GetRadius();
      OutputType outPix;
      outPix.SetSize( itOff.GetCenterPixel().GetSize() );
      outPix.Fill(0);
      OffsetType offset;
      offset.Fill(0);
      RadiusType radius;
      radius[0] = static_cast<unsigned int>( 0.5*( static_cast<double>(itOff.GetSize()[0] - 1) ) - static_cast<double>( vcl_abs(m_Offset[0])) );
      radius[1] = static_cast<unsigned int>( 0.5*( static_cast<double>(itOff.GetSize()[1] - 1) ) - static_cast<double>( vcl_abs(m_Offset[1])) );
  
      for ( unsigned int i=0; i<itOff.GetCenterPixel().GetSize(); i++ )
	{
	  NeighborhoodType inNeigh;
	  inNeigh.SetRadius(radius);
	  NeighborhoodType offNeigh;
	  offNeigh.SetRadius(radiusOff);
	  
	  for ( int l = -static_cast<int>(radius[0]); l <= static_cast<int>(radius[0]); l++ )
	    {
	      offset[0] = l;
	      for ( int k = -static_cast<int>(radius[1]); k <= static_cast<int>(radius[1]); k++)
		{
		  offset[1] = k;
		  inNeigh[offset] = itOff.GetPixel(offset)[i];
		}
	    }
	  offset.Fill(0);
	  for ( int l = -static_cast<int>(radiusOff[0]); l <= static_cast<int>(radiusOff[0]); l++ )
	    {
	      offset[0] = l;
	      for ( int k = -static_cast<int>(radiusOff[1]); k <= static_cast<int>(radiusOff[1]); k++)
		{
		  offset[1] = k;
		  offNeigh[offset] = itOff.GetPixel(offset)[i];
{'fraction_non_alphanumeric': 0.15335169880624427, 'fraction_numerical': 0.01116055661510207, 'mean_word_length': 3.40921831205232, 'pattern_counts': {'":': 0, '<': 105, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1780747', 'n_tokens_mistral': 4936, 'n_tokens_neox': 4635, 'n_words': 978}