/*=========================================================================
*
*  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 sitkDoubleThresholdImageFilter_h
#define sitkDoubleThresholdImageFilter_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 DoubleThresholdImageFilter
\brief Binarize an input image using double thresholding.

Double threshold addresses the difficulty in selecting a threshold that will select the objects of interest without selecting extraneous objects. Double threshold considers two threshold ranges: a narrow range and a wide range (where the wide range encompasses the narrow range). If the wide range was used for a traditional threshold (where values inside the range map to the foreground and values outside the range map to the background), many extraneous pixels may survive the threshold operation. If the narrow range was used for a traditional threshold, then too few pixels may survive the threshold.

Double threshold uses the narrow threshold image as a marker image and the wide threshold image as a mask image in the geodesic dilation. Essentially, the marker image (narrow threshold) is dilated but constrained to lie within the mask image (wide threshold). Thus, only the objects of interest (those pixels that survived the narrow threshold) are extracted but the those objects appear in the final image as they would have if the wide threshold was used.

\see GrayscaleGeodesicDilateImageFilter 


\see MorphologyImageFilter , GrayscaleDilateImageFilter , GrayscaleFunctionDilateImageFilter , BinaryDilateImageFilter
\sa itk::simple::DoubleThreshold for the procedural interface
\sa itk::DoubleThresholdImageFilter for the Doxygen on the original ITK class.
     */
    class SITKBasicFilters_EXPORT DoubleThresholdImageFilter : public ImageFilter {
    public:
      using Self = DoubleThresholdImageFilter;

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

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

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

      /**
       * Set the thresholds. Four thresholds should be specified. The two lower thresholds default to NumericTraits<InputPixelType>::NonpositiveMin() . The two upper thresholds default NumericTraits<InputPixelType>::max . Threshold1 <= Threshold2 <= Threshold3 <= Threshold4.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetThreshold1 ( double Threshold1 ) { this->m_Threshold1 = Threshold1; return *this; }

      /**
       * Get the threshold values.
       */
      double GetThreshold1() const { return this->m_Threshold1; }\

      /**
       * Set the thresholds. Four thresholds should be specified. The two lower thresholds default to NumericTraits<InputPixelType>::NonpositiveMin() . The two upper thresholds default NumericTraits<InputPixelType>::max . Threshold1 <= Threshold2 <= Threshold3 <= Threshold4.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetThreshold2 ( double Threshold2 ) { this->m_Threshold2 = Threshold2; return *this; }

      /**
       * Get the threshold values.
       */
      double GetThreshold2() const { return this->m_Threshold2; }\

      /**
       * Set the thresholds. Four thresholds should be specified. The two lower thresholds default to NumericTraits<InputPixelType>::NonpositiveMin() . The two upper thresholds default NumericTraits<InputPixelType>::max . Threshold1 <= Threshold2 <= Threshold3 <= Threshold4.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetThreshold3 ( double Threshold3 ) { this->m_Threshold3 = Threshold3; return *this; }

      /**
       * Get the threshold values.
       */
      double GetThreshold3() const { return this->m_Threshold3; }\

      /**
       * Set the thresholds. Four thresholds should be specified. The two lower thresholds default to NumericTraits<InputPixelType>::NonpositiveMin() . The two upper thresholds default NumericTraits<InputPixelType>::max . Threshold1 <= Threshold2 <= Threshold3 <= Threshold4.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetThreshold4 ( double Threshold4 ) { this->m_Threshold4 = Threshold4; return *this; }

      /**
       * Get the threshold values.
       */
      double GetThreshold4() const { return this->m_Threshold4; }\

      /**
       * Set the "inside" pixel value. The default value NumericTraits<OutputPixelType>::max()
       */
      SITK_RETURN_SELF_TYPE_HEADER SetInsideValue ( uint8_t InsideValue ) { this->m_InsideValue = InsideValue; return *this; }

      /**
       * Get the "inside" pixel value.
       */
      uint8_t GetInsideValue() const { return this->m_InsideValue; }\

      /**
       * Set the "outside" pixel value. The default value NumericTraits<OutputPixelType>::ZeroValue() .
       */
      SITK_RETURN_SELF_TYPE_HEADER SetOutsideValue ( uint8_t OutsideValue ) { this->m_OutsideValue = OutsideValue; return *this; }

      /**
       * Get the "outside" pixel value.
       */
      uint8_t GetOutsideValue() const { return this->m_OutsideValue; }\

      /**
       * Set/Get whether the connected components are defined strictly by face connectivity or by face+edge+vertex connectivity. Default is FullyConnectedOff. For objects that are 1 pixel wide, use FullyConnectedOn.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetFullyConnected ( bool FullyConnected ) { this->m_FullyConnected = FullyConnected; return *this; }

      /** Set the value of FullyConnected to true or false respectfully. */
      SITK_RETURN_SELF_TYPE_HEADER FullyConnectedOn() { return this->SetFullyConnected(true); }
      SITK_RETURN_SELF_TYPE_HEADER FullyConnectedOff() { return this->SetFullyConnected(false); }

      /**
       * Set/Get whether the connected components are defined strictly by face connectivity or by face+edge+vertex connectivity. Default is FullyConnectedOff. For objects that are 1 pixel wide, use FullyConnectedOn.
       */
      bool GetFullyConnected() const { return this->m_FullyConnected; }

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

      /** 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;


      double  m_Threshold1{0.0};

      double  m_Threshold2{1.0};

      double  m_Threshold3{254.0};

      double  m_Threshold4{255.0};

      uint8_t  m_InsideValue{1u};

      uint8_t  m_OutsideValue{0u};

      bool  m_FullyConnected{false};


    };

    /**\
     * \brief Binarize an input image using double thresholding.
     *
     * This function directly calls the execute method of DoubleThresholdImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::DoubleThresholdImageFilter for the object oriented interface
     * @{
     */

     SITKBasicFilters_EXPORT Image DoubleThreshold ( const Image& image1, double threshold1 = 0.0, double threshold2 = 1.0, double threshold3 = 254.0, double threshold4 = 255.0, uint8_t insideValue = 1u, uint8_t outsideValue = 0u, bool fullyConnected = false );

     /** @} */
}
#endif
