/*=========================================================================
*
*  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 sitkZeroCrossingBasedEdgeDetectionImageFilter_h
#define sitkZeroCrossingBasedEdgeDetectionImageFilter_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 ZeroCrossingBasedEdgeDetectionImageFilter
\brief This filter implements a zero-crossing based edge detector.

The zero-crossing based edge detector looks for pixels in the Laplacian of an image where the value of the Laplacian passes through zero points where the Laplacian changes sign. Such points often occur at "edges" in images i.e. points where the intensity of the image changes rapidly, but they also occur at places that are not as easy to associate with edges. It is best to think of the zero crossing detector as some sort of feature detector rather than as a specific edge detector.

\par 
Zero crossings always lie on closed contours and so the output from the zero crossing detector is usually a binary image with single pixel thickness lines showing the positions of the zero crossing points.


\par 
In this implementation, the input image is first smoothed with a Gaussian filter, then the LaplacianImageFilter is applied to smoothed image. Finally the zero-crossing of the Laplacian of the smoothed image is detected. The output is a binary image.


\par Inputs and Outputs
The input to the filter should be a scalar, itk::Image of arbitrary dimension. The output image is a binary, labeled image. See itkZeroCrossingImageFilter for more information on requirements of the data type of the output.


\par 
To use this filter, first set the parameters (variance and maximum error) needed by the embedded DiscreteGaussianImageFilter , i.e. See DiscreteGaussianImageFilter for information about these parameters. Optionally, you may also set foreground and background values for the zero-crossing filter. The default label values are Zero for the background and One for the foreground, as defined in NumericTraits for the data type of the output image.


\see DiscreteGaussianImageFilter 


\see LaplacianImageFilter 


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

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

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

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

      /**
       * Set the variance parameter needed by the embedded gaussian filter
       */
      SITK_RETURN_SELF_TYPE_HEADER SetVariance ( double Variance ) { this->m_Variance = Variance; return *this; }

      /**
       * Standard get/set macros for Gaussian filter parameters.
       */
      double GetVariance() const { return this->m_Variance; }\

      /**
       * Get/Set the label values for the ZeroCrossingImageFilter
       */
      SITK_RETURN_SELF_TYPE_HEADER SetForegroundValue ( uint8_t ForegroundValue ) { this->m_ForegroundValue = ForegroundValue; return *this; }

      /**
       * Get/Set the label values for the ZeroCrossingImageFilter
       */
      uint8_t GetForegroundValue() const { return this->m_ForegroundValue; }\

      /**
       * Get/Set the label values for the ZeroCrossingImageFilter
       */
      SITK_RETURN_SELF_TYPE_HEADER SetBackgroundValue ( uint8_t BackgroundValue ) { this->m_BackgroundValue = BackgroundValue; return *this; }

      /**
       * Get/Set the label values for the ZeroCrossingImageFilter
       */
      uint8_t GetBackgroundValue() const { return this->m_BackgroundValue; }\

      /**
       * Set the MaximumError parameter needed by the embedded gaussian filter This value is used to set the desired maximum error of the gaussian approximation. Maximum error is the difference between the area under the discrete Gaussian curve and the area under the continuous Gaussian. Maximum error affects the Gaussian operator size. The value must be between 0.0 and 1.0.
       */
      SITK_RETURN_SELF_TYPE_HEADER SetMaximumError ( double MaximumError ) { this->m_MaximumError = MaximumError; return *this; }

      /**
       * Standard get/set macros for Gaussian filter parameters.
       */
      double GetMaximumError() const { return this->m_MaximumError; }

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

      /** 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_Variance{1.0};

      uint8_t  m_ForegroundValue{1u};

      uint8_t  m_BackgroundValue{0u};

      double  m_MaximumError{0.1};


    };

    /**\
     * \brief This filter implements a zero-crossing based edge detector.
     *
     * This function directly calls the execute method of ZeroCrossingBasedEdgeDetectionImageFilter
     * in order to support a procedural API
     *
     * \sa itk::simple::ZeroCrossingBasedEdgeDetectionImageFilter for the object oriented interface
     * @{
     */

     SITKBasicFilters_EXPORT Image ZeroCrossingBasedEdgeDetection ( const Image& image1, double variance = 1.0, uint8_t foregroundValue = 1u, uint8_t backgroundValue = 0u, double maximumError = 0.1 );

     /** @} */
}
#endif
