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

Python readimage improvement series imageio #258

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Wrapping/Generators/Python/Tests/CMakeLists.txt
Expand Up @@ -50,7 +50,7 @@ if(ITK_WRAP_unsigned_char AND WRAP_2)
if(_have_numpy_return_code EQUAL 0)
itk_python_add_test(NAME PythonExtrasTest
COMMAND extras.py
DATA{${WrapITK_SOURCE_DIR}/images/cthead1.png} ${ITK_TEST_OUTPUT_DIR}/out.png
DATA{${WrapITK_SOURCE_DIR}/images/cthead1.png} ${ITK_TEST_OUTPUT_DIR}/out.png ${ITK_TEST_OUTPUT_DIR}
)
endif()
endif()
Expand Down
50 changes: 50 additions & 0 deletions Wrapping/Generators/Python/Tests/extras.py
Expand Up @@ -31,6 +31,7 @@ def custom_callback(name, progress):

import itk
import sys
import os

# test the force load function
itk.force_load()
Expand Down Expand Up @@ -154,6 +155,55 @@ def custom_callback(name, progress):
assert down_casted == reader
assert down_casted.__class__ == ReaderType

# test setting the IO manually
png_io = itk.PNGImageIO.New()
assert png_io.GetFileName() == ''
reader=itk.ImageFileReader.New(FileName=fileName, ImageIO=png_io)
fbudin69500 marked this conversation as resolved.
Show resolved Hide resolved
reader.Update()
assert png_io.GetFileName() == fileName

# test reading image series
series_reader = itk.ImageSeriesReader.New(FileNames=[fileName,fileName])
series_reader.Update()
assert series_reader.GetOutput().GetImageDimension() == 3
assert series_reader.GetOutput().GetLargestPossibleRegion().GetSize()[2] == 2

# test reading image series and check that dimension is not increased if
# last dimension is 1.
image_series = itk.Image[itk.UC, 3].New()
image_series.SetRegions([10, 7, 1])
image_series.Allocate()
image_series.FillBuffer(0)
image_series3d_filename = os.path.join(
sys.argv[3], "image_series_extras_py.mha")
itk.imwrite(image_series, image_series3d_filename)
series_reader = itk.ImageSeriesReader.New(
FileNames=[image_series3d_filename, image_series3d_filename])
series_reader.Update()
assert series_reader.GetOutput().GetImageDimension() == 3

# test reading image series with itk.imread()
image_series = itk.imread([fileName, fileName])
assert image_series.GetImageDimension() == 3

# Numeric series filename generation without any integer index. It is
# only to produce an ITK object that users could set as an input to
# `itk.ImageSeriesReader.New()` or `itk.imread()` and test that it works.
numeric_series_filename = itk.NumericSeriesFileNames.New()
numeric_series_filename.SetStartIndex(0)
numeric_series_filename.SetEndIndex(3)
numeric_series_filename.SetIncrementIndex(1)
numeric_series_filename.SetSeriesFormat(fileName)
image_series = itk.imread(numeric_series_filename.GetFileNames())
fbudin69500 marked this conversation as resolved.
Show resolved Hide resolved
number_of_files = len(numeric_series_filename.GetFileNames())
assert image_series.GetImageDimension() == 3
assert image_series.GetLargestPossibleRegion().GetSize()[2] == number_of_files

# test reading image series with `itk.imread()` and check that dimension is
# not increased if last dimension is 1.
image_series = itk.imread([image_series3d_filename, image_series3d_filename])
assert image_series.GetImageDimension() == 3

# pipeline, auto_pipeline and templated class are tested in other files

# BridgeNumPy
Expand Down
28 changes: 22 additions & 6 deletions Wrapping/Generators/Python/itkExtras.py
Expand Up @@ -454,22 +454,38 @@ def imwrite(image_or_filter, filename, compression=False):
writer.Update()

def imread(filename, pixel_type=None):
"""Read an image from a file and return an itk.Image.
"""Read an image from a file or series of files and return an itk.Image.

