Skip to content

Commit ceb157d

Browse files
N-Dekkerthewtex
authored andcommitted
BUG: Fix issue #1950, ImageMaskSpatialObject access outside image buffer
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.
1 parent 99c5706 commit ceb157d

2 files changed

Lines changed: 22 additions & 13 deletions

File tree

Modules/Core/SpatialObjects/include/itkImageMaskSpatialObject.hxx

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,12 @@ template <unsigned int TDimension, typename TPixel>
4040
bool
4141
ImageMaskSpatialObject<TDimension, TPixel>::IsInsideInObjectSpace(const PointType & point) const
4242
{
43-
typename Superclass::InterpolatorType::ContinuousIndexType index;
44-
if (this->GetImage()->TransformPhysicalPointToContinuousIndex(point, index))
45-
{
46-
using InterpolatorOutputType = typename InterpolatorType::OutputType;
47-
bool insideMask = (Math::NotExactlyEquals(DefaultConvertPixelTraits<InterpolatorOutputType>::GetScalarValue(
48-
this->GetInterpolator()->EvaluateAtContinuousIndex(index)),
49-
NumericTraits<PixelType>::ZeroValue()));
50-
if (insideMask)
51-
{
52-
return true;
53-
}
54-
}
43+
const ImageType * const image = this->GetImage();
44+
45+
const IndexType index = image->TransformPhysicalPointToIndex(point);
5546

56-
return false;
47+
return image->GetBufferedRegion().IsInside(index) &&
48+
Math::NotExactlyEquals(image->GetPixel(index), NumericTraits<PixelType>::ZeroValue());
5749
}
5850

5951

Modules/Core/SpatialObjects/test/itkImageMaskSpatialObjectGTest.cxx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,20 @@ TEST(ImageMaskSpatialObject, IsInsideIndependentOfDistantPixels)
306306

307307

308308
#endif
309+
310+
311+
// Tests that IsInsideInObjectSpace returns false for a corner point, when the
312+
// mask image is filled with zero values. This test would sometimes fail on
313+
// ITK v5.0.1 and v5.1.0
314+
TEST(ImageMaskSpatialObject, CornerPointIsNotInsideMaskOfZeroValues)
315+
{
316+
// Create a mask image, and fill the image with zero vales.
317+
const auto image = itk::Image<unsigned char>::New();
318+
image->SetRegions(itk::Size<>{ { 2, 2 } });
319+
image->Allocate(true);
320+
321+
const auto imageMaskSpatialObject = itk::ImageMaskSpatialObject<2>::New();
322+
imageMaskSpatialObject->SetImage(image);
323+
const double cornerPoint[] = { 1.5, 1.5 };
324+
ASSERT_FALSE(imageMaskSpatialObject->IsInsideInObjectSpace(cornerPoint));
325+
}

0 commit comments

Comments
 (0)