/*=========================================================================
*
*  Copyright NumFOCUS
*
*  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.txt
*
*  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 sitkOtsuMultipleThresholdsImageFilter_h
#define sitkOtsuMultipleThresholdsImageFilter_h

/*
 * WARNING: DO NOT EDIT THIS FILE!
 * THIS FILE IS AUTOMATICALLY GENERATED BY THE SIMPLEITK BUILD PROCESS.
 * Please look at sitkImageFilterTemplate.h.in to make changes.
 */

#include <memory>

#include "sitkBasicFilters.h"
#include "sitkImageFilter.h"

namespace itk::simple {

    /**\class OtsuMultipleThresholdsImageFilter
\brief Threshold an image using multiple Otsu Thresholds.

This filter creates a labeled image that separates the input image into various classes. The filter computes the thresholds using the OtsuMultipleThresholdsCalculator and applies those thresholds to the input image using the ThresholdLabelerImageFilter . The NumberOfHistogramBins and NumberOfThresholds can be set for the Calculator. The LabelOffset can be set for the ThresholdLabelerImageFilter .

This filter also includes an option to use the valley emphasis algorithm from H.F. Ng, "Automatic thresholding for defect detection", Pattern Recognition Letters, (27): 1644-1649, 2006. The valley emphasis algorithm is particularly effective when the object to be thresholded is small. See the following tests for examples: itkOtsuMultipleThresholdsImageFilterTest3 and itkOtsuMultipleThresholdsImageFilterTest4 To use this algorithm, simple call the setter: SetValleyEmphasis(true) It is turned off by default.

\see ScalarImageToHistogramGenerator 


\see OtsuMultipleThresholdsCalculator 


\see ThresholdLabelerImageFilter
\sa itk::simple::OtsuMultipleThresholds for the procedural interface
\sa itk::OtsuMultipleThresholdsImageFilter for the Doxygen on the original ITK class.
     */
    class SITKBasicFilters_EXPORT OtsuMultipleThresholdsImageFilter : public ImageFilter {
    public:
      using Self = OtsuMultipleThresholdsImageFilter;

      /** Destructor */
      virtual ~OtsuMultipleThresholdsImageFilter();

      /** Default Constructor that takes no arguments and initializes
       * default parameters */
      OtsuMultipleThresholdsImageFilter();

      /** Define the pixels types supported by this filter */
      using PixelIDTypeList = BasicPixelIDTypeList;
\

      /**
       * Set/Get the number of thresholds. Default is 1.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetNumberOfThresholds ( uint8_t NumberOfThresholds ) { this->m_NumberOfThresholds = NumberOfThresholds; return *this; }

      /**
       * Set/Get the number of thresholds. Default is 1.
       */
      uint8_t GetNumberOfThresholds() const { return this->m_NumberOfThresholds; }\

      /**
       * Set/Get the offset which labels have to start from. Default is 0.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetLabelOffset ( uint8_t LabelOffset ) { this->m_LabelOffset = LabelOffset; return *this; }

      /**
       * Set/Get the offset which labels have to start from. Default is 0.
       */
      uint8_t GetLabelOffset() const { return this->m_LabelOffset; }\

      /**
       * Set/Get the number of histogram bins. Default is 128.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetNumberOfHistogramBins ( uint32_t NumberOfHistogramBins ) { this->m_NumberOfHistogramBins = NumberOfHistogramBins; return *this; }

      /**
       * Set/Get the number of histogram bins. Default is 128.
       */
      uint32_t GetNumberOfHistogramBins() const { return this->m_NumberOfHistogramBins; }\

      /**
       * Set/Get the use of valley emphasis. Default is false.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetValleyEmphasis ( bool ValleyEmphasis ) { this->m_ValleyEmphasis = ValleyEmphasis; return *this; }

      /** Set the value of ValleyEmphasis to true or false respectfully. */
      SITK_RETURN_SELF_TYPE_HEADER ValleyEmphasisOn() { return this->SetValleyEmphasis(true); }
      SITK_RETURN_SELF_TYPE_HEADER ValleyEmphasisOff() { return this->SetValleyEmphasis(false); }

      /**
       * Set/Get the use of valley emphasis. Default is false.
       */
      bool GetValleyEmphasis() const { return this->m_ValleyEmphasis; }\

      /**
       * Should the threshold value be mid-point of the bin or the maximum? Default is to return bin maximum.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetReturnBinMidpoint ( bool ReturnBinMidpoint ) { this->m_ReturnBinMidpoint = ReturnBinMidpoint; return *this; }

      /** Set the value of ReturnBinMidpoint to true or false respectfully. */
      SITK_RETURN_SELF_TYPE_HEADER ReturnBinMidpointOn() { return this->SetReturnBinMidpoint(true); }
      SITK_RETURN_SELF_TYPE_HEADER ReturnBinMidpointOff() { return this->SetReturnBinMidpoint(false); }

      /**
       * Should the threshold value be mid-point of the bin or the maximum? Default is to return bin maximum.
       */
      bool GetReturnBinMidpoint() const { return this->m_ReturnBinMidpoint; }
     /**
      * Get the computed threshold.
      *
      * This is a measurement. Its value is updated in the Execute
      * methods, so the value will only be valid after an execution.
      */
     std::vector<double> GetThresholds() const { return this->m_Thresholds; };


      /** Name of this class */
      std::string GetName() const { return std::string ("OtsuMultipleThresholdsImageFilter"); }

      /** Print ourselves out */
      std::string ToString() const;


      /** Execute the filter on the input image */

      Image Execute ( const Image& image1 );

    private:

      /** Setup for member function dispatching */

      using MemberFunctionType = Image (Self::*)( const Image& image1 );
      template <class TImageType> Image ExecuteInternal ( const Image& image1 );


      friend struct detail::MemberFunctionAddressor<MemberFunctionType>;

      std::unique_ptr<detail::MemberFunctionFactory<MemberFunctionType> > m_MemberFactory;


      uint8_t  m_NumberOfThresholds{1u};

      uint8_t  m_LabelOffset{0u};

      uint32_t  m_NumberOfHistogramBins{128u};

      /*  */
      bool  m_ValleyEmphasis{false};

      bool  m_ReturnBinMidpoint{false};


      std::vector<double> m_Thresholds{std::vector<double>()};


    };

    /**\
     * \brief Threshold an image using multiple Otsu Thresholds.
     *
     * This function directly calls the execute method of OtsuMultipleThresholdsImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::OtsuMultipleThresholdsImageFilter for the object oriented interface
     * @{
     */

     SITKBasicFilters_EXPORT Image OtsuMultipleThresholds ( const Image& image1, uint8_t numberOfThresholds = 1u, uint8_t labelOffset = 0u, uint32_t numberOfHistogramBins = 128u, bool valleyEmphasis = false, bool returnBinMidpoint = false );

     /** @} */
}
#endif
