Reputation: 2343
If I want to multiply a 3D volume plane by plane with a 2D slice in numpy
I can use broadcasting:
import numpy as np
vol = np.random.rand(10, 20, 30)
slc = np.random.rand(10, 30)
new_vol = vol * slc[:, None]
If I try something similar in SimpleITK
I get an error
import SimpleITK as sitk
vol_img = sitk.GetImageFromArray(vol)
slc_img = sitk.GetImageFromArray(slc[:, None])
new_vol_img = vol_img * slc_img
---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-1-7d2c0160b591> in <module>
9 vol_img = sitk.GetImageFromArray(vol)
10 slc_img = sitk.GetImageFromArray(slc[:, None])
---> 11 new_vol_img = vol_img * slc_img
~\AppData\Local\Continuum\anaconda3\lib\site-packages\SimpleITK\SimpleITK.py in __mul__(self, other)
4273 def __mul__( self, other ):
4274 if isinstance( other, Image ):
-> 4275 return Multiply( self, other )
4276 try:
4277 return Multiply( self, float(other) )
~\AppData\Local\Continuum\anaconda3\lib\site-packages\SimpleITK\SimpleITK.py in Multiply(*args)
50874
50875 """
> 50876 return _SimpleITK.Multiply(*args)
50877 class N4BiasFieldCorrectionImageFilter(ImageFilter_0):
50878 """
RuntimeError: Exception thrown in SimpleITK Multiply: C:\b\3.6-64\ITK\Modules\Core\Common\src\itkDataObject.cxx:393:
Requested region is (at least partially) outside the largest possible region.
Upvotes: 0
Views: 372
Reputation: 541
This cannot be done directly in SimpleITK because the concept of an image is not equivalent to an array of intensities, it has a physical spatial extent (see this read-the-docs explanation). The spacing, origin and direction of two multiplied images must be the same.
To do what you want you will need to iterate over the slices and then recompose back into a volume.
Here is sample code that does just that:
import SimpleITK as sitk
img = sitk.ReadImage('training_001_ct.mha')
slc = sitk.GridSource(outputPixelType=img.GetPixelID(), size=img.GetSize()[0:2],
sigma=(0.1,0.1), gridSpacing=(20.0,20.0))
slc.SetSpacing(img.GetSpacing()[0:2])
modified_slices = []
for i in range(img.GetDepth()):
current_img_slc = img[:,:,i]
slc.SetOrigin(current_img_slc.GetOrigin())
slc.SetDirection(current_img_slc.GetDirection())
modified_slices.append(current_img_slc*slc)
sitk.Show(sitk.JoinSeries(modified_slices))
Please post future questions on the ITK discourse forum, and use the simpleitk tag.
Upvotes: 2