The reader is instantiated with the image type of the image file.
The reader is instantiated with the image type of the image file if
`pixel_type` is not provided (default). The dimension of the image is
automatically found. If the given filename is a list or a tuple, the
reader will use an itk.ImageSeriesReader object to read the files.
"""
import itk
if type(filename) in [list, tuple]:
TemplateReaderType=itk.ImageSeriesReader
io_filename=filename[0]
increase_dimension=True
kwargs={'FileNames':filename}
else:
TemplateReaderType=itk.ImageFileReader
io_filename=filename
increase_dimension=False
kwargs={'FileName':filename}
if pixel_type:
imageIO = itk.ImageIOFactory.CreateImageIO(filename, itk.ImageIOFactory.ReadMode)
imageIO = itk.ImageIOFactory.CreateImageIO(io_filename, itk.ImageIOFactory.ReadMode)
if not imageIO:
raise RuntimeError("No ImageIO is registered to handle the given file.")
imageIO.SetFileName( filename )
imageIO.SetFileName(io_filename)
imageIO.ReadImageInformation()
dimension = imageIO.GetNumberOfDimensions()
# Increase dimension if last dimension is not of size one.
if increase_dimension and imageIO.GetDimensions(dimension-1) != 1:
dimension += 1
ImageType=itk.Image[pixel_type,dimension]
reader = itk.ImageFileReader[ImageType].New(FileName=filename)
reader = TemplateReaderType[ImageType].New(**kwargs)
else:
reader = itk.ImageFileReader.New(FileName=filename)
reader = TemplateReaderType.New(**kwargs)
reader.Update()
return reader.GetOutput()

Expand Down
33 changes: 22 additions & 11 deletions Wrapping/Generators/Python/itkTemplate.py
Expand Up @@ -391,7 +391,11 @@ def New(self, *args, **kwargs):
keys = self.keys()
cur = itk.auto_pipeline.current
if self.__name__ == "itk::ImageFileReader":
return self._NewImageFileReader(*args, **kwargs)
return self._NewImageReader(itk.ImageFileReader, False, 'FileName', *args, **kwargs)
elif self.__name__ == "itk::ImageSeriesReader":
# Only support `FileNames`, not `FileName`, to simplify the logic and avoid having
# to deal with checking if both keyword arguments are given.
return self._NewImageReader(itk.ImageSeriesReader, True, 'FileNames', *args, **kwargs)
primary_input_methods = ('Input', 'InputImage', 'Input1')
if len(args) != 0:
# try to find a type suitable for the primary input provided
Expand All @@ -412,21 +416,25 @@ def New(self, *args, **kwargs):
raise RuntimeError("No suitable template parameter can be found.")
return self[list(keys)[0]].New(*args, **kwargs)

def _NewImageFileReader(self, *args, **kwargs):
primaryInputMethods = ('FileName',)
def _NewImageReader(self, TemplateReaderType, increase_dimension, primaryInputMethod, *args, **kwargs):
def firstIfList(arg):
if type(arg) in [list, tuple]:
return arg[0]
else:
return arg
inputFileName = ''
if len(args) != 0:
# try to find a type suitable for the primary input provided
inputFileName = args[0]
elif set(primaryInputMethods).intersection(kwargs.keys()):
for method in primaryInputMethods:
if method in kwargs:
inputFileName = kwargs[method]
break
inputFileName = firstIfList(args[0])
elif primaryInputMethod in kwargs:
inputFileName = firstIfList(kwargs[primaryInputMethod])
if not inputFileName:
raise RuntimeError("No FileName specified.")
import itk
imageIO = itk.ImageIOFactory.CreateImageIO( inputFileName, itk.ImageIOFactory.ReadMode )
if "ImageIO" in kwargs:
imageIO = kwargs["ImageIO"]
else:
imageIO = itk.ImageIOFactory.CreateImageIO( inputFileName, itk.ImageIOFactory.ReadMode )
fbudin69500 marked this conversation as resolved.
Show resolved Hide resolved
if not imageIO:
raise RuntimeError("No ImageIO is registered to handle the given file.")
componentTypeDic= {"float": itk.F, "double": itk.D,
Expand All @@ -437,13 +445,16 @@ def _NewImageFileReader(self, *args, **kwargs):
imageIO.SetFileName( inputFileName )
imageIO.ReadImageInformation()
dimension = imageIO.GetNumberOfDimensions()
# For image series, increase dimension if last dimension is not of size one.
if increase_dimension and imageIO.GetDimensions(dimension-1) != 1:
dimension += 1
componentAsString = imageIO.GetComponentTypeAsString(imageIO.GetComponentType())
component = componentTypeDic[componentAsString]
pixel = imageIO.GetPixelTypeAsString(imageIO.GetPixelType())
numberOfComponents = imageIO.GetNumberOfComponents()
PixelType = itkTemplate._pixelTypeFromIO(pixel, component, numberOfComponents)
ImageType = itk.Image[PixelType, dimension]
ReaderType = itk.ImageFileReader[ImageType]
ReaderType = TemplateReaderType[ImageType]
return ReaderType.New(*args, **kwargs)

@staticmethod
Expand Down