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 itkImageBoundaryCondition_h
19 #define itkImageBoundaryCondition_h
20 
21 #include "itkIndex.h"
22 #include "itkNeighborhood.h"
23 #include "itkImageRegion.h"
24 
25 namespace itk
26 {
27 /**
28  *\class ImageBoundaryCondition
29  * \brief A virtual base object that defines an interface to a class of
30  * boundary condition objects for use by neighborhood iterators.
31  *
32  * A boundary condition object supplies a phantom pixel value when
33  * given a neighborhood of (pointers to) image values, the (ND) index of
34  * the phantom pixel, and its (ND) offset from the boundary.  The index
35  * of the phantom pixel is relative to the "upper left-hand corner" of
36  * the neighborhood (as opposed to its center).
37  *
38  *
39  * Associated Types                 Description
40  * ----------------                 -----------
41  * PixelType                         The data type of the return value.
42  * PixelPointerType                  A pointer to PixelType.
43  * PixelPointerTypeNeighborhood      A neighborhood of PixelPointerTypes
44  *                                   that points to the pixel values in
45  *                                   an image neighborhood.
46  *
47  * \ingroup DataRepresentation
48  * \ingroup ImageObjects
49  * \ingroup ITKCommon
50  */
51 template< typename TInputImage, typename TOutputImage = TInputImage >
52 class ITK_TEMPLATE_EXPORT ImageBoundaryCondition
53 {
54 public:
55   /** Extract information from the image type */
56   static constexpr unsigned int ImageDimension = TInputImage::ImageDimension;
57 
58   /** Standard type alias. */
59   using Self = ImageBoundaryCondition;
60 
61   /** Extract information from the image type */
62   using InputImageType = TInputImage;
63   using OutputImageType = TOutputImage;
64   using PixelType = typename TInputImage::PixelType;
65   using PixelPointerType = typename TInputImage::InternalPixelType *;
66   using OutputPixelType = typename TOutputImage::PixelType;
67   using IndexType = Index< ImageDimension >;
68   using SizeType = Size< ImageDimension >;
69   using OffsetType = Offset< ImageDimension >;
70   using RegionType = ImageRegion< ImageDimension >;
71 
72   /** Type of the data container passed to this function object. */
73   using NeighborhoodType = Neighborhood< PixelPointerType, ImageDimension >;
74 
75   /** Functor used to access pixels from a neighborhood of pixel pointers */
76   using NeighborhoodAccessorFunctorType = typename TInputImage::NeighborhoodAccessorFunctorType;
77 
78   /** Default constructor. */
79   ImageBoundaryCondition() = default;
80 
81   /** Runtime information support. */
GetNameOfClass()82   virtual const char * GetNameOfClass() const
83   {
84     return "itkImageBoundaryCondition";
85   }
86 
87   /** Utility for printing the boundary condition. */
88   virtual void Print( std::ostream & os, Indent i = 0 ) const
89   {
90     os << i << this->GetNameOfClass() << " (" << this << ")" << std::endl;
91   }
92 
93   /** Returns a value for a given out-of-bounds pixel.  The arguments are the
94    * phantom pixel (ND) index within the neighborhood, the pixel's offset from
95    * the nearest image border pixel, and a neighborhood of pointers to pixel
96    * values in the image.  */
97   virtual OutputPixelType operator()(const OffsetType & point_index,
98                                      const OffsetType & boundary_offset,
99                                      const NeighborhoodType *data) const = 0;
100 
101   /** Computes and returns the appropriate pixel value from
102    * neighborhood iterator data, using the functor. */
103   virtual OutputPixelType operator()(
104     const OffsetType & point_index,
105     const OffsetType & boundary_offset,
106     const NeighborhoodType *data,
107     const NeighborhoodAccessorFunctorType & neighborhoodAccessorFunctor) const = 0;
108 
109   virtual ~ImageBoundaryCondition() = default;
110 
111   /** Tell if the boundary condition can index to any location within
112     * the associated iterator's neighborhood or if it has some limited
113     * subset (such as none) that it relies upon.
114     * Subclasses should override this method if they can safely limit
115     * indexes to active pixels (or no pixels).
116     */
RequiresCompleteNeighborhood()117   virtual bool RequiresCompleteNeighborhood() { return true; }
118 
119   /** Determines the necessary input region for an output region given
120    * the largest possible region of the input image. Subclasses should
121    * override this method to efficiently support streaming.
122    *
123    * \param inputLargestPossibleRegion Largest possible region of the input image.
124    * \param outputRequestedRegion The output requested region.
125    * \return The necessary input region required to determine the
126    * pixel values in the outputRequestedRegion.
127    */
GetInputRequestedRegion(const RegionType & inputLargestPossibleRegion,const RegionType & outputRequestedRegion)128   virtual RegionType GetInputRequestedRegion( const RegionType & inputLargestPossibleRegion,
129                                               const RegionType & outputRequestedRegion ) const
130   {
131     (void) outputRequestedRegion;
132     return inputLargestPossibleRegion;
133   }
134 
135   /** Returns a value for a given pixel at an index. If the index is inside the
136    * bounds of the input image, then the pixel value is obtained from
137    * the input image. Otherwise, the pixel value is determined
138    * according to the boundary condition type.
139    *
140    * \param index The index of the desired pixel.
141    * \param image The image from which pixel values should be determined.
142    */
143   virtual OutputPixelType GetPixel( const IndexType & index,
144                                     const TInputImage * image ) const = 0;
145 
146 };
147 } // end namespace itk
148 
149 #endif
150