torch-interpol
torch-interpol copied to clipboard
resizing results consistency with skimage.transform.resize?
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())
Hello,
I haven't done in depth comparisons, but I've quickly looked at skimage's code and:
- skimage's uses
scipy.zoom
withgrid_mode=True
, which corresponds to interpol'sanchor='edges'
(you did this correctly) - skimage's
mode
corresponds to interpol'sbound
, andmode='edge'
should be translated tobound='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?
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()