[Insight-developers] updating tests to deal with pixel-centered coordinates
Michel Audette
michel.audette at kitware.com
Fri May 29 17:14:42 EDT 2009
Dear gents,
I've updated, but have not committed itkWarpImageFilterTest.cxx to account
for new behaviour related to pixel-centered coordinates.
There were two types of mismatch that were causing failures, related to a
comparison between the pixel value returned by the output Iterator outIter
(spanning a larger image than the input iterator), and the value returned by
. These tests have a pattern, evaluated with an analytical function
Evaluate() part of an ImagePattern helper class, that is first evaluated at
inputIndex, prior to some expansion characterized by a variable factors[].
This expansion also involves padding the outer edge with some padValue (=4
in this case), if (m_Interpolator->IsInsideBuffer( point ) ) returns false
in itkWarpImageFilter.txx, in testing the output Image. If inside, the pixel
is assigned a value m_Interpolator->Evaluate( point ), which is an
interpolation as usual for "fully inside" pixels, but works out to
nearest-neighbour for the half-pixel outer band that now can now occur.
For example, a 64x64 image scales by (2,3) to a 128x192 image, where
(0-63,0-63) map to (0-127,0-191). Here, (127,y) coincides with (63.5,y/3),
so m_Interpolator->IsInsideBuffer( point ) correctly returns false: it is
outside the tolerated outer half-pixel band. (x,191) coincides with (x/2,
63.67) is also out. These 2 types of points get a padValue asssigned to
them.
(x,190) is seen as inside by this test, but is beyond (x,189) that maps to
(x/2,63) in the input image: it is in the outer half-band. It should get the
same intensity value as (x,189).
The first type of mismatch was due to inconsistencies between the IsInside()
used in itkWarpImageFilterTest.cxx, and (m_Interpolator->IsInsideBuffer(
point ) ) in itkWarpImageFilter.txx: the two methods could not agree on a
point being inside the image. The logic had to be consistent in assigning a
padValue to a pixel, which involves tweaking the validSize logic, as well as
passing the validSize parameter to pattern.Evaluate(). The 2nd type of
mismatch involves a point that is on that half-pixel band, which involves
determining a clampSize parameter, outside of which the intensity value is
clamped at that value, and passing that parameter to pattern.Evaluate as
well.
Unless this is done (i.e.: Evaluate() modified to handle these areas
explicitly), I don't see a way of reconciling the differences between 2 sets
of regression values, given the inconsistencies in inside-ness, as well as
the nearest-neighbour behaviour of the interpolator in the outer half-pixel
band. See code snippet below.
{
validSize[j] = size[j] * factors[j];
//Consider as inside anything < 1/2 pixel of (size[j]-1)*factors[j]
//(0-63) map to (0,126), with 127 exactly at 1/2 pixel, therefore
//edged out; or to (0,190), with 190 just beyond 189 by 1/3 pixel;
//or to (0,253), with 254 exactly at 1/2 pixel, therefore out
//also; or (0, 317), with 317 at 2/5 pixel beyond 315. And so on.
decrementForScaling[j] = factors[j] / 2 ;
validSize[j] -= decrementForScaling[j];
//This part of logic determines what is inside, but in outer
//1/2 pixel band, which has to be clamped to that nearest outer
//pixel scaled by factor: (0,63) maps to (0,190) as inside, but
//pixel 190 is outside of (0,189), and must be clamped to it.
//If factor is 2 or less, this decrement has no effect.
clampSizeDecrement[j] = (factors[j] - 1 - decrementForScaling[j]) ;
if (clampSizeDecrement[j] < 0)
{
clampSizeDecrement[j] = 0;
}
clampSize[j]= validSize[j] - clampSizeDecrement[j];
}
double Evaluate( const IndexType& index , const SizeType& size,
const SizeType& clampSize, const PixelType& padValue)
{
double accum = offset;
for( int j = 0; j < VDimension; j++ )
{
#ifdef ITK_USE_CENTERED_PIXEL_COORDINATES_CONSISTENTLY
if ( index[j] < size[j] )
{
if ( index[j] >= clampSize[j] )
{
//Interpolators behave this way in half-pixel band at image
perimeter
accum += coeff[j] * (double) (clampSize[j]-1);
}
else
{
accum += coeff[j] * (double) index[j];
}
}
else
{
accum = padValue;
break;
}
#else
accum += coeff[j] * (double) index[j];
#endif
}
return accum;
}
This fix was tested with itkWarpImageFilterTest with factors {2,3}, {2,4}
and {2,5}, all successfully. If no one objects, I'll check this test, as
well as fix the other tests in that spirit.
Cheers,
Michel
--
Michel Audette, Ph.D.
R & D Engineer,
Kitware Inc.,
Chapel Hill, N.C.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.itk.org/mailman/private/insight-developers/attachments/20090529/10cc477b/attachment.htm>
More information about the Insight-developers
mailing list