1 /*========================================================================= 2 * 3 * Copyright Insight Software Consortium 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0.txt 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 *=========================================================================*/ 18 #ifndef itkZeroFluxNeumannBoundaryCondition_h 19 #define itkZeroFluxNeumannBoundaryCondition_h 20 #include "itkImageBoundaryCondition.h" 21 22 namespace itk 23 { 24 /** \class ZeroFluxNeumannBoundaryCondition 25 * \brief 26 * A function object that determines a neighborhood of values at an 27 * image boundary according to a Neumann boundary condition where first, 28 * upwind derivatives on the boundary are zero. This is a useful condition 29 * in solving some classes of differential equations. 30 * 31 * For example, invoking this function object on a 7x5 iterator that masks 32 * a region at an image corner (iterator is centered on the 2): 33 \code 34 * * * * * * * 35 * * * * * * * 36 * * 1 2 3 4 5 (where * denotes pixels that lie 37 * * 3 3 5 5 6 outside of the image boundary) 38 * * 4 4 6 7 8 39 \endcode 40 * returns the following neighborhood of values: 41 \code 42 1 1 1 2 3 4 5 43 1 1 1 2 3 4 5 44 1 1 1 2 3 4 5 45 3 3 3 3 5 5 6 (note the corner values) 46 4 4 4 4 6 7 8 47 \endcode 48 * The input to this function object is a neighborhood iterator. This boundary 49 * condition object is designed to be given as a template argument to a 50 * NeighborhoodIterator or any of the NeighborhoodIterator 51 * subclasses. 52 * 53 * \ingroup DataRepresentation 54 * \ingroup ImageObjects 55 * \ingroup ITKCommon 56 */ 57 template< typename TInputImage, typename TOutputImage = TInputImage > 58 class ITK_TEMPLATE_EXPORT ZeroFluxNeumannBoundaryCondition: 59 public ImageBoundaryCondition< TInputImage, TOutputImage > 60 { 61 public: 62 /** Standard class type aliases. */ 63 using Self = ZeroFluxNeumannBoundaryCondition; 64 using Superclass = ImageBoundaryCondition< TInputImage, TOutputImage >; 65 66 /** Extract information from the image type. */ 67 using PixelType = typename Superclass::PixelType; 68 using PixelPointerType = typename Superclass::PixelPointerType; 69 using OutputPixelType = typename Superclass::OutputPixelType; 70 using RegionType = typename Superclass::RegionType; 71 using IndexType = typename Superclass::IndexType; 72 using SizeType = typename Superclass::SizeType; 73 using OffsetType = typename Superclass::OffsetType; 74 using NeighborhoodType = typename Superclass::NeighborhoodType; 75 76 using NeighborhoodAccessorFunctorType = typename Superclass::NeighborhoodAccessorFunctorType; 77 78 /** Extract information from the image type. */ 79 static constexpr unsigned int ImageDimension = Superclass::ImageDimension; 80 81 /** Default constructor. */ 82 ZeroFluxNeumannBoundaryCondition() = default; 83 84 /** Runtime information support. */ GetNameOfClass()85 const char * GetNameOfClass() const override 86 { 87 return "itkZeroFluxNeumannBoundaryCondition"; 88 } 89 90 /** Computes and returns a neighborhood of appropriate values from 91 * neighborhood iterator data.. */ 92 OutputPixelType operator()(const OffsetType & point_index, 93 const OffsetType & boundary_offset, 94 const NeighborhoodType *data) const override; 95 96 /** Computes and returns the appropriate pixel value from 97 * neighborhood iterator data, using the functor. */ 98 OutputPixelType operator()( 99 const OffsetType & point_index, 100 const OffsetType & boundary_offset, 101 const NeighborhoodType *data, 102 const NeighborhoodAccessorFunctorType & neighborhoodAccessorFunctor) const override; 103 104 /** Determines the necessary input region for the output region. 105 * For this boundary condition, only the intersection of the largest 106 * possible image region and the output requested region is 107 * needed. If the intersection is empty, then a one-pixel layer of 108 * the image from the side closest to the output requested region is needed. 109 * 110 * \param inputLargestPossibleRegion Largest possible region of the input image. 111 * \param outputRequestedRegion The output requested region. 112 * \return The necessary input region required to determine the 113 * pixel values in the outputRequestedRegion. 114 */ 115 RegionType GetInputRequestedRegion( const RegionType & inputLargestPossibleRegion, 116 const RegionType & outputRequestedRegion ) const override; 117 118 /** Returns a value for a given pixel at an index. If the index is inside the 119 * bounds of the input image, then the pixel value is obtained from 120 * the input image. Otherwise, the nearest pixel value is returned. 121 * 122 * \param index The index of the desired pixel. 123 * \param image The image from which pixel values should be determined. 124 */ 125 OutputPixelType GetPixel( const IndexType & index, const TInputImage * image ) const override; 126 127 }; 128 } // end namespace itk 129 130 #ifndef ITK_MANUAL_INSTANTIATION 131 #include "itkZeroFluxNeumannBoundaryCondition.hxx" 132 #endif 133 134 /* 135 #ifndef ITK_MANUAL_INSTANTIATION 136 #include "itkZeroFluxNeumannBoundaryCondition.hxx" 137 #endif 138 */ 139 140 #endif 141