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 itkResampleImageFilter_h
19 #define itkResampleImageFilter_h
20 
21 #include "itkFixedArray.h"
22 #include "itkTransform.h"
23 #include "itkImageRegionIterator.h"
24 #include "itkImageToImageFilter.h"
25 #include "itkExtrapolateImageFunction.h"
26 #include "itkLinearInterpolateImageFunction.h"
27 #include "itkSize.h"
28 #include "itkDefaultConvertPixelTraits.h"
29 #include "itkDataObjectDecorator.h"
30 
31 
32 namespace itk
33 {
34 /** \class ResampleImageFilter
35  * \brief Resample an image via a coordinate transform
36  *
37  * ResampleImageFilter resamples an existing image through some coordinate
38  * transform, interpolating via some image function.  The class is templated
39  * over the types of the input and output images.
40  *
41  * Note that the choice of interpolator function can be important.
42  * This function is set via SetInterpolator().  The default is
43  * LinearInterpolateImageFunction<InputImageType,
44  * TInterpolatorPrecisionType>, which
45  * is reasonable for ordinary medical images.  However, some synthetic
46  * images have pixels drawn from a finite prescribed set.  An example
47  * would be a mask indicating the segmentation of a brain into a small
48  * number of tissue types.  For such an image, one does not want to
49  * interpolate between different pixel values, and so
50  * NearestNeighborInterpolateImageFunction< InputImageType,
51  * TCoordRep > would be a better choice.
52  *
53  * If an sample is taken from outside the image domain, the default behavior is
54  * to use a default pixel value.  If different behavior is desired, an
55  * extrapolator function can be set with SetExtrapolator().
56  *
57  * Output information (spacing, size and direction) for the output
58  * image should be set. This information has the normal defaults of
59  * unit spacing, zero origin and identity direction. Optionally, the
60  * output information can be obtained from a reference image. If the
61  * reference image is provided and UseReferenceImage is On, then the
62  * spacing, origin and direction of the reference image will be used.
63  *
64  * Since this filter produces an image which is a different size than
65  * its input, it needs to override several of the methods defined
66  * in ProcessObject in order to properly manage the pipeline execution model.
67  * In particular, this filter overrides
68  * ProcessObject::GenerateInputRequestedRegion() and
69  * ProcessObject::GenerateOutputInformation().
70  *
71  * This filter is implemented as a multithreaded filter.  It provides a
72  * DynamicThreadedGenerateData() method for its implementation.
73  * \warning For multithreading, the TransformPoint method of the
74  * user-designated coordinate transform must be threadsafe.
75  *
76  * \ingroup GeometricTransform
77  * \ingroup ITKImageGrid
78  *
79  * \wiki
80  * \wikiexample{SimpleOperations/TranslationTransform,Translate an image}
81  * \wikiexample{ImageProcessing/Upsampling,Upsampling an image}
82  * \wikiexample{ImageProcessing/ResampleImageFilter,Resample (stretch or compress) an image}
83  * \endwiki
84  */
85 template< typename TInputImage,
86           typename TOutputImage,
87           typename TInterpolatorPrecisionType = double,
88           typename TTransformPrecisionType = TInterpolatorPrecisionType>
89 class ITK_TEMPLATE_EXPORT ResampleImageFilter :
90   public ImageToImageFilter< TInputImage, TOutputImage >
91 {
92 public:
93   ITK_DISALLOW_COPY_AND_ASSIGN(ResampleImageFilter);
94 
95   /** Standard class type aliases. */
96   using Self = ResampleImageFilter;
97   using Superclass = ImageToImageFilter< TInputImage, TOutputImage >;
98   using Pointer = SmartPointer< Self >;
99   using ConstPointer = SmartPointer< const Self >;
100 
101   using InputImageType = TInputImage;
102   using OutputImageType = TOutputImage;
103   using InputImagePointer = typename InputImageType::Pointer;
104   using InputImageConstPointer = typename InputImageType::ConstPointer;
105   using OutputImagePointer = typename OutputImageType::Pointer;
106   using InputImageRegionType = typename InputImageType::RegionType;
107 
108   /** Method for creation through the object factory. */
109   itkNewMacro(Self);
110 
111   /** Run-time type information (and related methods). */
112   itkTypeMacro(ResampleImageFilter, ImageToImageFilter);
113 
114   /** Number of dimensions. */
115   static constexpr unsigned int ImageDimension = TOutputImage::ImageDimension;
116   static constexpr unsigned int InputImageDimension = TInputImage::ImageDimension;
117 
118   /** base type for images of the current ImageDimension */
119   using ImageBaseType = ImageBase< Self::ImageDimension >;
120 
121   /**
122    *  Transform type alias.
123    */
124   using TransformType = Transform< TTransformPrecisionType,
125                      Self::ImageDimension,
126                      Self::ImageDimension >;
127   using TransformPointerType = typename TransformType::ConstPointer;
128   using DecoratedTransformType = DataObjectDecorator<TransformType>;
129   using DecoratedTransformPointer = typename DecoratedTransformType::Pointer;
130 
131 
132   /** Interpolator type alias. */
133   using InterpolatorType = InterpolateImageFunction< InputImageType,
134                                     TInterpolatorPrecisionType >;
135   using InterpolatorPointerType = typename InterpolatorType::Pointer;
136 
137   using InterpolatorOutputType = typename InterpolatorType::OutputType;
138 
139   using InterpolatorConvertType = DefaultConvertPixelTraits< InterpolatorOutputType >;
140 
141   using ComponentType = typename InterpolatorConvertType::ComponentType;
142 
143   using LinearInterpolatorType = LinearInterpolateImageFunction< InputImageType,
144                                           TInterpolatorPrecisionType >;
145   using LinearInterpolatorPointerType = typename LinearInterpolatorType::Pointer;
146 
147   /** Extrapolator type alias. */
148   using ExtrapolatorType = ExtrapolateImageFunction< InputImageType,
149                                     TInterpolatorPrecisionType >;
150   using ExtrapolatorPointerType = typename ExtrapolatorType::Pointer;
151 
152   /** Image size type alias. */
153   using SizeType = Size< Self::ImageDimension >;
154 
155   /** Image index type alias. */
156   using IndexType = typename TOutputImage::IndexType;
157 
158   /** Image point type alias. */
159   using PointType = typename InterpolatorType::PointType;
160   //using PointType = typename TOutputImage::PointType;
161 
162   /** Image pixel value type alias. */
163   using PixelType = typename TOutputImage::PixelType;
164   using InputPixelType = typename TInputImage::PixelType;
165 
166   using PixelConvertType = DefaultConvertPixelTraits<PixelType>;
167 
168   using PixelComponentType = typename PixelConvertType::ComponentType;
169 
170   /** Input pixel continuous index typdef */
171   using ContinuousInputIndexType =
172       ContinuousIndex< TInterpolatorPrecisionType, ImageDimension >;
173 
174   /** Typedef to describe the output image region type. */
175   using OutputImageRegionType = typename TOutputImage::RegionType;
176 
177   /** Image spacing,origin and direction type alias */
178   using SpacingType = typename TOutputImage::SpacingType;
179   using OriginPointType = typename TOutputImage::PointType;
180   using DirectionType = typename TOutputImage::DirectionType;
181 
182   /** Typedef the reference image type to be the ImageBase of the OutputImageType */
183   using ReferenceImageBaseType = ImageBase<ImageDimension>;
184 
185   /** Get/Set the coordinate transformation.
186    * Set the coordinate transform to use for resampling.  Note that this must
187    * be in physical coordinates and it is the output-to-input transform, NOT
188    * the input-to-output transform that you might naively expect.  By default
189    * the filter uses an Identity transform. You must provide a different
190    * transform here, before attempting to run the filter, if you do not want to
191    * use the default Identity transform. */
192    itkSetGetDecoratedObjectInputMacro(Transform, TransformType);
193 
194   /** Get/Set the interpolator function.  The default is
195    * LinearInterpolateImageFunction<InputImageType,
196    * TInterpolatorPrecisionType>. Some
197    * other options are NearestNeighborInterpolateImageFunction
198    * (useful for binary masks and other images with a small number of
199    * possible pixel values), and BSplineInterpolateImageFunction
200    * (which provides a higher order of interpolation).  */
201   itkSetObjectMacro(Interpolator, InterpolatorType);
202   itkGetModifiableObjectMacro(Interpolator, InterpolatorType);
203 
204   /** Get/Set the extrapolator function.  The default behavior when sampling outside
205    * of the input image is to use the DefaultPixelValue.  Some other options
206    * include NearestNeighborExtrapolateImageFunction. */
207   itkSetObjectMacro(Extrapolator, ExtrapolatorType);
208   itkGetModifiableObjectMacro(Extrapolator, ExtrapolatorType);
209 
210   /** Get/Set the size of the output image. */
211   itkSetMacro(Size, SizeType);
212   itkGetConstReferenceMacro(Size, SizeType);
213 
214   /** Get/Set the pixel value when a transformed pixel is outside of the
215    * image.  The default default pixel value is 0. */
216   itkSetMacro(DefaultPixelValue, PixelType);
217   itkGetConstReferenceMacro(DefaultPixelValue, PixelType);
218 
219   /** Set the output image spacing. */
220   itkSetMacro(OutputSpacing, SpacingType);
221   virtual void SetOutputSpacing(const double *values);
222 
223   /** Get the output image spacing. */
224   itkGetConstReferenceMacro(OutputSpacing, SpacingType);
225 
226   /** Set the output image origin. */
227   itkSetMacro(OutputOrigin, OriginPointType);
228   virtual void SetOutputOrigin(const double *values);
229 
230   /** Get the output image origin. */
231   itkGetConstReferenceMacro(OutputOrigin, OriginPointType);
232 
233   /** Set the output direciton cosine matrix. */
234   itkSetMacro(OutputDirection, DirectionType);
235   itkGetConstReferenceMacro(OutputDirection, DirectionType);
236 
237   /** Helper method to set the output parameters based on this image. */
238   void SetOutputParametersFromImage(const ImageBaseType *image);
239 
240   /** Set the start index of the output largest possible region.
241    * The default is an index of all zeros. */
242   itkSetMacro(OutputStartIndex, IndexType);
243 
244   /** Get the start index of the output largest possible region. */
245   itkGetConstReferenceMacro(OutputStartIndex, IndexType);
246 
247    /** Set a reference image to use to define the output information.
248     *  By default, output information is specificed through the
249     *  SetOutputSpacing, Origin, and Direction methods.  Alternatively,
250     *  this method can be used to specify an image from which to
251     *  copy the information. UseReferenceImageOn must be set to utilize the
252     *  reference image. */
253   itkSetInputMacro(ReferenceImage, ReferenceImageBaseType);
254 
255   /** Get the reference image that is defining the output information. */
256   itkGetInputMacro(ReferenceImage, ReferenceImageBaseType);
257 
258   /** Turn on/off whether a specified reference image should be used to define
259    *  the output information. */
260   itkSetMacro(UseReferenceImage, bool);
261   itkBooleanMacro(UseReferenceImage);
262   itkGetConstMacro(UseReferenceImage, bool);
263 
264 #ifdef ITK_USE_CONCEPT_CHECKING
265   // Begin concept checking
266   itkConceptMacro( OutputHasNumericTraitsCheck,
267                    ( Concept::HasNumericTraits< PixelComponentType > ) );
268   // End concept checking
269 #endif
270 
271 protected:
272   ResampleImageFilter();
273   ~ResampleImageFilter() override = default;
274   void PrintSelf(std::ostream & os, Indent indent) const override;
275 
276   /** Override VeriyInputInformation() since this filter's inputs do
277    * not need to occoupy the same physical space.
278    *
279    * \sa ProcessObject::VerifyInputInformation
280    */
VerifyInputInformation()281   void VerifyInputInformation() ITKv5_CONST override { }
282 
283   /** ResampleImageFilter produces an image which is a different size
284    * than its input.  As such, it needs to provide an implementation
285    * for GenerateOutputInformation() in order to inform the pipeline
286    * execution model.  The original documentation of this method is
287    * below. \sa ProcessObject::GenerateOutputInformaton() */
288   void GenerateOutputInformation() override;
289 
290   /** ResampleImageFilter needs a different input requested region than
291    * the output requested region.  As such, ResampleImageFilter needs
292    * to provide an implementation for GenerateInputRequestedRegion()
293    * in order to inform the pipeline execution model.
294    * \sa ProcessObject::GenerateInputRequestedRegion() */
295   void GenerateInputRequestedRegion() override;
296 
297   /** Set up state of filter before multi-threading.
298    * InterpolatorType::SetInputImage is not thread-safe and hence
299    * has to be set up before DynamicThreadedGenerateData */
300   void BeforeThreadedGenerateData() override;
301 
302   /** Set the state of the filter after multi-threading. */
303   void AfterThreadedGenerateData() override;
304 
305   /** Compute the Modified Time based on the changed components. */
306   ModifiedTimeType GetMTime() const override;
307 
308   /** ResampleImageFilter can be implemented as a multithreaded filter.
309    * Therefore, this implementation provides a DynamicThreadedGenerateData()
310    * routine which is called for each processing thread. The output
311    * image data is allocated automatically by the superclass prior
312    * to calling DynamicThreadedGenerateData().
313    * DynamicThreadedGenerateData can only write to the portion of the output image
314    * specified by the parameter "outputRegionForThread"
315    * \sa ImageToImageFilter::ThreadedGenerateData(),
316    *     ImageToImageFilter::GenerateData() */
317   void DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread) override;
318 
319 
320   /** Default implementation for resampling that works for any
321    * transformation type. */
322   virtual void NonlinearThreadedGenerateData(const OutputImageRegionType & outputRegionForThread);
323 
324   /** Implementation for resampling that works for with linear
325    *  transformation types. */
326   virtual void LinearThreadedGenerateData(const OutputImageRegionType & outputRegionForThread);
327 
328   /** Cast pixel from interpolator output to PixelType. */
329   itkLegacyMacro(
330   virtual PixelType CastPixelWithBoundsChecking( const InterpolatorOutputType value,
331                                                  const ComponentType minComponent,
332                                                  const ComponentType maxComponent) const);
333 
334 private:
335   static PixelComponentType CastComponentWithBoundsChecking(const PixelComponentType value);
336 
337   template <typename TComponent>
338   static PixelComponentType CastComponentWithBoundsChecking(const TComponent value);
339 
340   static PixelType CastPixelWithBoundsChecking(const ComponentType value);
341 
342   template <typename TPixel>
343   static PixelType CastPixelWithBoundsChecking(const TPixel value);
344 
345   SizeType                m_Size;         // Size of the output image
346   InterpolatorPointerType m_Interpolator; // Image function for
347                                           // interpolation
348   ExtrapolatorPointerType m_Extrapolator; // Image function for
349                                           // extrapolation
350   PixelType m_DefaultPixelValue;          // default pixel value
351                                           // if the point is
352                                           // outside the image
353   SpacingType     m_OutputSpacing;        // output image spacing
354   OriginPointType m_OutputOrigin;         // output image origin
355   DirectionType   m_OutputDirection;      // output image direction cosines
356   IndexType       m_OutputStartIndex;     // output image start index
357   bool            m_UseReferenceImage{ false };
358 
359 };
360 } // end namespace itk
361 
362 #ifndef ITK_MANUAL_INSTANTIATION
363 #include "itkResampleImageFilter.hxx"
364 #endif
365 
366 #endif
367