Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

resizing results consistency with skimage.transform.resize? #14

Open
thuzjf opened this issue Sep 20, 2023 · 2 comments
Open

resizing results consistency with skimage.transform.resize? #14

thuzjf opened this issue Sep 20, 2023 · 2 comments

Comments

@thuzjf
Copy link

thuzjf commented Sep 20, 2023

Thanks for you to open source this amazing project. Recently I was searching for some pytorch-based resampling methods that support bspline interpolation to replace the skimage.transform.resize in my project for speed concerns, and fortunately I found this. I tested both methods(skimage resize and interpol.resize) on a 3D medical data and found that the results are consistent when order(interpolation) is 1 and 2, but not consistent when order is 3, 4 or 5, through the difference is very small. Is this expected?(I also tested SimpleITK's ResampleFilter, and the results are slightly different except for order 1) Are there some default params which I can utilize to make the results exactly the same? Thank you!

here is a tiny test case

shape=[16,512,512]
new_shape=[32,320,320]

a = np.random.rand(*shape)
at = torch.from_numpy(a).unsqueeze(0).unsqueeze(0)

b1=resize(a, new_shape, order=3, mode='edge', anti_aliasing=False)
b2=interpol.resize(at, shape=new_shape, anchor='edges', interpolation=3)
b2=b2.squeeze().numpy()

print(np.abs(b2-b1).sum())
@balbasty
Copy link
Owner

Hello,

I haven't done in depth comparisons, but I've quickly looked at skimage's code and:

  • skimage's uses scipy.zoom with grid_mode=True, which corresponds to interpol's anchor='edges' (you did this correctly)
  • skimage's mode corresponds to interpol's bound, and mode='edge' should be translated to bound='nearest'

Essentially the mapping between boundary modes goes like this

interpol scipy.zoom numpy.pad
'replicate' or 'nearest' 'nearest' 'edge'
'dct1' or 'mirror' 'mirror' 'reflect'
'dct2' or 'reflect' 'reflect' 'symmetric'
'dst1' or 'antimirror' n/a n/a
'dst2' or 'antireflect' n/a n/a
'dft' or 'wrap' 'wrap' 'wrap'
'zero' or 'zeros' 'constant' 'constant'

with skimage following the np.pad convention.

What happens if you add bound='nearest' to your example?

@thuzjf
Copy link
Author

thuzjf commented Sep 21, 2023

Thank you for the quick response. I added bound='nearest' to my code and get the same results. I think the difference may not come from edge paddings, here is my testing code on 2D example for order=3, and we can see that the difference can appear in the central area:

import matplotlib.pyplot as plt
import numpy as np
import torch
import interpol
from skimage.transform import resize

shape=[512, 512]
new_shape=[320,320]
a = np.random.rand(*shape)
at = torch.from_numpy(a).unsqueeze(0).unsqueeze(0)

b1=resize(a, new_shape, order=3, mode='edge', anti_aliasing=False)
b2=interpol.resize(at, shape=new_shape, anchor='edges', interpolation=3, bound='nearest')
b2=b2.squeeze().numpy()
diff = np.abs(b2-b1)
print(diff.sum())

plt.matshow(diff)
plt.colorbar()

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants