Skip to content

Commit 896d48e

Browse files
committed
DOC: Indicate how to adjust resolution in ResampleAnImage
1 parent 66b8d2f commit 896d48e

File tree

2 files changed

+78
-44
lines changed

2 files changed

+78
-44
lines changed

src/Filtering/ImageGrid/ResampleAnImage/Code.cxx

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -43,49 +43,69 @@ main(int argc, char * argv[])
4343
using PixelType = unsigned char;
4444
using ImageType = itk::Image<PixelType, Dimension>;
4545
using ScalarType = double;
46+
using IndexValueType = typename itk::Index<Dimension>::IndexValueType;
4647

4748
using ReaderType = itk::ImageFileReader<ImageType>;
48-
ReaderType::Pointer reader = ReaderType::New();
49+
typename ReaderType::Pointer reader = ReaderType::New();
4950
reader->SetFileName(inputFileName);
5051
reader->Update();
5152

52-
ImageType::Pointer inputImage = reader->GetOutput();
53-
54-
ImageType::RegionType region = inputImage->GetLargestPossibleRegion();
55-
ImageType::SizeType size = region.GetSize();
56-
ImageType::SpacingType spacing = inputImage->GetSpacing();
57-
58-
itk::Index<Dimension> centralPixel;
59-
centralPixel[0] = size[0] / 2;
60-
centralPixel[1] = size[1] / 2;
61-
itk::Point<ScalarType, Dimension> centralPoint;
62-
centralPoint[0] = centralPixel[0];
63-
centralPoint[1] = centralPixel[1];
53+
const typename ImageType::Pointer inputImage = reader->GetOutput();
54+
const typename ImageType::RegionType inputRegion = inputImage->GetLargestPossibleRegion();
55+
const typename ImageType::SizeType inputSize = inputRegion.GetSize();
56+
const typename ImageType::SpacingType inputSpacing = inputImage->GetSpacing();
57+
const typename ImageType::PointType inputOrigin = inputImage->GetOrigin();
58+
59+
/*
60+
* We will scale the objects in the image by the factor `scale`; that is they
61+
* will be shrunk (scale < 1.0) or enlarged (scale > 1.0). However, the
62+
* number of pixels for each dimension of the output image will equal the
63+
* corresponding number of pixels in the input image, with padding (if
64+
* shrunk) or cropping (if enlarged) as necessary. Furthermore, the physical
65+
* distance between adjacent pixels will be the same in the input and the
66+
* output images. In contrast, if you want to change the resolution of the
67+
* image without changing the represented physical size of the objects in the
68+
* image, omit the transform and instead use:
69+
*
70+
* outputSize[d] = inputSize[d] * scale;
71+
* outputSpacing[d] = inputSpacing[d] / scale;
72+
* outputOrigin[d] = inputOrigin[d] + 0.5 * (outputSpacing[d] - inputSpacing[d]);
73+
*
74+
* in the loop over dimensions.
75+
*/
76+
77+
typename ImageType::SizeType outputSize = inputSize;
78+
typename ImageType::SpacingType outputSpacing = inputSpacing;
79+
typename ImageType::PointType outputOrigin = inputOrigin;
6480

6581
using ScaleTransformType = itk::ScaleTransform<ScalarType, Dimension>;
66-
ScaleTransformType::Pointer scaleTransform = ScaleTransformType::New();
67-
68-
ScaleTransformType::ParametersType parameters = scaleTransform->GetParameters();
69-
parameters[0] = scale;
70-
parameters[1] = scale;
82+
typename ScaleTransformType::Pointer scaleTransform = ScaleTransformType::New();
7183

72-
scaleTransform->SetParameters(parameters);
73-
scaleTransform->SetCenter(centralPoint);
84+
typename ScaleTransformType::ParametersType scaleTransformParameters = scaleTransform->GetParameters();
85+
itk::Point<ScalarType, Dimension> scaleTransformCenter;
86+
for (unsigned int d = 0; d < Dimension; ++d)
87+
{
88+
scaleTransformParameters[d] = scale;
89+
scaleTransformCenter[d] = static_cast<ScalarType>(static_cast<IndexValueType>(inputSize[d] / 2));
90+
}
91+
scaleTransform->SetParameters(scaleTransformParameters);
92+
scaleTransform->SetCenter(scaleTransformCenter);
7493

7594
using LinearInterpolatorType = itk::LinearInterpolateImageFunction<ImageType, ScalarType>;
76-
LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
95+
typename LinearInterpolatorType::Pointer interpolator = LinearInterpolatorType::New();
7796

