yujuezhao
yujuezhao

Reputation: 1105

Can I use numpy operation on SimpleITK.Image without converting using GetArrayFromImage

I can do so in SimpleITK,

img = sitk.ReadImage(file_path)
array = sitk.GetArrayFromImage(img)
array[array > 10] = 10
array[array < 0] = 0

Or I can do it like,

img = sitk.ReadImage(file_path)
binthresh = sitk.BinaryThresholdFilter()
... # set up params for binthresh
img = binthresh.Execute(img)

But the thing is, I want to take advantage of the fast speed of SimpleITK.ResampleImageFilter`, therefore I have to use it like,

img = sitk.ReadImage(file_path)
binthresh = sitk.BinaryThresholdFilter()
... # set up params for binthresh
img = binthresh.Execute(img)
resample = sitk.ResampleImageFilter()
... # set up params for resample
img = resample.Execute(img)

In fact, I hope there is a way like this,

img = sitk.ReadImage(file_path)
array_view = sitk.GetArrayViewFromImage(img)
array_view[array_view > 10] = 10
array_view[array_view < 0] = 0
resample = sitk.ResampleImageFilter()
... # set up params for resample
img = resample.Execute(img)

The code block above seems much compact, but the array_view from GetArrayViewFromImage is read-only. Therefore, is there a way to do the equivalent?

Upvotes: 0

Views: 5480

Answers (1)

blowekamp
blowekamp

Reputation: 1431

With SimpleITK's current implementations of GetArrayViewFromImage, it is safest to prevent alias (shallow copies) so that potential invalid memory access is avoided. Therefore, no writable access methods are implemented. However, the current development is working on developing a safe reference counted access method that will enable writing.

However, there is an equivalent image filter in SimpleITK to do the same operation the ClampImageFilter. It is faster as well:


In [1]: import numpy as np                                                                                                                                      

In [2]: import SimpleITK as sitk                                                                                                                                

In [3]: a = np.random.rand(512,512,128)*100-50                                                                                                                  

In [4]: img = sitk.GetImageFromArray(a)                                                                                                                         

In [5]: %timeit -n 10 sitk.Clamp(img, lowerBound=0, upperBound=10)                                                                                              
41.5 ms ± 1.11 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [6]: def f(a, copy=False): 
   ...:     out = a 
   ...:     if copy: 
   ...:         out = np.copy(a) 
   ...:     out[out>10] = 10 
   ...:     out[out<0] = 0 
   ...:     return out 
   ...:                                                                                                                                                         

In [7]: %timeit -n 10 f(a, copy=False)                                                                                                                          
49.7 ms ± 11.7 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [8]: %timeit -n 10 f(a, copy=True)                                                                                                                           
84.8 ms ± 228 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

Upvotes: 3

Related Questions