diff --git a/Modules/Bridge/NumPy/wrapping/PyBuffer.i.in b/Modules/Bridge/NumPy/wrapping/PyBuffer.i.in index 5629b2d848d..df545398f8a 100644 --- a/Modules/Bridge/NumPy/wrapping/PyBuffer.i.in +++ b/Modules/Bridge/NumPy/wrapping/PyBuffer.i.in @@ -9,6 +9,10 @@ i.e. k,j,i versus i,j,k. However C-order indexing is expected by most algorithms in NumPy / SciPy. """ + + if image.GetBufferPointer() is None: + return None + if update: # Ensure the image regions and image pixel buffer have been updated # correctly @@ -46,6 +50,8 @@ This is a deep copy of the image buffer and is completely safe and without potential side effects. """ + if image.GetBufferPointer() is None: + return None arrayView = itkPyBuffer@PyBufferTypes@.GetArrayViewFromImage(image, keep_axes, update) diff --git a/Modules/Bridge/NumPy/wrapping/test/itkPyBufferTest.py b/Modules/Bridge/NumPy/wrapping/test/itkPyBufferTest.py index e19113b1ff7..6e41bf48413 100644 --- a/Modules/Bridge/NumPy/wrapping/test/itkPyBufferTest.py +++ b/Modules/Bridge/NumPy/wrapping/test/itkPyBufferTest.py @@ -70,6 +70,38 @@ def test_NDArrayITKBase_pickle(self): equal = (recon_obj == ndarray_itk_base).all() assert equal, "Different results before and after pickle" + def test_EmptyImage_pickle(self): + """ + Test the serialization of an empty itk.Image + """ + Dimension = 3 + ImageType = itk.Image[itk.UC, Dimension] + RegionType = itk.ImageRegion[Dimension] + + region = RegionType() + region.SetSize(0, 6) + region.SetSize(1, 6) + region.SetSize(2, 6) + + image = ImageType.New() + image.SetRegions(region) + spacing = [3.0, 4.0, 5.0] + image.SetSpacing(spacing) + # Before allocation + # scalarImage.Allocate(True) + + import pickle + pickled = pickle.dumps(image) + reloaded = pickle.loads(pickled) + reloaded_spacing = reloaded.GetSpacing() + spacing = reloaded.GetSpacing() + assert spacing[0] == reloaded_spacing[0] + assert spacing[1] == reloaded_spacing[1] + assert spacing[2] == reloaded_spacing[2] + + ndarray_itk_base = itk.array_view_from_image(image) + assert ndarray_itk_base == None + def test_NumPyBridge_itkScalarImage(self): "Try to convert all pixel types to NumPy array view" diff --git a/Wrapping/Generators/Python/itk/support/extras.py b/Wrapping/Generators/Python/itk/support/extras.py index d5aacfe07e1..fae908161db 100644 --- a/Wrapping/Generators/Python/itk/support/extras.py +++ b/Wrapping/Generators/Python/itk/support/extras.py @@ -805,12 +805,17 @@ def image_from_dict(image_dict: Dict) -> "itkt.Image": import itk ImageType = image_type_from_wasm_type(image_dict["imageType"]) - image = itk.PyBuffer[ImageType].GetImageViewFromArray(image_dict["data"]) + if image_dict["data"] is None: + image = ImageType.New() + image.SetRegions(image_dict["size"]) + image.Allocate(True) + else: + image = itk.PyBuffer[ImageType].GetImageViewFromArray(image_dict["data"]) + image.SetRegions(image_dict["size"]) image.SetOrigin(image_dict["origin"]) image.SetSpacing(image_dict["spacing"]) image.SetDirection(image_dict["direction"]) image.SetObjectName(image_dict["name"]) - image.SetRegions(image_dict["size"]) return image