How to upsample two coregistered images ?

Hello,

I have two images 1 PET and 1 MRI that are perfectly aligned (they are acquired simultaneously).

MRI shape is (512, 512, 1312)
PET shape is (192, 192, 566)

I would like to upsample the PET image so it matches the MRI shape without loosing the fact that they are perfectly aligned.

I’ve tried:

resample = sitk.ResampleImageFilter()
resample.SetInterpolator(sitk.sitkBSpline)
resample.SetOutputDirection(img_PET.GetDirection())
resample.SetOutputOrigin(img_PET.GetOrigin())
resample.SetSize(img_mri.GetSize())
return resample.Execute(img_PET)

But the results are misaligned.

Thank you very much for your help in advance !

1 Like

Hello @Hugo,

If they are spatially aligned, then this should do the trick:

resampled_PET = sitk.Resample(img_PET, img_mri, interpolator = sitk.sitkBSpline)

If you don’t mind using the default linear interpolator it becomes even more concise:

resampled_PET = sitk.Resample(img_PET, img_mri)

If you are manipulating size, you should also change spacing: resample.SetSpacing(img_mri.GetSpacing()).

Thank you two for your nice answers,

for some reason the resampled PET is a zero array.

new_image_pet = sitk.Resample(img_PET, img_mri, interpolator = sitk.sitkBSpline)
np.unique(sitk.GetArrayFromImage(new_image_pet))

returns:

np.array([0.])

Any idea where might be the problem ?
I verified input and both images in input of the resampler are fine.

Also,
sitk.ResampleImageFilter() does not have a SetSpacing attribute in my set up

Hello @Hugo,

Such a result indicates that the images are not spatially aligned (the resample function uses a default transformation of identity).

Also, in the current code snippet your MR image is new_img_mri and not img_mri are these the same or is this a bug?

Edit:
Hello @Hugo, you’re quick ;).
The attributes in the sitk.ResampleImageFilter() are prefaced with Output, so it has SetOutputSpacing, SetOutputSize

Hello,

Thanks for the edit, they are indeed the same thing and I corrected the name in the code snippet.

I’ve noticed that the origin does not match.

However visualisation in itk-snap show that they are perfectly aligned.
Maybe the problem have to do with the origin ?

Do you know a way I can test the alignement ?

Can you provide all the metadata (origin, direction, spacing, size) for images? Get them for example via print(img_mri) and print(img_PET).

Print(img_mri):
Image (0x7ffc84427580)
RTTI typeinfo: itk::Image<short, 3u>
Reference Count: 1
Modified Time: 879
Debug: Off
Object Name:
Observers:
none
Source: (none)
Source output name: (none)
Release Data: Off
Data Released: False
Global Release Data: Off
PipelineMTime: 856
UpdateMTime: 878
RealTimeStamp: 0 seconds
LargestPossibleRegion:
Dimension: 3
Index: [0, 0, 0]
Size: [512, 512, 632]
BufferedRegion:
Dimension: 3
Index: [0, 0, 0]
Size: [512, 512, 632]
RequestedRegion:
Dimension: 3
Index: [0, 0, 0]
Size: [512, 512, 632]
Spacing: [0.9375, 0.9375, 1.69531]
Origin: [-258.346, 286.329, -1053.44]
Direction:
1 0 0
0 -1 0
0 0 1

  IndexToPointMatrix: 
0.9375 0 0
0 -0.9375 0
0 0 1.69531

  PointToIndexMatrix: 
1.06667 0 0
0 -1.06667 0
0 0 0.589863

  Inverse Direction: 
1 0 0
0 -1 0
0 0 1

  PixelContainer: 
    ImportImageContainer (0x7ffc7dc745a0)
      RTTI typeinfo:   itk::ImportImageContainer<unsigned long, short>
      Reference Count: 1
      Modified Time: 875
      Debug: Off
      Object Name: 
      Observers: 
        none
      Pointer: 0x7ffc5dc00000
      Container manages memory: true
      Size: 165675008
      Capacity: 165675008

Print(img_PET):
Image (0x7ffc84431a10)
RTTI typeinfo: itk::Image<float, 3u>
Reference Count: 1
Modified Time: 1150
Debug: Off
Object Name:
Observers:
none
Source: (none)
Source output name: (none)
Release Data: Off
Data Released: False
Global Release Data: Off
PipelineMTime: 1127
UpdateMTime: 1149
RealTimeStamp: 0 seconds
LargestPossibleRegion:
Dimension: 3
Index: [0, 0, 0]
Size: [192, 192, 357]
BufferedRegion:
Dimension: 3
Index: [0, 0, 0]
Size: [192, 192, 357]
RequestedRegion:
Dimension: 3
Index: [0, 0, 0]
Size: [192, 192, 357]
Spacing: [3.125, 3.125, 2.78]
Origin: [-298.438, 298.438, -1011.47]
Direction:
1 0 0
0 -1 0
0 0 1

  IndexToPointMatrix: 
3.125 0 0
0 -3.125 0
0 0 2.78

  PointToIndexMatrix: 
0.32 0 0
0 -0.32 0
0 0 0.359712

  Inverse Direction: 
1 0 0
0 -1 0
0 0 1

  PixelContainer: 
    ImportImageContainer (0x7ffc84417de0)
      RTTI typeinfo:   itk::ImportImageContainer<unsigned long, float>
      Reference Count: 1
      Modified Time: 1146
      Debug: Off
      Object Name: 
      Observers: 
        none
      Pointer: 0x7ffa6dc00000
      Container manages memory: true
      Size: 13160448
      Capacity: 13160448

Does this look aligned to you ?

Thanks,
Hugo

img_mri:

Index: [0, 0, 0]
Size: [512, 512, 632]
Spacing: [0.9375, 0.9375, 1.69531]
Origin: [-258.346, 286.329, -1053.44]
Direction:
1 0 0
0 -1 0
0 0 1

img_PET:

Index: [0, 0, 0]
Size: [192, 192, 357]
Spacing: [3.125, 3.125, 2.78]
Origin: [-298.438, 298.438, -1011.47]
Direction:
1 0 0
0 -1 0
0 0 1

MRI image has larger extent along Z, and PET has larger extent along X and Y axes. So they don’t have the same origin. But they do mostly overlap.