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 itkVectorInterpolateImageFunction_h
19 #define itkVectorInterpolateImageFunction_h
20 
21 #include "itkImageFunction.h"
22 #include "itkFixedArray.h"
23 
24 namespace itk
25 {
26 
27 /** \class VectorInterpolateImageFunction
28  * \brief Base class for all vector image interpolaters.
29  *
30  * VectorInterpolateImageFunction is the base for all ImageFunctions that
31  * interpolates image with vector pixel types. This function outputs
32  * a return value of type Vector<double,Dimension>.
33  *
34  * This class is templated input image type and the coordinate
35  * representation type.
36  *
37  * \warning This hierarchy of functions work only for images
38  * with Vector-based pixel types. For scalar images use
39  * InterpolateImageFunction.
40  *
41  * \sa InterpolateImageFunction
42  * \ingroup ImageFunctions ImageInterpolators
43  * \ingroup ITKImageFunction
44  */
45 template< typename TInputImage, typename TCoordRep = double >
46 class ITK_TEMPLATE_EXPORT VectorInterpolateImageFunction:
47   public ImageFunction<
48     TInputImage,
49     typename NumericTraits< typename TInputImage::PixelType >::RealType,
50     TCoordRep >
51 {
52 public:
53   ITK_DISALLOW_COPY_AND_ASSIGN(VectorInterpolateImageFunction);
54 
55   /** Extract the vector dimension from the pixel template parameter. */
56   static constexpr unsigned int Dimension = TInputImage::PixelType::Dimension;
57 
58   /** Dimension underlying input image. */
59   static constexpr unsigned int ImageDimension = TInputImage::ImageDimension;
60 
61   /** Standard class type aliases. */
62   using Self = VectorInterpolateImageFunction;
63   using Superclass = ImageFunction< TInputImage,
64                          typename NumericTraits< typename TInputImage::PixelType >::RealType,
65                          TCoordRep >;
66 
67   using Pointer = SmartPointer< Self >;
68   using ConstPointer = SmartPointer< const Self >;
69 
70   /** Run-time type information (and related methods). */
71   itkTypeMacro(VectorInterpolateImageFunction, ImageFunction);
72 
73   /** InputImageType type alias support */
74   using InputImageType = typename Superclass::InputImageType;
75   using PixelType = typename InputImageType::PixelType;
76   using ValueType = typename PixelType::ValueType;
77   using RealType = typename NumericTraits< ValueType >::RealType;
78 
79   /** Point type alias support */
80   using PointType = typename Superclass::PointType;
81 
82   /** Index type alias support */
83   using IndexType = typename Superclass::IndexType;
84 
85   /** ContinuousIndex type alias support */
86   using ContinuousIndexType = typename Superclass::ContinuousIndexType;
87 
88   /** Output type is RealType of TInputImage::PixelType. */
89   using OutputType = typename Superclass::OutputType;
90 
91   /** CoordRep type alias support */
92   using CoordRepType = TCoordRep;
93 
94   /** Returns the interpolated image intensity at a
95    * specified point position. No bounds checking is done.
96    * The point is assume to lie within the image buffer.
97    * ImageFunction::IsInsideBuffer() can be used to check bounds before
98    * calling the method. */
Evaluate(const PointType & point)99   OutputType Evaluate(const PointType & point) const override
100   {
101     ContinuousIndexType index;
102 
103     this->GetInputImage()->TransformPhysicalPointToContinuousIndex(point, index);
104     return ( this->EvaluateAtContinuousIndex(index) );
105   }
106 
107   /** Interpolate the image at a continuous index position
108    *
109    * Returns the interpolated image intensity at a
110    * specified index position. No bounds checking is done.
111    * The point is assume to lie within the image buffer.
112    *
113    * Subclasses must override this method.
114    *
115    * ImageFunction::IsInsideBuffer() can be used to check bounds before
116    * calling the method. */
117   OutputType EvaluateAtContinuousIndex(
118     const ContinuousIndexType & index) const override = 0;
119 
120   /** Interpolate the image at an index position.
121    * Simply returns the image value at the
122    * specified index position. No bounds checking is done.
123    * The point is assume to lie within the image buffer.
124    *
125    * ImageFunction::IsInsideBuffer() can be used to check bounds before
126    * calling the method. */
EvaluateAtIndex(const IndexType & index)127   OutputType EvaluateAtIndex(const IndexType & index) const override
128   {
129     OutputType output;
130     PixelType  input = this->GetInputImage()->GetPixel(index);
131 
132     for ( unsigned int k = 0;
133               k < this->GetInputImage()->GetNumberOfComponentsPerPixel(); k++ )
134       {
135       output[k] = static_cast< double >( input[k] );
136       }
137     return ( output );
138   }
139 
140 protected:
141   VectorInterpolateImageFunction() = default;
142   ~VectorInterpolateImageFunction() override = default;
PrintSelf(std::ostream & os,Indent indent)143   void PrintSelf(std::ostream & os, Indent indent) const override
144   { Superclass::PrintSelf(os, indent); }
145 };
146 } // end namespace itk
147 
148 #endif
149