7897
using ResampleFilterType = itk::ResampleImageFilter<ImageType, ImageType>;
79-
ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New();
98+
typename ResampleFilterType::Pointer resampleFilter = ResampleFilterType::New();
8099

81100
resampleFilter->SetInput(inputImage);
82101
resampleFilter->SetTransform(scaleTransform);
83102
resampleFilter->SetInterpolator(interpolator);
84-
resampleFilter->SetSize(size);
85-
resampleFilter->SetOutputSpacing(spacing);
103+
resampleFilter->SetSize(outputSize);
104+
resampleFilter->SetOutputSpacing(outputSpacing);
105+
resampleFilter->SetOutputOrigin(outputOrigin);
86106

87107
using WriterType = itk::ImageFileWriter<ImageType>;
88-
WriterType::Pointer writer = WriterType::New();
108+
typename WriterType::Pointer writer = WriterType::New();
89109
writer->SetFileName(outputFileName);
90110
writer->SetInput(resampleFilter->GetOutput());
91111

src/Filtering/ImageGrid/ResampleAnImage/Code.py

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,36 +21,50 @@
2121
print("Usage: " + sys.argv[0] + " <input_image> <output_image> <scale>")
2222
sys.exit(1)
2323

24-
input_image = sys.argv[1]
25-
output_image = sys.argv[2]
24+
input_file_name = sys.argv[1]
25+
output_file_name = sys.argv[2]
2626
scale = float(sys.argv[3])
2727

28-
input_image = itk.imread(input_image)
29-
30-
size = itk.size(input_image)
31-
spacing = itk.spacing(input_image)
32-
33-
central_pixel = [int(s / 2) for s in size]
34-
central_point = [float(p) for p in central_pixel]
35-
28+
input_image = itk.imread(input_file_name)
29+
input_size = itk.size(input_image)
30+
input_spacing = itk.spacing(input_image)
31+
input_origin = itk.origin(input_image)
3632
Dimension = input_image.GetImageDimension()
37-
scale_transform = itk.ScaleTransform[itk.D, Dimension].New()
3833

39-
parameters = scale_transform.GetParameters()
40-
for i in range(len(parameters)):
41-
parameters[i] = scale
34+
# We will scale the objects in the image by the factor `scale`; that is they
35+
# will be shrunk (scale < 1.0) or enlarged (scale > 1.0). However, the number
36+
# of pixels for each dimension of the output image will equal the corresponding
37+
# number of pixels in the input image, with cropping or padding as necessary.
38+
# Furthermore, the physical distance between adjacent pixels will be the same
39+
# in the input and the output images. In contrast, if you want to change the
40+
# resolution of the image without changing the represented physical size of the
41+
# objects in the image, omit the transform and instead supply:
42+
#
43+
# output_size = [int(input_size[d] * scale) for d in range(Dimension)]
44+
# output_spacing = [input_spacing[d] / scale for d in range(Dimension)]
45+
# output_origin = [input_origin[d] + 0.5 * (output_spacing[d] - input_spacing[d])
46+
# for d in range(Dimension)]
4247

43-
scale_transform.SetParameters(parameters)
44-
scale_transform.SetCenter(central_point)
48+
output_size = [input_size[d] for d in range(Dimension)]
49+
output_spacing = [input_spacing[d] for d in range(Dimension)]
50+
output_origin = [input_origin[d] for d in range(Dimension)]
51+
scale_transform = itk.ScaleTransform[itk.D, Dimension].New()
52+
scale_transform_parameters = scale_transform.GetParameters()
53+
for i in range(len(scale_transform_parameters)):
54+
scale_transform_parameters[i] = scale
55+
scale_transform_center = [float(int(s / 2)) for s in input_size]
56+
scale_transform.SetParameters(scale_transform_parameters)
57+
scale_transform.SetCenter(scale_transform_center)
4558

4659
interpolator = itk.LinearInterpolateImageFunction.New(input_image)
4760

4861
resampled = itk.resample_image_filter(
4962
input_image,
5063
transform=scale_transform,
5164
interpolator=interpolator,
52-
size=[size[d] for d in range(Dimension)],
53-
output_spacing=spacing,
65+
size=output_size,
66+
output_spacing=output_spacing,
67+
output_origin=output_origin,
5468
)
5569

56-
itk.imwrite(resampled, output_image)
70+
itk.imwrite(resampled, output_file_name)

0 commit comments

Comments
 (0)