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 itkConstantBoundaryCondition_h
19 #define itkConstantBoundaryCondition_h
20 
21 #include "itkNumericTraits.h"
22 #include "itkImageBoundaryCondition.h"
23 
24 namespace itk
25 {
26 // Forward reference for VariableLengthVector
27 template <typename TValue> class VariableLengthVector;
28 
29 /** \class ConstantBoundaryCondition
30  * \brief This boundary condition returns a constant value for out-of-bounds
31  * image pixels.
32  *
33  * For example, invoking this function object with a constant value of zero
34  * (the default) on each out-of-bounds element of a 7x5 iterator that masks a
35  * region at an image corner
36  * (iterator is centered on the 2):
37  *
38  *               * * * * * * *
39  *               * * * * * * *
40  *               * * 1 2 3 4 5  (where * denotes pixels that lie
41  *               * * 3 3 5 5 6          outside of the image boundary)
42  *               * * 4 4 6 7 8
43  *
44  * would produce the following neighborhood of values:
45  *
46  *               0 0 0 0 0 0 0
47  *               0 0 0 0 0 0 0
48  *               0 0 1 2 3 4 5
49  *               0 0 3 3 5 5 6
50  *               0 0 4 4 6 7 8
51  *
52  * \note If you are using an image with Array as the pixel type, you will need
53  * to set the constant explicitly with an array of the appropriate length. This
54  * is also true if your image type is a VectorImage.
55  *
56  * \sa ImageBoundaryCondition
57  *
58  * \ingroup DataRepresentation
59  * \ingroup ImageObjects
60  * \ingroup ITKCommon
61  *
62  * \wiki
63  * \wikiexample{Iterators/ConstantBoundaryCondition,Make out of bounds pixels return a constant value}
64  * \endwiki
65  */
66 template< typename TInputImage, typename TOutputImage = TInputImage >
67 class ITK_TEMPLATE_EXPORT ConstantBoundaryCondition:
68     public ImageBoundaryCondition< TInputImage, TOutputImage >
69 {
70 public:
71   /** Self & superclass type alias */
72   using Self = ConstantBoundaryCondition;
73   using Superclass = ImageBoundaryCondition< TInputImage, TOutputImage >;
74 
75   /** Extract information from the image type */
76   using PixelType = typename Superclass::PixelType;
77   using PixelPointerType = typename Superclass::PixelPointerType;
78   using OutputPixelType = typename Superclass::OutputPixelType;
79   using RegionType = typename Superclass::RegionType;
80   using IndexType = typename Superclass::IndexType;
81   using SizeType = typename Superclass::SizeType;
82   using OffsetType = typename Superclass::OffsetType;
83   using NeighborhoodType = typename Superclass::NeighborhoodType;
84 
85   using NeighborhoodAccessorFunctorType = typename Superclass::NeighborhoodAccessorFunctorType;
86 
87   /** Save the image dimension. */
88   static constexpr unsigned int ImageDimension = Superclass::ImageDimension;
89 
90   /** Default constructor. */
91   ConstantBoundaryCondition();
92 
93   /** Runtime information support. */
GetNameOfClass()94   const char * GetNameOfClass() const override
95   {
96     return "itkConstantBoundaryCondition";
97   }
98 
99   /** Utility for printing the boundary condition. */
100   void Print( std::ostream & os, Indent i = 0 ) const override;
101 
102   /** Special version of initialize for images with pixel type
103    * VariableLengthVector. */
104   template < typename TPixel >
105   void Initialize( const VariableLengthVector< TPixel > * );
106 
107   /** Computes and returns appropriate out-of-bounds values from
108    * neighborhood iterator data. */
109   OutputPixelType operator()(const OffsetType &,
110                                      const OffsetType &,
111                                      const NeighborhoodType *) const override;
112 
113   /** Computes and returns the appropriate pixel value from
114    * neighborhood iterator data, using the functor. */
115   OutputPixelType operator()(
116     const OffsetType &,
117     const OffsetType &,
118     const NeighborhoodType *,
119     const NeighborhoodAccessorFunctorType &) const override;
120 
121   /** Set the value of the constant. */
122   void SetConstant(const OutputPixelType & c);
123 
124   /** Get the value of the constant. */
125   const OutputPixelType & GetConstant() const;
126 
127   /** Tell if the boundary condition can index to any location within
128     * the associated iterator's neighborhood or if it has some limited
129     * subset (such as none) that it relies upon. */
RequiresCompleteNeighborhood()130   bool RequiresCompleteNeighborhood() override { return false; }
131 
132   /** Determines the necessary input region for the output region.
133    * For this boundary condition, only the intersection of the largest
134    * possible image region and the output requested region is needed.
135    *
136    * \param inputLargestPossibleRegion Largest possible region of the input image.
137    * \param outputRequestedRegion The output requested region.
138    * \return The necessary input region required to determine the
139    * pixel values in the outputRequestedRegion.
140    */
141   RegionType GetInputRequestedRegion( const RegionType & inputLargestPossibleRegion,
142                                               const RegionType & outputRequestedRegion ) const override;
143 
144   /** Returns a value for a given pixel at an index. If the index is inside the
145    * bounds of the input image, then the pixel value is obtained from
146    * the input image. Otherwise, the constant value is returned.
147    *
148    * \param index The index of the desired pixel.
149    * \param image The image from which pixel values should be determined.
150    */
151   OutputPixelType GetPixel( const IndexType & index, const TInputImage * image ) const override;
152 
153 private:
154   OutputPixelType m_Constant;
155 };
156 } // end namespace itk
157 
158 #ifndef ITK_MANUAL_INSTANTIATION
159 #include "itkConstantBoundaryCondition.hxx"
160 #endif
161 
162 #endif
163