ITK Release 4/Image Class Hierarchy Refactoring: Difference between revisions
(→Design) |
|||
(75 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
= Image Class Hierarchy Refactoring = | = Image Class Hierarchy Refactoring = | ||
The goal of this proposal is to refactor ITK's image class hierarchy to make adding other image types to ITK easier and to simplify the interface of image classes wherever possible. | |||
== Motivation == | == Motivation == | ||
ITK currently supports several types of image: | ITK currently supports several types of image: | ||
Line 11: | Line 11: | ||
** [http://www.itk.org/Doxygen320/html/classitk_1_1PhasedArray3DSpecialCoordinatesImage.html PhasedArray3DSpecialCoordinatesImage] | ** [http://www.itk.org/Doxygen320/html/classitk_1_1PhasedArray3DSpecialCoordinatesImage.html PhasedArray3DSpecialCoordinatesImage] | ||
* [http://www.itk.org/Doxygen320/html/classitk_1_1BloxImage.html BloxImage] | * [http://www.itk.org/Doxygen320/html/classitk_1_1BloxImage.html BloxImage] | ||
** [http://www.itk.org/Doxygen320/html/classitk_1_1BloxCoreAtomImage.html BloxCoreAtomImage] | |||
** [http://www.itk.org/Doxygen320/html/classitk_1_1BloxBoundaryProfileImage.html BloxBoundaryProfileImage] | |||
** [http://www.itk.org/Doxygen320/html/classitk_1_1BloxBoundaryPointImage.html BloxBoundaryPointImage] | |||
* [http://www.itk.org/Doxygen320/html/classitk_1_1SparseImage.html SparseImage] | * [http://www.itk.org/Doxygen320/html/classitk_1_1SparseImage.html SparseImage] | ||
* [http://www.itk.org/Doxygen320/html/classitk_1_1LabelMap.html LabelMap] | * [http://www.itk.org/Doxygen320/html/classitk_1_1LabelMap.html LabelMap] | ||
* [http://www.itk.org/Doxygen320/html/classitk_1_1ImageAdaptor.html ImageAdaptors] and subclasses | * [http://www.itk.org/Doxygen320/html/classitk_1_1ImageAdaptor.html ImageAdaptors] and subclasses | ||
* [http://www.insight-journal.org/browse/publication/646 Slice contiguous, sparse, and single-bit binary images] - Insight Journal article from Dan Mueller | |||
Most of the image types supported by ITK assume that the image topology is an n-dimensional lattice and that voxels have regular physical spacing in each dimension. While it makes sense to preserve the topology assumption, the regular spacing assumption should be relaxed wherever possible. The regular spacing assumption covers many cases in biomedical imaging, but it | Most of the image types supported by ITK assume that the image topology is an n-dimensional lattice and that voxels have regular physical spacing in each dimension. While it makes sense to preserve the topology assumption in a library focused on image analysis, the regular spacing assumption should be relaxed wherever possible. The regular spacing assumption covers many cases in biomedical imaging, but it is insufficient for certain types of images in other applications. For example, certain motorized stages used in fluorescence microscopes fail to achieve regular spacing in z when acquiring a 3D image. Helpfully, these stages report the positions of z-planes acquired during image stack collection. Assuming a regular z-spacing in place of the actual z-plane positions may result in significant errors in image analysis algorithms run on the image. | ||
It is possible to create image types in ITK that do not assume regular spacing: [http://www.itk.org/Doxygen320/html/classitk_1_1PhasedArray3DSpecialCoordinatesImage.html PhasedArray3DSpecialCoordinatesImage] is an example. Nevertheless, its interface still has the SetSpacing() and GetSpacing() methods defined in the ImageBase class (and overriden in SpecialCoordinatesImage). These methods are required for compatibility in filter pipelines, but their presence in this class is misleading; they do nothing. Other types of images may consist of samples not associated with a physical space. For these image types, class methods for setting metadata about the physical embedding of the image are not needed. | |||
== Goals == | == Goals == | ||
The primary goal in this refactoring is to | The primary goal in this refactoring is to produce a logical image class hierarchy in ITK that removes methods in image types where they are not needed. | ||
The secondary goal is to add a RectilinearImage class, a physically embedded image with origin, irregular spacing in each dimension, and orientation. | |||
== Requirements == | == Requirements == | ||
Line 33: | Line 34: | ||
* Each of the physically embedded image types will properly calculate transforms from indices to physical coordinates and back. | * Each of the physically embedded image types will properly calculate transforms from indices to physical coordinates and back. | ||
* All physically embedded images should support orientations. | * All physically embedded images should support orientations. | ||
* ImageAdaptors should work on all image types | |||
* Resampling should be supported for all physically embedded image types | |||
* Conversion of new image types to appropriate VTK classes for visualization | |||
== Challenges and Potential Pitfalls == | == Challenges and Potential Pitfalls == | ||
* ImageAdaptors should present the correct interface for the image type they adapt. This can be accomplished with partial template specialization of the ImageAdaptor class to avoid modifying any of the existing adaptors. | * ImageAdaptors should present the correct interface for the image type they adapt. This can be accomplished with partial template specialization of the ImageAdaptor class to avoid modifying any of the existing adaptors. | ||
* | * Numerous classes use regular spacing of images (they call GetSpacing()) directly and will need to be modified to handle the new image types or be restricted to work with only image types with regular sample spacing. A list of these classes can be found at the appendix at the end of this page. | ||
* Filters that require voxel positions should ideally use methods TransformIndexToPhysicalPoint, etc., but this may not be optimal for performance. | |||
* Filters that require voxel positions should | * Adding image types will add significant compilation time to wrapping | ||
* | |||
= Design = | = Design = | ||
ImageBase will be stripped to the bare minimum functionality required to support images with lattice topology. Other image types will have more specialized base classes, all descended (perhaps indirectly) from ImageBase. The base classes will provide support for additional image metadata. | |||
== Class Hierarchy == | == Class Hierarchy == | ||
Line 50: | Line 53: | ||
The class hierarchy will look like this: | The class hierarchy will look like this: | ||
* ImageBase< unsigned int VDimension > | * ImageBase< unsigned int VDimension > | ||
** PhysicalImageBase< unsigned int VDimension > | ** PhysicalImageBase< unsigned int VDimension > | ||
*** RegularImageBase< unsigned int VDimension > | *** RegularImageBase< unsigned int VDimension > | ||
**** Image< class TPixel, unsigned int VDimension > | |||
**** Image< class TPixel, unsigned int VDimension > | |||
***** BloxImage< class TPixel, unsigned int VDimension > | ***** BloxImage< class TPixel, unsigned int VDimension > | ||
****** BloxImage subclasses | |||
***** SparseImage< class TNode, unsigned int VDimension > | ***** SparseImage< class TNode, unsigned int VDimension > | ||
**** | **** VectorImage< class TPixel, unsigned int VDimension > | ||
**** | **** LabelMap< class TPixel, unsigned int VDimension > | ||
*** RectilinearImageBase < unsigned int VDimension > | *** RectilinearImageBase < unsigned int VDimension > | ||
**** RectilinearImage <class TPixel, unsigned in VDimension > | **** RectilinearImage <class TPixel, unsigned in VDimension > | ||
*** PhasedArray3DSpecialCoordinatesImage< class TPixel > | *** PhasedArray3DSpecialCoordinatesImage< class TPixel > | ||
All | All base image classes specify the interface for only the metadata of the image. This design is required to support the method CopyInformation(). For example, you may encounter a situation where you copy information from a RectilinearImage<float, 3> to a RectilinearImage<double, 3>. Dynamic casting from a RectilinearImage<float, 3> to a RectilinearImage<double, 3> won't work, so the method will throw an exception. Casting a RectilinearImage<float, 3> to a RectilinearImageBase< 3 > will work, enabling access to the metadata methods (GetSpacing(), GetOrigin(), etc.) from the source image. | ||
Specific methods defined or overridden in each class are provided below. | Specific methods defined or overridden in each class are provided below. | ||
=== Class Diagram === | |||
<graphviz> | |||
digraph G { | |||
ImageBase | |||
PhysicalImageBase | |||
RegularImageBase | |||
Image [shape=box]; | |||
BloxImage [shape=box]; | |||
BloxImageDerived [shape=box]; | |||
LabelMap [shape=box]; | |||
VectorImage [shape=box]; | |||
RectilinearImage [shape=box]; | |||
SparseImage [shape=box]; | |||
PhasedArray3DSpecialCoordinatesImage [shape=box]; | |||
ImageBase -> PhysicalImageBase | |||
PhysicalImageBase -> RegularImageBase | |||
RegularImageBase -> Image | |||
Image -> BloxImage | |||
BloxImage -> BloxImageDerived | |||
Image -> SparseImage | |||
RegularImageBase -> VectorImage | |||
RegularImageBase -> LabelMap | |||
PhysicalImageBase -> RectilinearImageBase | |||
RectilinearImageBase -> RectilinearImage | |||
PhysicalImageBase -> PhasedArray3DSpecialCoordinatesImage | |||
} | |||
</graphviz> | |||
== Image Types == | == Image Types == | ||
Line 136: | Line 168: | ||
Additional methods | Additional methods | ||
* [] | * operator[] | ||
* FillBuffer() | * FillBuffer() | ||
* GetBufferPointer() | * GetBufferPointer() | ||
Line 181: | Line 213: | ||
Additional methods | Additional methods | ||
* [] | * operator[] | ||
* FillBuffer() | * FillBuffer() | ||
* GetBufferPointer() | * GetBufferPointer() | ||
Line 216: | Line 248: | ||
== ImageAdaptors == | == ImageAdaptors == | ||
The ImageAdaptor class should be designed to present the proper API for each of the new image types. This requires partial template specialization of the ImageAdaptor template class to maintain backwards compatibility. Specifically, several definitions of the ImageAdaptor class will need to be defined, one for each image type. | |||
To work with the CopyInformation() method in the various Image subclasses, each ImageBase type (RegularImageBase, RectilinearImageBase, etc.) will need to have a corresponding ImageAdaptor type (RegularImageAdaptor, RectilinearImageAdaptor, etc.), each of which is a subclass of its corresponding image base type. They CANNOT be subclasses of the image types with pixel containers because of the problem with dynamic casting in the CopyInformation() method mentioned above. | To work with the CopyInformation() method in the various Image subclasses, each ImageBase type (RegularImageBase, RectilinearImageBase, etc.) will need to have a corresponding ImageAdaptor type (RegularImageAdaptor, RectilinearImageAdaptor, etc.), each of which is a subclass of its corresponding image base type. They CANNOT be subclasses of the image types with pixel containers because of the problem with dynamic casting in the CopyInformation() method mentioned above. | ||
Line 222: | Line 254: | ||
== ResampleImageFilter and WarpImageFilter == | == ResampleImageFilter and WarpImageFilter == | ||
The method SetOutputParametersFromImage() takes | The method SetOutputParametersFromImage() takes an ImageBase as input. Now that the metadata is stored in subclasses of ImageBase, this may be suboptimal. | ||
One solution is to try to dynamic_cast the ImageBase input to the various descendants of ImageBase (PhysicalImageBase, RegularImageBase, RectilinearImageBase, etc.). Upon successful casting, the relevant parameters from the ImageBase input can be copied over to the filter. However, say we're resampling to a RectilinearImage with the ResampleImageFilter. The ResampleImageFilter would need to have a method to support individual voxel spacings. But this method isn't needed for resampling to an Image, so it | One solution is to try to dynamic_cast the ImageBase input to the various descendants of ImageBase (PhysicalImageBase, RegularImageBase, RectilinearImageBase, etc.). Upon successful casting, the relevant parameters from the ImageBase input can be copied over to the filter. However, say we're resampling to a RectilinearImage with the ResampleImageFilter. The ResampleImageFilter would need to have a method to support individual voxel spacings. But this method isn't needed for resampling to an Image, so it would go to waste. | ||
Alternatively, these classes could be specialized for the output image type much like the ImageAdaptor is specialized. | Alternatively, these classes could be specialized for the output image type much like the ImageAdaptor is specialized. This seems like the best option. | ||
== Outstanding Questions == | == Outstanding Questions == | ||
* Are BloxImages and SparseImages physically embedded images? | |||
* Should image sources be specialized for different image types? | |||
* Will interpolators work out-of-the-box for Images with implementations of TransformIndexToPhysicalPoint, etc? | |||
* File readers? | |||
* Use concept checking in filters and image sources to check support for input/output image types? | |||
= Implementation Plan = | = Implementation Plan = | ||
After all phases of implementation, existing tests must compile and pass. | After all phases of implementation, existing tests must compile and pass. | ||
A sample implementation encompassing phases 1-3 is available at [http://github.com/cquammen/ITK/tree/image-hierarchy-refactoring GitHub]. | |||
== Phase 1 == | == Phase 1 == | ||
Line 256: | Line 296: | ||
* Implement RectilinearImageBase and RectilinearImage | * Implement RectilinearImageBase and RectilinearImage | ||
* Specialize the ImageAdaptor template for RectilinearImages | * Specialize the ImageAdaptor template for RectilinearImages | ||
* Add tests for rectilinear images | * Add example tests for rectilinear images | ||
'''Example implementation complete''' | '''Example implementation complete''' | ||
== Phase 4 == | |||
* Specialize ResampleImageFilter | |||
* Specialize WarpImageFilter | |||
= Participants = | = Participants = | ||
* Cory Quammen (UNC Chapel Hill) | * Cory Quammen (UNC Chapel Hill) | ||
= Appendix: Classes that use Regular Spacing of Images = | |||
== Algorithms == | |||
** Algorithms/itkBinaryMask3DMeshSource.txx | |||
*** Should be easily modified to use TransformIndexToPhysicalPoint | |||
** Algorithms/itkCollidingFrontsImageFilter.txx | |||
*** GetSpacing() required by FastMarchingUpwindGradientImageFilter->GetOutputSpacing() | |||
** Algorithms/itkDeformableSimplexMesh3DGradientConstraintForceFilter.txx | |||
*** Should be easily modified to use TransformIndexToPhysicalPoint | |||
** Algorithms/itkDemonsRegistrationFunction.txx | |||
*** Should be able to calculate m_Normalizer by getting the volume of a voxel | |||
** Algorithms/itkFastMarchingImageFilter.txx | |||
*** ? | |||
** Algorithms/itkFastMarchingUpwindGradientImageFilter.txx | |||
*** Spacing in finite difference calculation should be replaceable by more general image spacing; images with curvilinear coordinate systems won't work | |||
** Algorithms/itkFastSymmetricForcesDemonsRegistrationFunction.txx | |||
*** Should be able to calculate m_Normalizer by getting the volume of a voxel | |||
** Algorithms/itkFEMRegistrationFilter.txx | |||
*** Spacing is passed to WarpImageFilter; could be resolved by calling SetOutputParametersFromImage() | |||
** Algorithms/itkGradientDifferenceImageToImageMetric.txx | |||
*** Spacing is passed to ResampleImageFilter; could be resolved by calling SetOutputParametersFromImage() | |||
** Algorithms/itkImageToImageMetric.txx | |||
*** Uses the largest voxel size as the sigma in an internal gradient filter | |||
** Algorithms/itkIsoContourDistanceImageFilter.txx | |||
*** ? | |||
** Algorithms/itkKLMRegionGrowImageFilter.txx | |||
*** Uses spacing to compute region border lengths; could be replaced with a method in an image class | |||
** Algorithms/itkLevelSetMotionRegistrationFunction.txx | |||
*** Uses spacing for forward difference calculation | |||
** Algorithms/itkMeanSquareRegistrationFunction.txx | |||
*** ? | |||
** Algorithms/itkMultiResolutionPDEDeformableRegistration.txx | |||
*** ? | |||
** Algorithms/itkMultiResolutionPyramidImageFilter.txx | |||
*** Sets spacing of output images at each level; it seems unlikely to want to generate irregular images for a multi-resolution pyramid | |||
** Algorithms/itkNCCRegistrationFunction.txx; | |||
*** Uses spacings in computing the gradient squared magnitude for the fixed image | |||
** Algorithms/itkPDEDeformableRegistrationFilter.txx | |||
*** Forwards spacing from output to a temporary deformation field | |||
** Algorithms/itkPointSetToImageMetric.txx | |||
*** Uses the largest voxel size as the sigma in an internal gradient filter | |||
** Algorithms/itkRayCastInterpolateImageFunction.txx | |||
*** This class is heavily tied to the assumption of regular spacing | |||
** Algorithms/itkReinitializeLevelSetImageFilter.txx | |||
*** Forwards spacing from input image to the FastMarchingImageFilterType | |||
** Algorithms/itkSymmetricForcesDemonsRegistrationFunction.txx | |||
*** Should be able to calculate m_Normalizer by getting the volume of a voxel | |||
== BasicFilters == | |||
** BasicFilters/itkAccumulateImageFilter.txx | |||
*** Essentially forwards the spacing to the output, except for the collapsed dimension which has the spacing set to the size of the original image in the collapsed dimension | |||
** BasicFilters/itkAnisotropicDiffusionImageFilter.txx | |||
*** Uses spacing to determine a timestep that produces stable solutions | |||
** BasicFilters/itkBilateralImageFilter.txx | |||
*** ? | |||
** BasicFilters/itkBSplineDownsampleImageFilter.txx | |||
*** Output image spacing is twice that of the input; should be able to do something for images with non-regular spacing | |||
** BasicFilters/itkBSplineInterpolateImageFunction.txx | |||
*** Used in derivative calculation | |||
** BasicFilters/itkBSplineUpsampleImageFilter.txx | |||
*** Output image spacing is half that of the input; should be able to do something for images with non-regular spacing | |||
** BasicFilters/itkChangeInformationImageFilter.txx | |||
*** Should probably have a special ChangeInformationImageFilter for other image types | |||
** BasicFilters/itkDanielssonDistanceMapImageFilter.txx | |||
*** ? | |||
** BasicFilters/itkDerivativeImageFilter.txx | |||
*** Used for scaling coefficient in DerivativeOperator; this may not work well for images with irregular spacing | |||
** BasicFilters/itkDiscreteGaussianImageFilter.txx | |||
*** Depends on GaussianOperator supporting irregular spacing | |||
** BasicFilters/itkDisplacementFieldJacobianDeterminantFilter.txx | |||
*** Used in m_DerivativeWeights and m_HalfDerivativeWeights, which themselves don't seem to be used anywhere | |||
** BasicFilters/itkExpandImageFilter.txx | |||
*** Should be straightforward to implement for images of irregular spacing | |||
** BasicFilters/itkExtractImageFilter.txx | |||
*** Should be straightforward to implement for images of irregular spacing | |||
** BasicFilters/itkGradientImageFilter.txx | |||
*** Depends on DerivativeOperator supporting irregular spacing | |||
** BasicFilters/itkGradientImageToBloxBoundaryPointImageFilter.txx | |||
*** Sets output image spacing to multiple of the input image spacing | |||
** BasicFilters/itkGradientMagnitudeImageFilter.txx | |||
*** Depends on DerivativeOperator supporting irregular spacing | |||
** BasicFilters/itkGradientMagnitudeRecursiveGaussianImageFilter.txx | |||
*** ? | |||
** BasicFilters/itkGradientRecursiveGaussianImageFilter.txx | |||
*** Spacing used to divide output scalar values | |||
** BasicFilters/itkHessianRecursiveGaussianImageFilter.txx | |||
*** Used to normalize output values | |||
** BasicFilters/itkHoughTransform2DCirclesImageFilter.txx | |||
*** Forwards spacing from input image to radius image | |||
** BasicFilters/itkHoughTransform2DLinesImageFilter.txx | |||
*** Forwards spacing from input image to m_SimplifyAccumulator image | |||
** BasicFilters/itkImportImageFilter.h | |||
*** Would need to write a version for images with irregular spacing | |||
** BasicFilters/itkInterpolateImagePointsFilter.txx | |||
*** Spacing of the image specifying the x-coordinates of the interpolation points is used as the spacing of the output image; this is rather arbitrary as the output image sample coordinates are arbitrary | |||
** BasicFilters/itkInverseDeformationFieldImageFilter.txx | |||
*** A scale factor of the input image spacing is used as the output image spacing | |||
** BasicFilters/itkIterativeInverseDeformationFieldImageFilter.txx | |||
*** Sets output spacing to that of the input image | |||
** BasicFilters/itkJoinSeriesImageFilter.txx | |||
*** Spacing of new dimension is set by the filter; this would have to be an array of spacings for a RectilinearImage | |||
** BasicFilters/itkLaplacianImageFilter.txx | |||
*** Depends on LaplacianOperator supporting irregular spacing | |||
** BasicFilters/itkLaplacianRecursiveGaussianImageFilter.txx | |||
*** Uses spacing as normalizer | |||
** BasicFilters/itkLaplacianSharpeningImageFilter.txx | |||
*** Depends on LaplacianOperator supporting irregular spacing | |||
** BasicFilters/itkParallelSparseFieldLevelSetImageFilter.txx | |||
*** ? | |||
** BasicFilters/itkPermuteAxesImageFilter.txx | |||
*** Forwards spacing of input image to the output image | |||
** BasicFilters/itkPolylineMask2DImageFilter.txx | |||
*** Forwards spacing from input to output image | |||
** BasicFilters/itkPolylineMaskImageFilter.txx | |||
*** Forwards spacing from input to output image | |||
** BasicFilters/itkProjectionImageFilter.txx | |||
*** Forwards spacing from input to output image | |||
** BasicFilters/itkRecursiveSeparableImageFilter.txx | |||
*** Regular spacing assumption is encoded as a parameter in the SetUp pure virtual method | |||
** BasicFilters/itkRelabelComponentImageFilter.txx | |||
*** Spacing used to compute volume of voxels | |||
** BasicFilters/itkResampleImageFilter.txx | |||
*** Discussed in more detail below | |||
** BasicFilters/itkShrinkImageFilter.txx | |||
*** Filter shrinks an image to an integer multiple of the original image size | |||
** BasicFilters/itkSignedMaurerDistanceMapImageFilter.txx | |||
*** Uses spacing to map index of voxel position to physical space | |||
** BasicFilters/itkSparseFieldLevelSetImageFilter.txx | |||
*** ? | |||
** BasicFilters/itkSpatialObjectToImageStatisticsCalculator.txx | |||
*** Used to remove spacing considerations from an internal FloodFill iterator | |||
** BasicFilters/itkTileImageFilter.txx | |||
*** Forwards spacing from input to output image | |||
** BasicFilters/itkTriangleMeshToBinaryImageFilter.txx | |||
*** Generates image with a given spacing | |||
** BasicFilters/itkUnaryFunctorImageFilter.txx | |||
*** Forwards spacing from input to output image | |||
** BasicFilters/itkVectorExpandImageFilter.txx | |||
*** Output image spacing is an integer multiple of input image spacing | |||
** BasicFilters/itkVectorGradientMagnitudeImageFilter.txx | |||
*** Spacing used as derivative weights | |||
** BasicFilters/itkWarpImageFilter.txx | |||
*** See discussion below | |||
== Common == | |||
** Common/itkAnnulusOperator.h | |||
*** Uses spacing to ensure annulus is spherical | |||
** Common/itkBSplineDeformableTransform.txx | |||
*** Used to set the coefficient grid spacing | |||
** Common/itkCentralDifferenceImageFunction.txx | |||
*** Used in finite difference calculation | |||
** Common/itkDenseFiniteDifferenceImageFilter.txx | |||
*** Used to set spacing of output image | |||
** Common/itkFiniteDifferenceImageFilter.txx | |||
*** Spacing used in finite difference coefficients | |||
** Common/itkFloodFilledFunctionConditionalConstIterator.txx | |||
*** Not clear where the spacing is used. | |||
** Common/itkGaussianBlurImageFunction.txx | |||
*** Depends on irregular spacing support in GaussianOperator | |||
** Common/itkGaussianDerivativeImageFunction.txx | |||
*** Depends on irregular spacing support in GaussianOperator | |||
** Common/itkImageDuplicator.txx | |||
*** Forwards spacing of input image to output image | |||
** Common/itkPathConstIterator.txx | |||
*** Not clear where the spacing is used. | |||
== IO == | |||
** IO/itkGDCMImageIO.cxx | |||
*** Sets spacing from image | |||
** IO/itkImageFileReader.txx | |||
*** Sets spacing from image | |||
** IO/itkImageFileWriter.txx | |||
*** Writes spacing to file | |||
** IO/itkImageIOBase.h | |||
*** Spacing goes to/comes from image file | |||
** IO/itkImageSeriesReader.txx | |||
*** Produces regular image | |||
** IO/itkImageSeriesWriter.txx | |||
*** Geared to images with regular spacing | |||
** IO/itkMetaImageIO.cxx | |||
*** Geared to images with regular spacing | |||
** IO/itkNiftiImageIO.cxx | |||
*** Geared to images with regular spacing | |||
** IO/itkNrrdImageIO.cxx | |||
*** Geared to images with regular spacing | |||
== Numerics == | |||
** Numerics/Statistics/itkHistogramToImageFilter.h | |||
*** Sets size of output image | |||
== Review == | |||
** Review/itkAreaClosingImageFilter.h | |||
*** Can optionally use spacing to compute area. | |||
** Review/itkAreaOpeningImageFilter.h | |||
*** Can optionally use spacing to compute area. | |||
** Review/itkBSplineDeformableTransformInitializer.txx | |||
*** Uses image spacing to calculate grid spacing | |||
** Review/itkBSplineScatteredDataPointSetToImageFilter.txx | |||
*** ? | |||
** Review/itkConstrainedRegionBasedLevelSetFunctionSharedData.h | |||
*** Spacing used to determine query points | |||
** Review/itkDiffeomorphicDemonsRegistrationFilter.txx | |||
*** Sets output spacing to that of input | |||
** Review/itkDirectFourierReconstructionImageToImageFilter.txx | |||
*** Spacing of output image set from input image | |||
** Review/itkDiscreteGaussianDerivativeImageFilter.txx | |||
*** Depends on GaussianDerivativeOperator | |||
** Review/itkDiscreteGaussianDerivativeImageFunction.txx | |||
*** Depends on GaussianDerivativeOperator | |||
** Review/itkDiscreteGradientMagnitudeGaussianImageFunction.txx | |||
*** Depends on GaussianDerivativeOperator | |||
** Review/itkDiscreteHessianGaussianImageFunction.txx | |||
*** Used by NeighborhoodOperatorImageFunction | |||
** Review/itkESMDemonsRegistrationFunction.txx | |||
*** Spacing is used to computer normalizer | |||
** Review/itkExponentialDeformationFieldImageFilter.txx | |||
*** Used to calculate number of iterations | |||
** Review/itkFastSymmetricForcesDemonsRegistrationFilter.txx | |||
*** Copies input spacing to output image | |||
** Review/itkGaborImageSource.txx | |||
*** User sets spacing | |||
** Review/itkGridForwardWarpImageFilter.txx | |||
*** Copies input spacing to output image | |||
** Review/itkGridImageSource.txx | |||
*** User sets spacing | |||
** Review/itkJPEG2000ImageIO.cxx | |||
*** Produces regular images | |||
** Review/itkLabelGeometryImageFilter.txx | |||
*** Copies input spacing to output spacing | |||
** Review/itkLabelPerimeterEstimationCalculator.txx | |||
*** Uses spacing to compute physical size of voxels | |||
** Review/itkMINC2ImageIO.cxx | |||
*** Produces regular images | |||
** Review/itkMultiphaseFiniteDifferenceImageFilter.txx | |||
*** Spacing used for scale coefficients in the difference functions | |||
** Review/itkMultiphaseSparseFiniteDifferenceImageFilter.txx | |||
*** ? | |||
** Review/itkRegionBasedLevelSetFunction.h | |||
*** Spacing used in gradient computation | |||
** Review/itkShapedFloodFilledFunctionConditionalConstIterator.txx | |||
*** ? | |||
** Review/itkShapeLabelMapFilter.txx | |||
*** Spacing used for physical volume measurements | |||
** Review/itkStatisticsLabelMapFilter.txx | |||
*** Used for statistics of physical dimensions of voxels | |||
** Review/itkStochasticFractalDimensionImageFilter.txx | |||
*** ? | |||
** Review/itkStreamingImageIOBase.cxx | |||
*** Produces images with regular spacing | |||
** Review/itkTransformToDeformationFieldSource.txx | |||
*** Can optionally use spacing from reference image | |||
** Review/itkVectorCentralDifferenceImageFunction.txx | |||
*** Used in derivative weights | |||
** Review/itkVTKImageIO2.cxx | |||
*** Produces images with regular spacing | |||
** Review/itkWarpHarmonicEnergyCalculator.txx | |||
*** Used in derivative weights | |||
== Spatial Object == | |||
** SpatialObject/itkImageSpatialObject.txx | |||
*** spacing doesn't seem to be used | |||
** SpatialObject/itkMetaImageConverter.txx | |||
*** Spacing is set on the metaimage. | |||
** SpatialObject/itkSpatialObject.h | |||
*** spacing is essentially a geometric scaling factor |
Latest revision as of 18:32, 16 October 2010
Image Class Hierarchy Refactoring
The goal of this proposal is to refactor ITK's image class hierarchy to make adding other image types to ITK easier and to simplify the interface of image classes wherever possible.
Motivation
ITK currently supports several types of image:
- Image
- VectorImage
- SpecialCoordinatesImage
- BloxImage
- SparseImage
- LabelMap
- ImageAdaptors and subclasses
- Slice contiguous, sparse, and single-bit binary images - Insight Journal article from Dan Mueller
Most of the image types supported by ITK assume that the image topology is an n-dimensional lattice and that voxels have regular physical spacing in each dimension. While it makes sense to preserve the topology assumption in a library focused on image analysis, the regular spacing assumption should be relaxed wherever possible. The regular spacing assumption covers many cases in biomedical imaging, but it is insufficient for certain types of images in other applications. For example, certain motorized stages used in fluorescence microscopes fail to achieve regular spacing in z when acquiring a 3D image. Helpfully, these stages report the positions of z-planes acquired during image stack collection. Assuming a regular z-spacing in place of the actual z-plane positions may result in significant errors in image analysis algorithms run on the image.
It is possible to create image types in ITK that do not assume regular spacing: PhasedArray3DSpecialCoordinatesImage is an example. Nevertheless, its interface still has the SetSpacing() and GetSpacing() methods defined in the ImageBase class (and overriden in SpecialCoordinatesImage). These methods are required for compatibility in filter pipelines, but their presence in this class is misleading; they do nothing. Other types of images may consist of samples not associated with a physical space. For these image types, class methods for setting metadata about the physical embedding of the image are not needed.
Goals
The primary goal in this refactoring is to produce a logical image class hierarchy in ITK that removes methods in image types where they are not needed.
The secondary goal is to add a RectilinearImage class, a physically embedded image with origin, irregular spacing in each dimension, and orientation.
Requirements
- Make changes fully backwards compatible with examples and tests (all examples and tests should compile and run without modification and all tests should pass)
- Each of the physically embedded image types will properly calculate transforms from indices to physical coordinates and back.
- All physically embedded images should support orientations.
- ImageAdaptors should work on all image types
- Resampling should be supported for all physically embedded image types
- Conversion of new image types to appropriate VTK classes for visualization
Challenges and Potential Pitfalls
- ImageAdaptors should present the correct interface for the image type they adapt. This can be accomplished with partial template specialization of the ImageAdaptor class to avoid modifying any of the existing adaptors.
- Numerous classes use regular spacing of images (they call GetSpacing()) directly and will need to be modified to handle the new image types or be restricted to work with only image types with regular sample spacing. A list of these classes can be found at the appendix at the end of this page.
- Filters that require voxel positions should ideally use methods TransformIndexToPhysicalPoint, etc., but this may not be optimal for performance.
- Adding image types will add significant compilation time to wrapping
Design
ImageBase will be stripped to the bare minimum functionality required to support images with lattice topology. Other image types will have more specialized base classes, all descended (perhaps indirectly) from ImageBase. The base classes will provide support for additional image metadata.
Class Hierarchy
The class hierarchy will look like this:
- ImageBase< unsigned int VDimension >
- PhysicalImageBase< unsigned int VDimension >
- RegularImageBase< unsigned int VDimension >
- Image< class TPixel, unsigned int VDimension >
- BloxImage< class TPixel, unsigned int VDimension >
- BloxImage subclasses
- SparseImage< class TNode, unsigned int VDimension >
- BloxImage< class TPixel, unsigned int VDimension >
- VectorImage< class TPixel, unsigned int VDimension >
- LabelMap< class TPixel, unsigned int VDimension >
- Image< class TPixel, unsigned int VDimension >
- RectilinearImageBase < unsigned int VDimension >
- RectilinearImage <class TPixel, unsigned in VDimension >
- PhasedArray3DSpecialCoordinatesImage< class TPixel >
- RegularImageBase< unsigned int VDimension >
- PhysicalImageBase< unsigned int VDimension >
All base image classes specify the interface for only the metadata of the image. This design is required to support the method CopyInformation(). For example, you may encounter a situation where you copy information from a RectilinearImage<float, 3> to a RectilinearImage<double, 3>. Dynamic casting from a RectilinearImage<float, 3> to a RectilinearImage<double, 3> won't work, so the method will throw an exception. Casting a RectilinearImage<float, 3> to a RectilinearImageBase< 3 > will work, enabling access to the metadata methods (GetSpacing(), GetOrigin(), etc.) from the source image.
Specific methods defined or overridden in each class are provided below.
Class Diagram
Image Types
ImageBase
Methods:
- Allocate()
- ComputeIndex()
- ComputeOffset()
- ComputeOffsetTable()
- CopyInformation()
- GetBufferedRegion()
- GetImageDimension()
- GetLargestPossibleRegion()
- GetNumberOfComponentsPerPixel()
- GetOffsetTable()
- GetRequestedRegion()
- Graft()
- Initialize()
- InitializeBufferedRegion()
- RequestedRegionIsOutsideOfTheBufferedRegion()
- SetBufferedRegion()
- SetLargestPossibleRegion()
- SetNumberOfComponentsPerPixel()
- SetRequestedRegion(const RegionType ®ion)
- SetRequestedRegion(DataObject *data)
- SetRequestedRegionToLargestPossibleRegion()
- UpdateOutputData()
- UpdateOutputInformation()
PhysicalImageBase
Methods overridden from ImageBase
- CopyInformation()
Additional methods
- GetOrigin()
- SetOrigin()
- GetDirection()
- SetDirection()
RegularImageBase
Methods overridden from PhysicalImageBase
- CopyInformation()
Additional methods
- ComputeIndexToPhysicalPointMatrices()
- GetSpacing()
- SetSpacing()
- TransformContinuousIndexToPhysicalPoint(const ContinuousIndex< TCoordRep, VImageDimension > &index, Point< TCoordRep, VImageDimension > &point) const
- TransformIndexToPhysicalPoint(const IndexType &index, Point< TCoordRep, VImageDimension > &point) const
- TransformLocalVectorToPhysicalVector(const FixedArray< TCoordRep, VImageDimension > &inputGradient, FixedArray< TCoordRep, VImageDimension > &outputGradient) const
- TransformPhysicalPointToContinuousIndex(const Point< TCoordRep, VImageDimension > &point, ContinuousIndex< TCoordRep, VImageDimension > &index) const
- TransformPhysicalPointToIndex(const Point< TCoordRep, VImageDimension > &point, IndexType &index) const
Image (subclass of itkRegularImageBase)
Methods overridden from RegularImageBase
- Allocate()
- Graft()
- Initialize()
Additional methods
- operator[]
- FillBuffer()
- GetBufferPointer()
- GetNeighborhoodAccessor()
- GetPixel(const IndexType &index) const
- GetPixel(const IndexType &index)
- GetPixelAccessor(void)
- GetPixelAccessor(void) const
- GetPixelContainer()
- GetPixelContainer() const
- SetNeighborhoodAccessor()
- SetPixel(const IndexType &index, const TPixel &value)
- SetPixelContainer(PixelContainer *container)
RectilinearImageBase
Methods overridden from PhysicalImageBase
- CopyInformation()
- SetLargestPossibleRegion()
Additional methods
- ComputeSpacingPrefixSum()
- GetDefaultSpacing()
- GetDimensionSpacing(unsigned int dimension)
- InitializeWithDefaultSpacings()
- SetDefaultSpacing()
- SetSpacing(unsigned int dimension, long index, Array<PointValueType>)
- TransformContinuousIndexToPhysicalPoint(const ContinuousIndex< TCoordRep, VImageDimension > &index, Point< TCoordRep, VImageDimension > &point) const
- TransformIndexToPhysicalPoint(const IndexType &index, Point< TCoordRep, VImageDimension > &point) const
- TransformLocalVectorToPhysicalVector(const FixedArray< TCoordRep, VImageDimension > &inputGradient, FixedArray< TCoordRep, VImageDimension > &outputGradient) const
- TransformPhysicalPointToContinuousIndex(const Point< TCoordRep, VImageDimension > &point, ContinuousIndex< TCoordRep, VImageDimension > &index) const
- TransformPhysicalPointToIndex(const Point< TCoordRep, VImageDimension > &point, IndexType &index) const
RectilinearImage
Methods overridden from RectilinearImageBase
- Allocate()
- Graft()
- Initialize()
Additional methods
- operator[]
- FillBuffer()
- GetBufferPointer()
- GetPixel(const IndexType &index) const
- GetPixel(const IndexType &index)
- GetPixelAccessor(void)
- GetPixelAccessor(void) const
- GetPixelContainer()
- GetPixelContainer() const
- GetNeighborhoodAccessor()
- GetNeighborhoodAccessor() const
- SetPixel(const IndexType &index, const TPixel &value)
- SetPixelContainer(PixelContainer *container)
LabelMap
No change needed, but the new interface will not have the methods:
- GetDirection()
- GetSpacing()
- SetDirection()
- SetSpacing()
If LabelMaps have a physical embedding, then the LabelMap class should be changed to inherit from PhysicalImageBase.
BloxImage
This class currently descends from Image. If it has no spatial embedding, then it could be changed to descend from a new DigitalImage class.
SparseImage
This class currently descends from Image. If it has no spatial embedding, then it could be changed to descend from a new DigitalImage class.
ImageAdaptors
The ImageAdaptor class should be designed to present the proper API for each of the new image types. This requires partial template specialization of the ImageAdaptor template class to maintain backwards compatibility. Specifically, several definitions of the ImageAdaptor class will need to be defined, one for each image type.
To work with the CopyInformation() method in the various Image subclasses, each ImageBase type (RegularImageBase, RectilinearImageBase, etc.) will need to have a corresponding ImageAdaptor type (RegularImageAdaptor, RectilinearImageAdaptor, etc.), each of which is a subclass of its corresponding image base type. They CANNOT be subclasses of the image types with pixel containers because of the problem with dynamic casting in the CopyInformation() method mentioned above.
ResampleImageFilter and WarpImageFilter
The method SetOutputParametersFromImage() takes an ImageBase as input. Now that the metadata is stored in subclasses of ImageBase, this may be suboptimal.
One solution is to try to dynamic_cast the ImageBase input to the various descendants of ImageBase (PhysicalImageBase, RegularImageBase, RectilinearImageBase, etc.). Upon successful casting, the relevant parameters from the ImageBase input can be copied over to the filter. However, say we're resampling to a RectilinearImage with the ResampleImageFilter. The ResampleImageFilter would need to have a method to support individual voxel spacings. But this method isn't needed for resampling to an Image, so it would go to waste.
Alternatively, these classes could be specialized for the output image type much like the ImageAdaptor is specialized. This seems like the best option.
Outstanding Questions
- Are BloxImages and SparseImages physically embedded images?
- Should image sources be specialized for different image types?
- Will interpolators work out-of-the-box for Images with implementations of TransformIndexToPhysicalPoint, etc?
- File readers?
- Use concept checking in filters and image sources to check support for input/output image types?
Implementation Plan
After all phases of implementation, existing tests must compile and pass.
A sample implementation encompassing phases 1-3 is available at GitHub.
Phase 1
- Implement PhysicalImageBase< unsigned int VDimension >
- Implement RegularImageBase
- Make Image and VectorImage subclasses of RegularImageBase
- Make SpecialCoordinatesImage a subclass of RegularImageBase
Example implementation complete
Phase 2
- Write RegularImageAdaptor
- Specialize the ImageAdaptor template for Image, VectorImage, and PhasedArray3DSpecialCoordinatesImage classes.
- Remove unnecessary methods from adaptor classes.
- Remove unnecessary methods, typedefs, and member variables from ImageBase, PhysicalImageBase, and RegularImageBase.
Example implementation complete
Phase 3
- Implement RectilinearImageBase and RectilinearImage
- Specialize the ImageAdaptor template for RectilinearImages
- Add example tests for rectilinear images
Example implementation complete
Phase 4
- Specialize ResampleImageFilter
- Specialize WarpImageFilter
Participants
- Cory Quammen (UNC Chapel Hill)
Appendix: Classes that use Regular Spacing of Images
Algorithms
- Algorithms/itkBinaryMask3DMeshSource.txx
- Should be easily modified to use TransformIndexToPhysicalPoint
- Algorithms/itkCollidingFrontsImageFilter.txx
- GetSpacing() required by FastMarchingUpwindGradientImageFilter->GetOutputSpacing()
- Algorithms/itkDeformableSimplexMesh3DGradientConstraintForceFilter.txx
- Should be easily modified to use TransformIndexToPhysicalPoint
- Algorithms/itkDemonsRegistrationFunction.txx
- Should be able to calculate m_Normalizer by getting the volume of a voxel
- Algorithms/itkFastMarchingImageFilter.txx
- ?
- Algorithms/itkFastMarchingUpwindGradientImageFilter.txx
- Spacing in finite difference calculation should be replaceable by more general image spacing; images with curvilinear coordinate systems won't work
- Algorithms/itkFastSymmetricForcesDemonsRegistrationFunction.txx
- Should be able to calculate m_Normalizer by getting the volume of a voxel
- Algorithms/itkFEMRegistrationFilter.txx
- Spacing is passed to WarpImageFilter; could be resolved by calling SetOutputParametersFromImage()
- Algorithms/itkGradientDifferenceImageToImageMetric.txx
- Spacing is passed to ResampleImageFilter; could be resolved by calling SetOutputParametersFromImage()
- Algorithms/itkImageToImageMetric.txx
- Uses the largest voxel size as the sigma in an internal gradient filter
- Algorithms/itkIsoContourDistanceImageFilter.txx
- ?
- Algorithms/itkKLMRegionGrowImageFilter.txx
- Uses spacing to compute region border lengths; could be replaced with a method in an image class
- Algorithms/itkLevelSetMotionRegistrationFunction.txx
- Uses spacing for forward difference calculation
- Algorithms/itkMeanSquareRegistrationFunction.txx
- ?
- Algorithms/itkMultiResolutionPDEDeformableRegistration.txx
- ?
- Algorithms/itkMultiResolutionPyramidImageFilter.txx
- Sets spacing of output images at each level; it seems unlikely to want to generate irregular images for a multi-resolution pyramid
- Algorithms/itkNCCRegistrationFunction.txx;
- Uses spacings in computing the gradient squared magnitude for the fixed image
- Algorithms/itkPDEDeformableRegistrationFilter.txx
- Forwards spacing from output to a temporary deformation field
- Algorithms/itkPointSetToImageMetric.txx
- Uses the largest voxel size as the sigma in an internal gradient filter
- Algorithms/itkRayCastInterpolateImageFunction.txx
- This class is heavily tied to the assumption of regular spacing
- Algorithms/itkReinitializeLevelSetImageFilter.txx
- Forwards spacing from input image to the FastMarchingImageFilterType
- Algorithms/itkSymmetricForcesDemonsRegistrationFunction.txx
- Should be able to calculate m_Normalizer by getting the volume of a voxel
- Algorithms/itkBinaryMask3DMeshSource.txx
BasicFilters
- BasicFilters/itkAccumulateImageFilter.txx
- Essentially forwards the spacing to the output, except for the collapsed dimension which has the spacing set to the size of the original image in the collapsed dimension
- BasicFilters/itkAnisotropicDiffusionImageFilter.txx
- Uses spacing to determine a timestep that produces stable solutions
- BasicFilters/itkBilateralImageFilter.txx
- ?
- BasicFilters/itkBSplineDownsampleImageFilter.txx
- Output image spacing is twice that of the input; should be able to do something for images with non-regular spacing
- BasicFilters/itkBSplineInterpolateImageFunction.txx
- Used in derivative calculation
- BasicFilters/itkBSplineUpsampleImageFilter.txx
- Output image spacing is half that of the input; should be able to do something for images with non-regular spacing
- BasicFilters/itkChangeInformationImageFilter.txx
- Should probably have a special ChangeInformationImageFilter for other image types
- BasicFilters/itkDanielssonDistanceMapImageFilter.txx
- ?
- BasicFilters/itkDerivativeImageFilter.txx
- Used for scaling coefficient in DerivativeOperator; this may not work well for images with irregular spacing
- BasicFilters/itkDiscreteGaussianImageFilter.txx
- Depends on GaussianOperator supporting irregular spacing
- BasicFilters/itkDisplacementFieldJacobianDeterminantFilter.txx
- Used in m_DerivativeWeights and m_HalfDerivativeWeights, which themselves don't seem to be used anywhere
- BasicFilters/itkExpandImageFilter.txx
- Should be straightforward to implement for images of irregular spacing
- BasicFilters/itkExtractImageFilter.txx
- Should be straightforward to implement for images of irregular spacing
- BasicFilters/itkGradientImageFilter.txx
- Depends on DerivativeOperator supporting irregular spacing
- BasicFilters/itkGradientImageToBloxBoundaryPointImageFilter.txx
- Sets output image spacing to multiple of the input image spacing
- BasicFilters/itkGradientMagnitudeImageFilter.txx
- Depends on DerivativeOperator supporting irregular spacing
- BasicFilters/itkGradientMagnitudeRecursiveGaussianImageFilter.txx
- ?
- BasicFilters/itkGradientRecursiveGaussianImageFilter.txx
- Spacing used to divide output scalar values
- BasicFilters/itkHessianRecursiveGaussianImageFilter.txx
- Used to normalize output values
- BasicFilters/itkHoughTransform2DCirclesImageFilter.txx
- Forwards spacing from input image to radius image
- BasicFilters/itkHoughTransform2DLinesImageFilter.txx
- Forwards spacing from input image to m_SimplifyAccumulator image
- BasicFilters/itkImportImageFilter.h
- Would need to write a version for images with irregular spacing
- BasicFilters/itkInterpolateImagePointsFilter.txx
- Spacing of the image specifying the x-coordinates of the interpolation points is used as the spacing of the output image; this is rather arbitrary as the output image sample coordinates are arbitrary
- BasicFilters/itkInverseDeformationFieldImageFilter.txx
- A scale factor of the input image spacing is used as the output image spacing
- BasicFilters/itkIterativeInverseDeformationFieldImageFilter.txx
- Sets output spacing to that of the input image
- BasicFilters/itkJoinSeriesImageFilter.txx
- Spacing of new dimension is set by the filter; this would have to be an array of spacings for a RectilinearImage
- BasicFilters/itkLaplacianImageFilter.txx
- Depends on LaplacianOperator supporting irregular spacing
- BasicFilters/itkLaplacianRecursiveGaussianImageFilter.txx
- Uses spacing as normalizer
- BasicFilters/itkLaplacianSharpeningImageFilter.txx
- Depends on LaplacianOperator supporting irregular spacing
- BasicFilters/itkParallelSparseFieldLevelSetImageFilter.txx
- ?
- BasicFilters/itkPermuteAxesImageFilter.txx
- Forwards spacing of input image to the output image
- BasicFilters/itkPolylineMask2DImageFilter.txx
- Forwards spacing from input to output image
- BasicFilters/itkPolylineMaskImageFilter.txx
- Forwards spacing from input to output image
- BasicFilters/itkProjectionImageFilter.txx
- Forwards spacing from input to output image
- BasicFilters/itkRecursiveSeparableImageFilter.txx
- Regular spacing assumption is encoded as a parameter in the SetUp pure virtual method
- BasicFilters/itkRelabelComponentImageFilter.txx
- Spacing used to compute volume of voxels
- BasicFilters/itkResampleImageFilter.txx
- Discussed in more detail below
- BasicFilters/itkShrinkImageFilter.txx
- Filter shrinks an image to an integer multiple of the original image size
- BasicFilters/itkSignedMaurerDistanceMapImageFilter.txx
- Uses spacing to map index of voxel position to physical space
- BasicFilters/itkSparseFieldLevelSetImageFilter.txx
- ?
- BasicFilters/itkSpatialObjectToImageStatisticsCalculator.txx
- Used to remove spacing considerations from an internal FloodFill iterator
- BasicFilters/itkTileImageFilter.txx
- Forwards spacing from input to output image
- BasicFilters/itkTriangleMeshToBinaryImageFilter.txx
- Generates image with a given spacing
- BasicFilters/itkUnaryFunctorImageFilter.txx
- Forwards spacing from input to output image
- BasicFilters/itkVectorExpandImageFilter.txx
- Output image spacing is an integer multiple of input image spacing
- BasicFilters/itkVectorGradientMagnitudeImageFilter.txx
- Spacing used as derivative weights
- BasicFilters/itkWarpImageFilter.txx
- See discussion below
- BasicFilters/itkAccumulateImageFilter.txx
Common
- Common/itkAnnulusOperator.h
- Uses spacing to ensure annulus is spherical
- Common/itkBSplineDeformableTransform.txx
- Used to set the coefficient grid spacing
- Common/itkCentralDifferenceImageFunction.txx
- Used in finite difference calculation
- Common/itkDenseFiniteDifferenceImageFilter.txx
- Used to set spacing of output image
- Common/itkFiniteDifferenceImageFilter.txx
- Spacing used in finite difference coefficients
- Common/itkFloodFilledFunctionConditionalConstIterator.txx
- Not clear where the spacing is used.
- Common/itkGaussianBlurImageFunction.txx
- Depends on irregular spacing support in GaussianOperator
- Common/itkGaussianDerivativeImageFunction.txx
- Depends on irregular spacing support in GaussianOperator
- Common/itkImageDuplicator.txx
- Forwards spacing of input image to output image
- Common/itkPathConstIterator.txx
- Not clear where the spacing is used.
- Common/itkAnnulusOperator.h
IO
- IO/itkGDCMImageIO.cxx
- Sets spacing from image
- IO/itkImageFileReader.txx
- Sets spacing from image
- IO/itkImageFileWriter.txx
- Writes spacing to file
- IO/itkImageIOBase.h
- Spacing goes to/comes from image file
- IO/itkImageSeriesReader.txx
- Produces regular image
- IO/itkImageSeriesWriter.txx
- Geared to images with regular spacing
- IO/itkMetaImageIO.cxx
- Geared to images with regular spacing
- IO/itkNiftiImageIO.cxx
- Geared to images with regular spacing
- IO/itkNrrdImageIO.cxx
- Geared to images with regular spacing
- IO/itkGDCMImageIO.cxx
Numerics
- Numerics/Statistics/itkHistogramToImageFilter.h
- Sets size of output image
- Numerics/Statistics/itkHistogramToImageFilter.h
Review
- Review/itkAreaClosingImageFilter.h
- Can optionally use spacing to compute area.
- Review/itkAreaOpeningImageFilter.h
- Can optionally use spacing to compute area.
- Review/itkBSplineDeformableTransformInitializer.txx
- Uses image spacing to calculate grid spacing
- Review/itkBSplineScatteredDataPointSetToImageFilter.txx
- ?
- Review/itkConstrainedRegionBasedLevelSetFunctionSharedData.h
- Spacing used to determine query points
- Review/itkDiffeomorphicDemonsRegistrationFilter.txx
- Sets output spacing to that of input
- Review/itkDirectFourierReconstructionImageToImageFilter.txx
- Spacing of output image set from input image
- Review/itkDiscreteGaussianDerivativeImageFilter.txx
- Depends on GaussianDerivativeOperator
- Review/itkDiscreteGaussianDerivativeImageFunction.txx
- Depends on GaussianDerivativeOperator
- Review/itkDiscreteGradientMagnitudeGaussianImageFunction.txx
- Depends on GaussianDerivativeOperator
- Review/itkDiscreteHessianGaussianImageFunction.txx
- Used by NeighborhoodOperatorImageFunction
- Review/itkESMDemonsRegistrationFunction.txx
- Spacing is used to computer normalizer
- Review/itkExponentialDeformationFieldImageFilter.txx
- Used to calculate number of iterations
- Review/itkFastSymmetricForcesDemonsRegistrationFilter.txx
- Copies input spacing to output image
- Review/itkGaborImageSource.txx
- User sets spacing
- Review/itkGridForwardWarpImageFilter.txx
- Copies input spacing to output image
- Review/itkGridImageSource.txx
- User sets spacing
- Review/itkJPEG2000ImageIO.cxx
- Produces regular images
- Review/itkLabelGeometryImageFilter.txx
- Copies input spacing to output spacing
- Review/itkLabelPerimeterEstimationCalculator.txx
- Uses spacing to compute physical size of voxels
- Review/itkMINC2ImageIO.cxx
- Produces regular images
- Review/itkMultiphaseFiniteDifferenceImageFilter.txx
- Spacing used for scale coefficients in the difference functions
- Review/itkMultiphaseSparseFiniteDifferenceImageFilter.txx
- ?
- Review/itkRegionBasedLevelSetFunction.h
- Spacing used in gradient computation
- Review/itkShapedFloodFilledFunctionConditionalConstIterator.txx
- ?
- Review/itkShapeLabelMapFilter.txx
- Spacing used for physical volume measurements
- Review/itkStatisticsLabelMapFilter.txx
- Used for statistics of physical dimensions of voxels
- Review/itkStochasticFractalDimensionImageFilter.txx
- ?
- Review/itkStreamingImageIOBase.cxx
- Produces images with regular spacing
- Review/itkTransformToDeformationFieldSource.txx
- Can optionally use spacing from reference image
- Review/itkVectorCentralDifferenceImageFunction.txx
- Used in derivative weights
- Review/itkVTKImageIO2.cxx
- Produces images with regular spacing
- Review/itkWarpHarmonicEnergyCalculator.txx
- Used in derivative weights
- Review/itkAreaClosingImageFilter.h
Spatial Object
- SpatialObject/itkImageSpatialObject.txx
- spacing doesn't seem to be used
- SpatialObject/itkMetaImageConverter.txx
- Spacing is set on the metaimage.
- SpatialObject/itkSpatialObject.h
- spacing is essentially a geometric scaling factor
- SpatialObject/itkImageSpatialObject.txx