/*========================================================================= Program: Visualization Toolkit Module: $RCSfile: vtkImageReslice.h,v $ Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ // .NAME vtkImageReslice - Reslices a volume along a new set of axes. // .SECTION Description // vtkImageReslice is the swiss-army-knife of image geometry filters: // It can permute, rotate, flip, scale, resample, deform, and pad image // data in any combination with reasonably high efficiency. Simple // operations such as permutation, resampling and padding are done // with similar efficiently to the specialized vtkImagePermute, // vtkImageResample, and vtkImagePad filters. There are a number of // tasks that vtkImageReslice is well suited for: //
1) Application of simple rotations, scales, and translations to // an image. It is often a good idea to use vtkImageChangeInformation // to center the image first, so that scales and rotations occur around // the center rather than around the lower-left corner of the image. //
2) Resampling of one data set to match the voxel sampling of // a second data set via the SetInformationInput() method, e.g. for // the purpose of comparing two images or combining two images. // A transformation, either linear or nonlinear, can be applied // at the same time via the SetResliceTransform method if the two // images are not in the same coordinate space. //
3) Extraction of slices from an image volume. The most convenient // way to do this is to use SetResliceAxesDirectionCosines() to // specify the orientation of the slice. The direction cosines give // the x, y, and z axes for the output volume. The method // SetOutputDimensionality(2) is used to specify that want to output a // slice rather than a volume. The SetResliceAxesOrigin() command is // used to provide an (x,y,z) point that the slice will pass through. // You can use both the ResliceAxes and the ResliceTransform at the // same time, in order to extract slices from a volume that you have // applied a transformation to. // .SECTION Caveats // This filter is very inefficient if the output X dimension is 1. // .SECTION see also // vtkAbstractTransform vtkMatrix4x4 #ifndef __vtkImageReslice_h #define __vtkImageReslice_h #include "vtkThreadedImageAlgorithm.h" // interpolation mode constants #define VTK_RESLICE_NEAREST 0 #define VTK_RESLICE_LINEAR 1 #define VTK_RESLICE_CUBIC 3 class vtkImageData; class vtkAbstractTransform; class vtkMatrix4x4; class vtkImageStencilData; class VTK_IMAGING_EXPORT vtkImageReslice : public vtkThreadedImageAlgorithm { public: static vtkImageReslice *New(); vtkTypeRevisionMacro(vtkImageReslice, vtkThreadedImageAlgorithm); virtual void PrintSelf(ostream& os, vtkIndent indent); // Description: // This method is used to set up the axes for the output voxels. // The output Spacing, Origin, and Extent specify the locations // of the voxels within the coordinate system defined by the axes. // The ResliceAxes are used most often to permute the data, e.g. // to extract ZY or XZ slices of a volume as 2D XY images. //
The first column of the matrix specifies the x-axis // vector (the fourth element must be set to zero), the second // column specifies the y-axis, and the third column the // z-axis. The fourth column is the origin of the // axes (the fourth element must be set to one). //
An alternative to SetResliceAxes() is to use // SetResliceAxesDirectionCosines() to set the directions of the // axes and SetResliceAxesOrigin() to set the origin of the axes. virtual void SetResliceAxes(vtkMatrix4x4*); vtkGetObjectMacro(ResliceAxes, vtkMatrix4x4); // Description: // Specify the direction cosines for the ResliceAxes (i.e. the // first three elements of each of the first three columns of // the ResliceAxes matrix). This will modify the current // ResliceAxes matrix, or create a new matrix if none exists. void SetResliceAxesDirectionCosines(double x0, double x1, double x2, double y0, double y1, double y2, double z0, double z1, double z2); void SetResliceAxesDirectionCosines(const double x[3], const double y[3], const double z[3]) { this->SetResliceAxesDirectionCosines(x[0], x[1], x[2], y[0], y[1], y[2], z[0], z[1], z[2]); }; void SetResliceAxesDirectionCosines(const double xyz[9]) { this->SetResliceAxesDirectionCosines(xyz[0], xyz[1], xyz[2], xyz[3], xyz[4], xyz[5], xyz[6], xyz[7], xyz[8]); }; void GetResliceAxesDirectionCosines(double x[3], double y[3], double z[3]); void GetResliceAxesDirectionCosines(double xyz[9]) { this->GetResliceAxesDirectionCosines(&xyz[0], &xyz[3], &xyz[6]); }; double *GetResliceAxesDirectionCosines() { this->GetResliceAxesDirectionCosines(this->ResliceAxesDirectionCosines); return this->ResliceAxesDirectionCosines; }; // Description: // Specify the origin for the ResliceAxes (i.e. the first three // elements of the final column of the ResliceAxes matrix). // This will modify the current ResliceAxes matrix, or create // new matrix if none exists. void SetResliceAxesOrigin(double x, double y, double z); void SetResliceAxesOrigin(const double xyz[3]) { this->SetResliceAxesOrigin(xyz[0], xyz[1], xyz[2]); }; void GetResliceAxesOrigin(double xyz[3]); double *GetResliceAxesOrigin() { this->GetResliceAxesOrigin(this->ResliceAxesOrigin); return this->ResliceAxesOrigin; }; // Description: // Set a transform to be applied to the resampling grid that has // been defined via the ResliceAxes and the output Origin, Spacing // and Extent. Note that applying a transform to the resampling // grid (which lies in the output coordinate system) is // equivalent to applying the inverse of that transform to // the input volume. Nonlinear transforms such as vtkGridTransform // and vtkThinPlateSplineTransform can be used here. virtual void SetResliceTransform(vtkAbstractTransform*); vtkGetObjectMacro(ResliceTransform, vtkAbstractTransform); // Description: // Set a vtkImageData from which the default Spacing, Origin, // and WholeExtent of the output will be copied. The spacing, // origin, and extent will be permuted according to the // ResliceAxes. Any values set via SetOutputSpacing, // SetOutputOrigin, and SetOutputExtent will override these // values. By default, the Spacing, Origin, and WholeExtent // of the Input are used. virtual void SetInformationInput(vtkImageData*); vtkGetObjectMacro(InformationInput, vtkImageData); // Description: // Specify whether to transform the spacing, origin and extent // of the Input (or the InformationInput) according to the // direction cosines and origin of the ResliceAxes before applying // them as the default output spacing, origin and extent // (default: On). vtkSetMacro(TransformInputSampling, int); vtkBooleanMacro(TransformInputSampling, int); vtkGetMacro(TransformInputSampling, int); // Description: // Turn this on if you want to guarantee that the extent of the // output will be large enough to ensure that none of the // data will be cropped (default: Off). vtkSetMacro(AutoCropOutput, int); vtkBooleanMacro(AutoCropOutput, int); vtkGetMacro(AutoCropOutput, int); // Description: // Turn on wrap-pad feature (default: Off). vtkSetMacro(Wrap, int); vtkGetMacro(Wrap, int); vtkBooleanMacro(Wrap, int); // Description: // Turn on mirror-pad feature (default: Off). // This will override the wrap-pad. vtkSetMacro(Mirror, int); vtkGetMacro(Mirror, int); vtkBooleanMacro(Mirror, int); // Description: // Extend the apparent input border by a half voxel (default: On). // This changes how interpolation is handled at the borders of the // input image: if the center of an output voxel is beyond the edge // of the input image, but is within a half voxel width of the edge // (using the input voxel width), then the value of the output voxel // is calculated as if the input's edge voxels were duplicated past // the edges of the input. // This has no effect if Mirror or Wrap are on. vtkSetMacro(Border, int); vtkGetMacro(Border, int); vtkBooleanMacro(Border, int); // Description: // Set interpolation mode (default: nearest neighbor). vtkSetMacro(InterpolationMode, int); vtkGetMacro(InterpolationMode, int); void SetInterpolationModeToNearestNeighbor() { this->SetInterpolationMode(VTK_RESLICE_NEAREST); }; void SetInterpolationModeToLinear() { this->SetInterpolationMode(VTK_RESLICE_LINEAR); }; void SetInterpolationModeToCubic() { this->SetInterpolationMode(VTK_RESLICE_CUBIC); }; const char *GetInterpolationModeAsString(); // Description: // Turn on and off optimizations (default on, they should only be // turned off for testing purposes). vtkSetMacro(Optimization, int); vtkGetMacro(Optimization, int); vtkBooleanMacro(Optimization, int); // Description: // Set the background color (for multi-component images). vtkSetVector4Macro(BackgroundColor, double); vtkGetVector4Macro(BackgroundColor, double); // Description: // Set background grey level (for single-component images). void SetBackgroundLevel(double v) { this->SetBackgroundColor(v,v,v,v); }; double GetBackgroundLevel() { return this->GetBackgroundColor()[0]; }; // Description: // Set the voxel spacing for the output data. The default output // spacing is the input spacing permuted through the ResliceAxes. vtkSetVector3Macro(OutputSpacing, double); vtkGetVector3Macro(OutputSpacing, double); void SetOutputSpacingToDefault() { this->SetOutputSpacing(VTK_DOUBLE_MAX, VTK_DOUBLE_MAX, VTK_DOUBLE_MAX); }; // Description: // Set the origin for the output data. The default output origin // is the input origin permuted through the ResliceAxes. vtkSetVector3Macro(OutputOrigin, double); vtkGetVector3Macro(OutputOrigin, double); void SetOutputOriginToDefault() { this->SetOutputOrigin(VTK_DOUBLE_MAX, VTK_DOUBLE_MAX, VTK_DOUBLE_MAX); }; // Description: // Set the extent for the output data. The default output extent // is the input extent permuted through the ResliceAxes. vtkSetVector6Macro(OutputExtent, int); vtkGetVector6Macro(OutputExtent, int); void SetOutputExtentToDefault() { this->SetOutputExtent(VTK_INT_MIN, VTK_INT_MAX, VTK_INT_MIN, VTK_INT_MAX, VTK_INT_MIN, VTK_INT_MAX); }; // Description: // Force the dimensionality of the output to either 1, 2, // 3 or 0 (default: 3). If the dimensionality is 2D, then // the Z extent of the output is forced to (0,0) and the Z // origin of the output is forced to 0.0 (i.e. the output // extent is confined to the xy plane). If the dimensionality // is 1D, the output extent is confined to the x axis. // For 0D, the output extent consists of a single voxel at // (0,0,0). vtkSetMacro(OutputDimensionality, int); vtkGetMacro(OutputDimensionality, int); // Description: // When determining the modified time of the filter, // this check the modified time of the transform and matrix. unsigned long int GetMTime(); // Description: // Convenient methods for switching between nearest-neighbor and linear // interpolation. // InterpolateOn() is equivalent to SetInterpolationModeToLinear() and // InterpolateOff() is equivalent to SetInterpolationModeToNearestNeighbor(). // You should not use these methods if you use the SetInterpolationMode // methods. void SetInterpolate(int t) { if (t && !this->GetInterpolate()) { this->SetInterpolationModeToLinear(); } else if (!t && this->GetInterpolate()) { this->SetInterpolationModeToNearestNeighbor(); } }; void InterpolateOn() { this->SetInterpolate(1); }; void InterpolateOff() { this->SetInterpolate(0); }; int GetInterpolate() { return (this->GetInterpolationMode() != VTK_RESLICE_NEAREST); }; // Description: // Use a stencil to limit the calculations to a specific region of // the output. Portions of the output that are 'outside' the stencil // will be cleared to the background color. void SetStencil(vtkImageStencilData *stencil); vtkImageStencilData *GetStencil(); protected: vtkImageReslice(); ~vtkImageReslice(); vtkMatrix4x4 *ResliceAxes; double ResliceAxesDirectionCosines[9]; double ResliceAxesOrigin[3]; vtkAbstractTransform *ResliceTransform; vtkImageData *InformationInput; int Wrap; int Mirror; int Border; int InterpolationMode; int Optimization; double BackgroundColor[4]; double OutputOrigin[3]; double OutputSpacing[3]; int OutputExtent[6]; int OutputDimensionality; int TransformInputSampling; int AutoCropOutput; int HitInputExtent; vtkMatrix4x4 *IndexMatrix; vtkAbstractTransform *OptimizedTransform; void GetAutoCroppedOutputBounds(vtkInformation *inInfo, double bounds[6]); virtual int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *); virtual int RequestUpdateExtent(vtkInformation *, vtkInformationVector **, vtkInformationVector *); virtual void ThreadedRequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector, vtkImageData ***inData, vtkImageData **outData, int ext[6], int id); virtual int FillInputPortInformation(int port, vtkInformation *info); vtkMatrix4x4 *GetIndexMatrix(vtkInformation *inInfo, vtkInformation *outInfo); vtkAbstractTransform *GetOptimizedTransform() { return this->OptimizedTransform; }; private: vtkImageReslice(const vtkImageReslice&); // Not implemented. void operator=(const vtkImageReslice&); // Not implemented. }; //---------------------------------------------------------------------------- inline const char *vtkImageReslice::GetInterpolationModeAsString() { switch (this->InterpolationMode) { case VTK_RESLICE_NEAREST: return "NearestNeighbor"; case VTK_RESLICE_LINEAR: return "Linear"; case VTK_RESLICE_CUBIC: return "Cubic"; default: return ""; } } #endif