Skip to content

Commit

Permalink
ENH: Make Python Image.astype() work for more types
Browse files Browse the repository at this point in the history
  • Loading branch information
Leengit committed Nov 18, 2020
1 parent c0ae3ef commit 8f2a6c9
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 9 deletions.
8 changes: 8 additions & 0 deletions Modules/Bridge/VTK/include/itkVTKImageExport.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ VTKImageExport<TInputImage>::VTKImageExport()
{
m_ScalarTypeName = "unsigned long";
}
else if (typeid(ScalarType) == typeid(long long))
{
m_ScalarTypeName = "long long";
}
else if (typeid(ScalarType) == typeid(unsigned long long))
{
m_ScalarTypeName = "unsigned long long";
}
else if (typeid(ScalarType) == typeid(int))
{
m_ScalarTypeName = "int";
Expand Down
14 changes: 11 additions & 3 deletions Modules/Filtering/ImageFilterBase/wrapping/itkCastImageFilter.wrap
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,28 @@ itk_wrap_class("itk::CastImageFilter" POINTER_WITH_SUPERCLASS)
foreach(image_dim ${ITK_WRAP_IMAGE_DIMS})
if(ITK_WRAP_vector_float AND ITK_WRAP_vector_double)
if(ITKM_VIF${image_dim} AND ITKM_VID${image_dim} AND ITKT_VIF${image_dim} AND ITKT_VID${image_dim})
# VectorImage(float) <-> VectorImage(double)
# VectorImage(double, float) <-> VectorImage(double, float)
itk_wrap_template("${ITKM_VID${image_dim}}${ITKM_VID${image_dim}}" "${ITKT_VID${image_dim}},${ITKT_VID${image_dim}}")
itk_wrap_template("${ITKM_VIF${image_dim}}${ITKM_VID${image_dim}}" "${ITKT_VIF${image_dim}},${ITKT_VID${image_dim}}")
itk_wrap_template("${ITKM_VID${image_dim}}${ITKM_VIF${image_dim}}" "${ITKT_VID${image_dim}},${ITKT_VIF${image_dim}}")
itk_wrap_template("${ITKM_VIF${image_dim}}${ITKM_VIF${image_dim}}" "${ITKT_VIF${image_dim}},${ITKT_VIF${image_dim}}")
endif()
foreach(pixel_type "${WRAP_ITK_RGB};${WRAP_ITK_RGBA}")
if(ITKM_VIF${image_dim} AND ITKM_I${ITKM_${pixel_type}}${image_dim} AND ITKT_VIF${image_dim} AND ITKT_I${ITKM_${pixel_type}}${image_dim})
# VectorImage(float) <-> (RGBPixel, RGBAPixel)
itk_wrap_template("${ITKM_VIF${image_dim}}${ITKM_I${ITKM_${pixel_type}}${image_dim}}" "${ITKT_VIF${image_dim}},${ITKT_I${ITKM_${pixel_type}}${image_dim}}")
itk_wrap_template("${ITKM_I${ITKM_${pixel_type}}${image_dim}}${ITKM_VIF${image_dim}}" "${ITKT_I${ITKM_${pixel_type}}${image_dim}},${ITKT_VIF${image_dim}}")
# Vector(float, 3) <-> (RGBPixel, RGBAPixel)
itk_wrap_template("${ITKM_IVF3${image_dim}}${ITKM_I${ITKM_${pixel_type}}${image_dim}}" "${ITKT_IVF3${image_dim}},${ITKT_I${ITKM_${pixel_type}}${image_dim}}")
itk_wrap_template("${ITKM_I${ITKM_${pixel_type}}${image_dim}}${ITKM_IVF3${image_dim}}" "${ITKT_I${ITKM_${pixel_type}}${image_dim}},${ITKT_IVF3${image_dim}}")
endif()
if(ITKM_VID${image_dim} AND ITKM_I${ITKM_${pixel_type}}${image_dim} AND ITKT_VID${image_dim} AND ITKT_I${ITKM_${pixel_type}}${image_dim})
# VectorImage(double) <-> (RGBPixel, RGBAPixel)
itk_wrap_template("${ITKM_VID${image_dim}}${ITKM_I${ITKM_${pixel_type}}${image_dim}}" "${ITKT_VID${image_dim}},${ITKT_I${ITKM_${pixel_type}}${image_dim}}")
itk_wrap_template("${ITKM_I${ITKM_${pixel_type}}${image_dim}}${ITKM_VID${image_dim}}" "${ITKT_I${ITKM_${pixel_type}}${image_dim}},${ITKT_VID${image_dim}}")
# Vector(double, 3) <-> (RGBPixel, RGBAPixel)
itk_wrap_template("${ITKM_IVD3${image_dim}}${ITKM_I${ITKM_${pixel_type}}${image_dim}}" "${ITKT_IVD3${image_dim}},${ITKT_I${ITKM_${pixel_type}}${image_dim}}")
itk_wrap_template("${ITKM_I${ITKM_${pixel_type}}${image_dim}}${ITKM_IVD3${image_dim}}" "${ITKT_I${ITKM_${pixel_type}}${image_dim}},${ITKT_IVD3${image_dim}}")
endif()
endforeach()
endif()
Expand Down Expand Up @@ -61,8 +69,8 @@ itk_wrap_class("itk::CastImageFilter" POINTER_WITH_SUPERCLASS)
itk_wrap_image_filter_combinations("${rgb}" "${rgb}")

# vector <-> RGB
# itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR}" "${WRAP_ITK_RGB}" 3)
# itk_wrap_image_filter_combinations("${WRAP_ITK_RGB}" "${WRAP_ITK_VECTOR}" 3)
# itk_wrap_image_filter_combinations("${WRAP_ITK_VECTOR}" "${WRAP_ITK_RGB}")
# itk_wrap_image_filter_combinations("${WRAP_ITK_RGB}" "${WRAP_ITK_VECTOR}")

# Enable casting 64 bit unsigned int to smaller integer types
if(ITK_WRAP_unsigned_long OR NOT ${ITKM_IT} STREQUAL "ULL")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@
watershed.SetThreshold(0.01)
watershed.SetLevel(0.2)

relabel = itk.RelabelComponentImageFilter.New(Input=watershed.GetOutput())
# If `cmake` has `-DITK_WRAP_signed_char:BOOL=ON` at build time then the output image type for this
# use of `RelabelComponentImageFilter` defaults to `itk.Image[itk.SC,2]`, but that does not provide
# sufficiently many output labels, giving a runtime error for this test. So, we explicitly override
# the output image type here to use `itk.Image[itk.SS,2]`.
relabel = itk.RelabelComponentImageFilter[type(watershed.GetOutput()),itk.Image[itk.SS,2]].New(Input=watershed.GetOutput())

cast = itk.CastImageFilter[relabel.GetOutput().__class__,
itk.Image[itk.ctype('unsigned char'), Dimension]].New(Input=relabel.GetOutput())
Expand Down
15 changes: 10 additions & 5 deletions Wrapping/Generators/Python/PyBase/pyBase.i
Original file line number Diff line number Diff line change
Expand Up @@ -425,13 +425,18 @@ str = str
import numpy as np
import itkTypes
# numpy dtype
# if both a numpy dtype and a ctype exist, use the latter.
if type(pixel_type) is type:
pixel_type = itkTypes.itkCType.GetCTypeForDType(pixel_type)
current_pixel_type = itk.template(self)[1][0]
if current_pixel_type is pixel_type:
c_pixel_type = itkTypes.itkCType.GetCTypeForDType(pixel_type)
if c_pixel_type is not None:
pixel_type = c_pixel_type
# input_image_template is Image or VectorImage
(input_image_template, (input_pixel_type, input_image_dimension)) = itk.template(self)
if input_pixel_type is pixel_type:
return self
OutputImageType = itk.Image[pixel_type, self.GetImageDimension()]
OutputImageType = input_image_template[pixel_type, input_image_dimension]
cast = itk.cast_image_filter(self, ttype=(type(self), OutputImageType))
return cast
Expand Down
10 changes: 10 additions & 0 deletions Wrapping/Generators/Python/Tests/extras.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,16 @@ def custom_callback(name, progress):
cast = image.astype(np.float32)
assert cast.dtype == np.float32

# Test .astype for conversion between vector-like pixel types.
components = 3
numpyImage = np.random.randint(0, 256, (12,8,components)).astype(np.uint8)
input_image = itk.image_from_array(numpyImage, is_vector=True)
if (type(input_image) == itk.Image[itk.RGBPixel[itk.UC],2] and
hasattr(itk.CastImageFilter, 'IRGBUC2IVF32')):
output_pixel_type = itk.Vector[itk.F,components]
output_image = input_image.astype(output_pixel_type)
assert type(output_image) == itk.Image[output_pixel_type, 2]

except ImportError:
print("NumPy not imported. Skipping BridgeNumPy tests")
# Numpy is not available, do not run the Bridge NumPy tests
Expand Down

0 comments on commit 8f2a6c9

Please sign in to comment.