Skip to content

Commit

Permalink
BUG: Fix issue #1950, ImageMaskSpatialObject access outside image buffer
Browse files Browse the repository at this point in the history
Fixed issue #1950, "ImageMaskSpatialObject tries to access pixels
outside the image buffer (segfault)".

In the original code, `TransformPhysicalPointToContinuousIndex` did
estimate whether the specified point was inside the image buffer, but
then `GetInterpolator()->EvaluateAtContinuousIndex(index)` did in some
cases still try to access a pixel outside the image buffer.

This fix avoids using an interpolator. It only accesses a pixel when its
index is inside the buffered region.

The use of an interpolator appears less relevant for an image mask than
for other spatial objects, as for each mask pixel value, it is usually
only interesting to know whether it is zero or non-zero.

Added ImageMaskSpatialObject.CornerPointIsNotInsideMaskOfZeroValues unit
test.
  • Loading branch information
N-Dekker authored and thewtex committed Aug 10, 2020
1 parent 99c5706 commit ceb157d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 13 deletions.
18 changes: 5 additions & 13 deletions Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,12 @@ template <unsigned int TDimension, typename TPixel>
bool
ImageMaskSpatialObject<TDimension, TPixel>::IsInsideInObjectSpace(const PointType & point) const
{
typename Superclass::InterpolatorType::ContinuousIndexType index;
if (this->GetImage()->TransformPhysicalPointToContinuousIndex(point, index))
{
using InterpolatorOutputType = typename InterpolatorType::OutputType;
bool insideMask = (Math::NotExactlyEquals(DefaultConvertPixelTraits<InterpolatorOutputType>::GetScalarValue(
this->GetInterpolator()->EvaluateAtContinuousIndex(index)),
NumericTraits<PixelType>::ZeroValue()));
if (insideMask)
{
return true;
}
}
const ImageType * const image = this->GetImage();

const IndexType index = image->TransformPhysicalPointToIndex(point);

return false;
return image->GetBufferedRegion().IsInside(index) &&
Math::NotExactlyEquals(image->GetPixel(index), NumericTraits<PixelType>::ZeroValue());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,20 @@ TEST(ImageMaskSpatialObject, IsInsideIndependentOfDistantPixels)


#endif


// Tests that IsInsideInObjectSpace returns false for a corner point, when the
// mask image is filled with zero values. This test would sometimes fail on
// ITK v5.0.1 and v5.1.0
TEST(ImageMaskSpatialObject, CornerPointIsNotInsideMaskOfZeroValues)
{
// Create a mask image, and fill the image with zero vales.
const auto image = itk::Image<unsigned char>::New();
image->SetRegions(itk::Size<>{ { 2, 2 } });
image->Allocate(true);

const auto imageMaskSpatialObject = itk::ImageMaskSpatialObject<2>::New();
imageMaskSpatialObject->SetImage(image);
const double cornerPoint[] = { 1.5, 1.5 };
ASSERT_FALSE(imageMaskSpatialObject->IsInsideInObjectSpace(cornerPoint));
}

0 comments on commit ceb157d

Please sign in to comment.