Skip to content

Commit

Permalink
ENH: Add IsSameImageGeometryAs convenience method to ImageBase
Browse files Browse the repository at this point in the history
  • Loading branch information
dzenanz committed Feb 26, 2024
1 parent ef28b0f commit a7c0f32
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
18 changes: 18 additions & 0 deletions Modules/Core/Common/include/itkImageBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,24 @@ class ITK_TEMPLATE_EXPORT ImageBase : public DataObject
bool
VerifyRequestedRegion() override;

/** Checks whether the images' pixels with the same index occupy the same physical space.
* Compares the origin, spacing, and direction for equality within provided tolerances.
* There is no check for valid regions in between the images. */
bool
IsCongruentImageGeometry(const ImageBase * otherImage, double coordinateTolerance, double directionTolerance) const;

/** Check whether this image and the other image have the same grid in physical space.
* Compares largest possible regions for equality, and the origin, spacing,
* and direction cosines for equality within provided tolerances.
* See also: ImageToImageFilter, namely:
* https://github.com/InsightSoftwareConsortium/ITK/blob/v5.3.0/Modules/Core/Common/include/itkImageToImageFilter.h#L78-L92
* https://github.com/InsightSoftwareConsortium/ITK/blob/v5.3.0/Modules/Core/Common/src/itkImageToImageFilterCommon.cxx#L26-L27
*/
bool
IsSameImageGeometryAs(const ImageBase * otherImage,
double coordinateTolerance = 1e-6,
double directionTolerance = 1e-6) const;

/** INTERNAL This method is used internally by filters to copy meta-data from
* the output to the input. Users should not have a need to use this method.
*
Expand Down
32 changes: 32 additions & 0 deletions Modules/Core/Common/include/itkImageBase.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,38 @@ ImageBase<VImageDimension>::VerifyRequestedRegion()
}


template <unsigned int VImageDimension>
bool
ImageBase<VImageDimension>::IsCongruentImageGeometry(const ImageBase * otherImage,
double coordinateTolerance,
double directionTolerance) const
{
// check that the image occupy the same physical space, and that
// each index is at the same physical location

// tolerance for origin and spacing depends on the size of pixel
// tolerance for directions a fraction of the unit cube.
const SpacePrecisionType coordinateTol =
itk::Math::abs(coordinateTolerance * this->GetSpacing()[0]); // use first dimension spacing

return this->GetOrigin().GetVnlVector().is_equal(otherImage->GetOrigin().GetVnlVector(), coordinateTol) &&
this->GetSpacing().GetVnlVector().is_equal(otherImage->GetSpacing().GetVnlVector(), coordinateTol) &&
this->GetDirection().GetVnlMatrix().as_ref().is_equal(otherImage->GetDirection().GetVnlMatrix().as_ref(),
directionTolerance);
}


template <unsigned int VImageDimension>
bool
ImageBase<VImageDimension>::IsSameImageGeometryAs(const ImageBase * otherImage,
double coordinateTolerance,
double directionTolerance) const
{
return this->IsCongruentImageGeometry(otherImage, coordinateTolerance, directionTolerance) &&
this->GetLargestPossibleRegion() == otherImage->GetLargestPossibleRegion();
}


template <unsigned int VImageDimension>
void
ImageBase<VImageDimension>::SetBufferedRegion(const RegionType & region)
Expand Down
5 changes: 1 addition & 4 deletions Modules/Core/Common/include/itkImageToImageFilter.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,7 @@ ImageToImageFilter<TInputImage, TOutputImage>::VerifyInputInformation() ITKv5_CO
const SpacePrecisionType coordinateTol =
itk::Math::abs(this->m_CoordinateTolerance * inputPtr1->GetSpacing()[0]); // use first dimension spacing

if (!inputPtr1->GetOrigin().GetVnlVector().is_equal(inputPtrN->GetOrigin().GetVnlVector(), coordinateTol) ||
!inputPtr1->GetSpacing().GetVnlVector().is_equal(inputPtrN->GetSpacing().GetVnlVector(), coordinateTol) ||
!inputPtr1->GetDirection().GetVnlMatrix().as_ref().is_equal(inputPtrN->GetDirection().GetVnlMatrix().as_ref(),
this->m_DirectionTolerance))
if (!inputPtr1->IsCongruentImageGeometry(inputPtrN, m_CoordinateTolerance, m_DirectionTolerance))
{
std::ostringstream originString, spacingString, directionString;
if (!inputPtr1->GetOrigin().GetVnlVector().is_equal(inputPtrN->GetOrigin().GetVnlVector(), coordinateTol))
Expand Down

0 comments on commit a7c0f32

Please sign in to comment.