[Insight-users] Bug in PyramidFIlter?
sgerber
sgerber at cs.utah.edu
Mon Jul 15 13:58:29 EDT 2013
Below is a self contained example that demonstrates the undesired
behavior. Run the example and open the resulting images in Seg3D (or any
other image viewer that renders the image spacing units / origins
correctly and allows you to overlay the images), the edge in the image
downsampled by RecursiveMultiResolutionPyramidImageFilter is not
centered on the edge of the input image.
The culprit appears to be the ShrinkImageFilter. If the pyramid filter
is set UseShrinkImageFilterOff() the outputs match. Maybe that is the
intended behavior but for a multiresolution image pyramid I would claim
that this is typically not the desired output.
Kind regards
Sam
#include "itkImage.h"
#include "itkImageFileWriter.h"
#include "itkRescaleIntensityImageFilter.h"
#include "itkRecursiveMultiResolutionPyramidImageFilter.h"
#include "itkResampleImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
typedef itk::Image<double> ImageType;
ImageType::Pointer CreateImage(){
// Create a black image with 2 white regions
ImageType::Pointer image = ImageType::New();
ImageType::IndexType start;
start.Fill(0);
ImageType::SizeType size;
size.Fill(200);
ImageType::RegionType region(start,size);
image->SetRegions(region);
image->Allocate();
image->FillBuffer(0);
// Make a square
for(unsigned int r = 20; r < 80; r++)
{
for(unsigned int c = 30; c < 100; c++)
{
ImageType::IndexType pixelIndex;
pixelIndex[0] = r;
pixelIndex[1] = c;
image->SetPixel(pixelIndex, 255);
}
}
return image;
};
int main( int argc, char ** argv ){
ImageType::Pointer image = CreateImage();
{
typedef itk::ImageFileWriter<ImageType> FileWriterType;
FileWriterType::Pointer writer = FileWriterType::New();
writer->SetFileName("test-input.nrrd");
writer->SetInput( image );
writer->Update();
}
unsigned int numberOfLevels = 3;
{
typedef itk::RecursiveMultiResolutionPyramidImageFilter<
ImageType, ImageType>
RecursiveMultiResolutionPyramidImageFilterType;
RecursiveMultiResolutionPyramidImageFilterType::Pointer
pyramidFilter =
RecursiveMultiResolutionPyramidImageFilterType::New();
pyramidFilter->SetInput(image);
pyramidFilter->SetNumberOfLevels(numberOfLevels);
pyramidFilter->Update();
typedef itk::ImageFileWriter<ImageType> FileWriterType;
FileWriterType::Pointer writer = FileWriterType::New();
writer->SetFileName("test1.nrrd");
writer->SetInput( pyramidFilter->GetOutput() );
writer->Update();
}
{
ImageType::Pointer input = image;
for(int i = 1; i < numberOfLevels; i++){
typedef itk::DiscreteGaussianImageFilter<ImageType, ImageType>
Blur;
Blur::Pointer blur = Blur::New();
blur->SetUseImageSpacingOff();
blur->SetVariance(1);
blur->SetInput(input);
blur->Update();
input = blur->GetOutput();
// Resize
ImageType::SizeType inputSize =
input->GetLargestPossibleRegion().GetSize();
ImageType::SizeType outputSize;
outputSize[0] = inputSize[0] / 2;
outputSize[1] = inputSize[1] / 2;
ImageType::SpacingType inputSpacing = input->GetSpacing();
ImageType::SpacingType outputSpacing;
outputSpacing[0] = inputSpacing[0] *
(static_cast<double>(inputSize[0]) /
static_cast<double>(outputSize[0]));
outputSpacing[1] = inputSpacing[1] *
(static_cast<double>(inputSize[1]) /
static_cast<double>(outputSize[1]));
ImageType::PointType origin = input->GetOrigin();
origin[0] -= inputSpacing[0]/2 - outputSpacing[0]/2;
origin[1] -= inputSpacing[1]/2 - outputSpacing[1]/2;
typedef itk::IdentityTransform<double, 2> TransformType;
typedef itk::ResampleImageFilter<ImageType, ImageType>
ResampleImageFilterType;
ResampleImageFilterType::Pointer resample =
ResampleImageFilterType::New();
resample->SetInput(input);
resample->SetSize(outputSize);
resample->SetOutputOrigin(origin);
resample->SetOutputSpacing(outputSpacing);
resample->SetTransform(TransformType::New());
resample->UpdateLargestPossibleRegion();
resample->Update();
input = resample->GetOutput();
}
typedef itk::ImageFileWriter<ImageType> FileWriterType;
FileWriterType::Pointer writer = FileWriterType::New();
writer->SetFileName("test2.nrrd");
writer->SetInput( input );
writer->Update();
}
return EXIT_SUCCESS;
}
More information about the Insight-users
mailing list