From f6a0343be3d6c81b53a92898e0855c3799d217d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Fri, 7 Jul 2023 16:48:55 -0400 Subject: [PATCH] ENH: Add SSSCI wrapping with Python test and baseline --- ...ecialCoordinatesImageTestPython.mha.sha512 | 1 + test/Input/bmode_p59.hdf5.sha512 | 1 + wrapping/CMakeLists.txt | 4 +- ...Array3DSpecialCoordinatesImageFilters.wrap | 2 +- ...itkSliceSeriesSpecialCoordinatesImage.wrap | 51 +++++ ...eSeriesSpecialCoordinatesImageFilters.wrap | 185 ++++++++++++++++++ ...ectra1DSupportWindowToMaskImageFilter.wrap | 14 ++ wrapping/test/CMakeLists.txt | 15 ++ wrapping/test/PythonSliceSeriesResample.py | 57 ++++++ 9 files changed, 328 insertions(+), 2 deletions(-) create mode 100644 test/Baseline/itkSliceSeriesSpecialCoordinatesImageTestPython.mha.sha512 create mode 100644 test/Input/bmode_p59.hdf5.sha512 create mode 100644 wrapping/itkSliceSeriesSpecialCoordinatesImage.wrap create mode 100644 wrapping/itkSliceSeriesSpecialCoordinatesImageFilters.wrap create mode 100644 wrapping/test/PythonSliceSeriesResample.py diff --git a/test/Baseline/itkSliceSeriesSpecialCoordinatesImageTestPython.mha.sha512 b/test/Baseline/itkSliceSeriesSpecialCoordinatesImageTestPython.mha.sha512 new file mode 100644 index 0000000..5f4a68d --- /dev/null +++ b/test/Baseline/itkSliceSeriesSpecialCoordinatesImageTestPython.mha.sha512 @@ -0,0 +1 @@ +ee322ad1e126dfd8660ad8d550f5203e48b83a88cd4767b52ff4224259dd6b13b63984382dd2971a2a8c95381d491a2cfb519918075efed76e7e09955de0fc7e diff --git a/test/Input/bmode_p59.hdf5.sha512 b/test/Input/bmode_p59.hdf5.sha512 new file mode 100644 index 0000000..c07643b --- /dev/null +++ b/test/Input/bmode_p59.hdf5.sha512 @@ -0,0 +1 @@ +637863e4b552e0d58c5ee9ce1f414b3b3c89b782a29a9503c0f2eca4fc23bbbf0ad8d741b5d884400e4aed71e8f43c3881113914c6ca34a79fcdc85272066179 diff --git a/wrapping/CMakeLists.txt b/wrapping/CMakeLists.txt index 9ea3628..faddb31 100644 --- a/wrapping/CMakeLists.txt +++ b/wrapping/CMakeLists.txt @@ -11,6 +11,8 @@ set(WRAPPER_SUBMODULE_ORDER itkSpecialCoordinatesImage itkCurvilinearArraySpecialCoordinatesImage itkCurvilinearArraySpecialCoordinatesImageFilters + itkSliceSeriesSpecialCoordinatesImage + itkSliceSeriesSpecialCoordinatesImageFilters itkAttenuationImageFilter itkBlockMatchingMetricImageFilter itkBlockMatchingNormalizedCrossCorrelationMetricImageFilter @@ -18,7 +20,7 @@ set(WRAPPER_SUBMODULE_ORDER itkBlockMatchingNormalizedCrossCorrelationNeighborhoodIteratorMetricImageFilter itkImageUltrasound # must come before Spectra1DSupportWindow itkSpectra1DSupportWindowImageFilter - itkSpectra1DSupportWindowToMaskImageFilter # must come after CASCI + itkSpectra1DSupportWindowToMaskImageFilter # must come after CASCI SSSCI itkFrequencyDomain1DFilterFunction itkFrequencyDomain1DImageFilter itkRegionFromReferenceImageFilter diff --git a/wrapping/itkPhasedArray3DSpecialCoordinatesImageFilters.wrap b/wrapping/itkPhasedArray3DSpecialCoordinatesImageFilters.wrap index 30e4d34..2faa512 100644 --- a/wrapping/itkPhasedArray3DSpecialCoordinatesImageFilters.wrap +++ b/wrapping/itkPhasedArray3DSpecialCoordinatesImageFilters.wrap @@ -47,7 +47,7 @@ itk_wrap_class("itk::ImageToImageFilter" POINTER) endforeach() itk_end_wrap_class() -itk_wrap_class("itk::ImageFileReader" POINTER_WITH_SUPERCLASS) +itk_wrap_class("itk::ImageFileReader" POINTER) foreach(t ${WRAP_ITK_SCALAR}) itk_wrap_template("PA3DSCI${ITKM_${t}}" "itk::PhasedArray3DSpecialCoordinatesImage< ${ITKT_${t}} >") diff --git a/wrapping/itkSliceSeriesSpecialCoordinatesImage.wrap b/wrapping/itkSliceSeriesSpecialCoordinatesImage.wrap new file mode 100644 index 0000000..216273d --- /dev/null +++ b/wrapping/itkSliceSeriesSpecialCoordinatesImage.wrap @@ -0,0 +1,51 @@ +itk_wrap_include("itkEuler3DTransform.h") + +# Explicitly override template method wrappings so that implicit +# scalar type is always `double` for greatest precision. +# Adds wrapping overrides to `itkSliceSeriesSpecialCoordinatesImage_ext.i` configured with +# CMake for input to SWIG wrapping generation. +# See `DECL_PYTHON_IMAGEBASE_CLASS` definition in `ITK/Wrapping/Generators/Python/PyBase/pyBase.i` +# for precedent. +string(APPEND ITK_WRAP_PYTHON_SWIG_EXT " +%inline %{ +#include \"itkContinuousIndexSwigInterface.h\" +%} + +%define DECL_PYTHON_SLICESERIESSPECIALCOORDINATESIMAGE_CLASS(swig_name, template_params) + + %extend swig_name { + itkIndex##template_params TransformPhysicalPointToIndex(const itkPointD##template_params & point ) { + return self->TransformPhysicalPointToIndex( point ); + } + + itkContinuousIndexD##template_params TransformPhysicalPointToContinuousIndex(const itkPointD##template_params & point ) { + return self->TransformPhysicalPointToContinuousIndex( point ); + } + + itkPointD##template_params TransformContinuousIndexToPhysicalPoint(const itkContinuousIndexD##template_params & idx ) { + return self->TransformContinuousIndexToPhysicalPoint( idx ); + } + + itkPointD##template_params TransformIndexToPhysicalPoint(const itkIndex##template_params & idx ) { + return self->TransformIndexToPhysicalPoint( idx ); + } + } + +%enddef +") + +# Wrap class for UC and F. Dimension is always 3 (slice dimension 2). +itk_wrap_class("itk::SliceSeriesSpecialCoordinatesImage" POINTER_WITH_SUPERCLASS) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template_params "itk::Image, itk::Euler3DTransform") + itk_wrap_template("IUC3E3D" ${SSSCI_template_params}) + string(APPEND ITK_WRAP_PYTHON_SWIG_EXT "DECL_PYTHON_SLICESERIESSPECIALCOORDINATESIMAGE_CLASS(${WRAPPER_SWIG_NAME}IUC3E3D, 3)\n") + endif() + if(ITK_WRAP_float) + set(SSSCI_template_params "itk::Image, itk::Euler3DTransform") + itk_wrap_template("IF3E3D" ${SSSCI_template_params}) + string(APPEND ITK_WRAP_PYTHON_SWIG_EXT "DECL_PYTHON_SLICESERIESSPECIALCOORDINATESIMAGE_CLASS(${WRAPPER_SWIG_NAME}IF3E3D, 3)\n") + endif() +itk_end_wrap_class() + +# Then wrap consuming filters in itkSliceSeriesSpecialCoordinatesImageFilters.wrap diff --git a/wrapping/itkSliceSeriesSpecialCoordinatesImageFilters.wrap b/wrapping/itkSliceSeriesSpecialCoordinatesImageFilters.wrap new file mode 100644 index 0000000..9414178 --- /dev/null +++ b/wrapping/itkSliceSeriesSpecialCoordinatesImageFilters.wrap @@ -0,0 +1,185 @@ +# ITK image filters wrapped for ITKUltrasound `itk::SliceSeriesSpecialCoordinatesImage` inputs. +# Must be wrapped in a separate file after `itkSliceSeriesSpecialCoordinatesImage.wrap` so that +# SWIG does not implicitly define erroneous overrides for template methods such as +# `TransformPhysicalPointToContinuousIndex`, etc. + +# See `WRAPPER_SUBMODULE_ORDER` in CMakeLists.txt for where +# `itkSliceSeriesSpecialCoordinatesImageFilters.wrap` is set to +# be wrapped after `itkSliceSeriesSpecialCoordinatesImage.wrap`. + +itk_wrap_include("itkSliceSeriesSpecialCoordinatesImage.h") +itk_wrap_include("itkEuler3DTransform.h") + +itk_wrap_class("itk::ImageSource" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3D" "${SSSCI_template}") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3D" "${SSSCI_template}") + endif() +itk_end_wrap_class() + +itk_wrap_include("itkImage.h") +itk_wrap_class("itk::ImageToImageFilter" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("IUC3SSSCIUC3E3D" "itk::Image< unsigned char, 3 >, ${SSSCI_template}") + # itk_wrap_template("SSSCIUC3E3DSSSCIUC3E3D" "${SSSCI_template}, ${SSSCI_template}") # procedural form defaults to this + itk_wrap_template("SSSCIUC3E3DIUC3" "${SSSCI_template}, itk::Image< unsigned char, 3 >") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("IF3SSSCIF3E3D" "itk::Image< float, 3 >, ${SSSCI_template}") + # itk_wrap_template("SSSCIF3E3DSSSCIF3E3D" "${SSSCI_template}, ${SSSCI_template}") # procedural form defaults to this + itk_wrap_template("SSSCIF3E3DIF3" "${SSSCI_template}, itk::Image< float, 3 >") + endif() + if(ITK_WRAP_unsigned_char AND ITK_WRAP_float) + set(SSSCI_F "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3DIUC3" "${SSSCI_F}, itk::Image< unsigned char, 3 >") + endif() +itk_end_wrap_class() + +itk_wrap_class("itk::ImageFileReader" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3D" "${SSSCI_template}") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3D" "${SSSCI_template}") + endif() +itk_end_wrap_class() + +itk_wrap_class("itk::ImageFileWriter" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3D" "${SSSCI_template}") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3D" "${SSSCI_template}") + endif() +itk_end_wrap_class() + +itk_wrap_class("itk::CastImageFilter" POINTER_WITH_2_SUPERCLASSES) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("IUC3SSSCIUC3E3D" "itk::Image< unsigned char, 3 >, ${SSSCI_template}") + itk_wrap_template("SSSCIUC3E3DIUC3" "${SSSCI_template}, itk::Image< unsigned char, 3 >") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("IF3SSSCIF3E3D" "itk::Image< float, 3 >, ${SSSCI_template}") + itk_wrap_template("SSSCIF3E3DIF3" "${SSSCI_template}, itk::Image< float, 3 >") + endif() + if(ITK_WRAP_unsigned_char AND ITK_WRAP_float) + set(SSSCI_UC "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + set(SSSCI_F "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3DSSSCIF3E3D" "${SSSCI_UC}, ${SSSCI_F}") + itk_wrap_template("SSSCIF3E3DSSSCIUC3E3D" "${SSSCI_F}, ${SSSCI_UC}") + endif() +itk_end_wrap_class() + +itk_wrap_class("itk::RescaleIntensityImageFilter" POINTER_WITH_2_SUPERCLASSES) + if(ITK_WRAP_unsigned_char AND ITK_WRAP_float) + set(SSSCI_UC "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + set(SSSCI_F "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3DSSSCIUC3E3D" "${SSSCI_F}, ${SSSCI_UC}") + endif() +itk_end_wrap_class() + +# The rest is needed for ResampleImageFilter and interpolator functions +itk_wrap_include("itkResampleImageFilter.h") +itk_wrap_class("itk::ResampleImageFilter" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("IUC3SSSCIUC3E3D" "itk::Image< unsigned char, 3 >, ${SSSCI_template}") + itk_wrap_template("SSSCIUC3E3DIUC3" "${SSSCI_template}, itk::Image< unsigned char, 3 >") + # itk_wrap_template("SSSCIUC3E3DSSSCIUC3E3D" "${SSSCI_template}, ${SSSCI_template}") # itk.resample_image_filter defaults to this + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("IF3SSSCIF3E3D" "itk::Image< float, 3 >, ${SSSCI_template}") + itk_wrap_template("SSSCIF3E3DIF3" "${SSSCI_template}, itk::Image< float, 3 >") + # itk_wrap_template("SSSCIF3E3DSSSCIF3E3D" "${SSSCI_template}, ${SSSCI_template}") # itk.resample_image_filter defaults to this + endif() + if(ITK_WRAP_unsigned_char AND ITK_WRAP_float) + set(SSSCI_F "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3DIUC3" "${SSSCI_F}, itk::Image< unsigned char, 3 >") + endif() +itk_end_wrap_class() + +itk_wrap_class("itk::ImageFunction" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}, ${ITKT_D}") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}, ${ITKT_D}") + endif() +itk_end_wrap_class() + +itk_wrap_class("itk::InterpolateImageFunction" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}") + endif() +itk_end_wrap_class() + +itk_wrap_class("itk::NearestNeighborInterpolateImageFunction" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}") + endif() +itk_end_wrap_class() + +itk_wrap_class("itk::LinearInterpolateImageFunction" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}") + endif() +itk_end_wrap_class() + +itk_wrap_class("itk::GaussianInterpolateImageFunction" POINTER) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3D${ITKM_D}" "${SSSCI_template}, ${ITKT_D}") + endif() +itk_end_wrap_class() + +itk_wrap_include("itkWindowedSincInterpolateImageFunction.h") +set(window_functions "Hamming" "Cosine" "Welch" "Lanczos") +set(radii 2 3) +itk_wrap_class("itk::WindowedSincInterpolateImageFunction" POINTER) + foreach(r ${radii}) # radius + foreach(function ${window_functions}) + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIUC3E3D${r}${function}" "${SSSCI_template}, ${r}, itk::Function::${function}WindowFunction< ${r} >") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("SSSCIF3E3D${r}${function}" "${SSSCI_template}, ${r}, itk::Function::${function}WindowFunction< ${r} >") + endif() + endforeach() + endforeach() +itk_end_wrap_class() diff --git a/wrapping/itkSpectra1DSupportWindowToMaskImageFilter.wrap b/wrapping/itkSpectra1DSupportWindowToMaskImageFilter.wrap index 781009c..5eb625e 100644 --- a/wrapping/itkSpectra1DSupportWindowToMaskImageFilter.wrap +++ b/wrapping/itkSpectra1DSupportWindowToMaskImageFilter.wrap @@ -2,18 +2,32 @@ itk_wrap_include("list") itk_wrap_include("itkIndex.h") itk_wrap_include("itkImage.h") itk_wrap_include("itkCurvilinearArraySpecialCoordinatesImage.h") +itk_wrap_include("itkSliceSeriesSpecialCoordinatesImage.h") +itk_wrap_include("itkEuler3DTransform.h") itk_wrap_class("itk::Spectra1DSupportWindowToMaskImageFilter" POINTER_WITH_2_SUPERCLASSES) + # regular image foreach(d ${ITK_WRAP_IMAGE_DIMS}) foreach(t ${WRAP_ITK_INT}) itk_wrap_template("IlistitkIndex${d}${d}${ITKM_I${t}${d}}" "itk::Image< std::list< itk::Index< ${d} > >, ${d} >, ${ITKT_I${t}${d}}") endforeach(t) endforeach(d) + # CASCI foreach(d ${ITK_WRAP_IMAGE_DIMS}) foreach(t ${WRAP_ITK_INT}) itk_wrap_template("IlistitkIndex${d}${d}CASCI${ITKM_${t}}${d}" "itk::Image< std::list< itk::Index< ${d} > >, ${d} >, itk::CurvilinearArraySpecialCoordinatesImage< ${ITKT_${t}}, ${d} >") endforeach() endforeach() + + # SSSCI + if(ITK_WRAP_unsigned_char) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("IlistitkIndex33SSSCIUC3E3D" "itk::Image< std::list< itk::Index< 3 > >, 3 >, ${SSSCI_template}") + endif() + if(ITK_WRAP_float) + set(SSSCI_template "itk::SliceSeriesSpecialCoordinatesImage, itk::Euler3DTransform>") + itk_wrap_template("IlistitkIndex33SSSCIF3E3D" "itk::Image< std::list< itk::Index< 3 > >, 3 >, ${SSSCI_template}") + endif() itk_end_wrap_class() diff --git a/wrapping/test/CMakeLists.txt b/wrapping/test/CMakeLists.txt index b1ee703..62a27e2 100644 --- a/wrapping/test/CMakeLists.txt +++ b/wrapping/test/CMakeLists.txt @@ -58,6 +58,21 @@ itk_python_add_test(NAME PythonCurvilinearResampleTest --first-sample-distance 26.4 ) +itk_python_expression_add_test(NAME PythonInstantiateGaussianInterpolateImageFunctionSSSCI + EXPRESSION "iFunc = itk.GaussianInterpolateImageFunction[itk.SliceSeriesSpecialCoordinatesImage[itk.Image[itk.UC, 2], itk.Euler3DTransform[itk.D]], itk.D].New()" + ) + +itk_python_add_test(NAME PythonSliceSeriesResampleTest + TEST_DRIVER_ARGS + --compareIntensityTolerance 1 + --compare + DATA{${test_baseline_dir}/itkSliceSeriesSpecialCoordinatesImageTestPython.mha} + ${ITK_TEST_OUTPUT_DIR}/itkSliceSeriesSpecialCoordinatesImageTestPython.mha + COMMAND PythonSliceSeriesResample.py + -i DATA{${test_input_dir}/bmode_p59.hdf5} + -o ${ITK_TEST_OUTPUT_DIR}/itkSliceSeriesSpecialCoordinatesImageTestPython.mha + ) + itk_python_expression_add_test(NAME PythonInstantiateGaussianInterpolateImageFunctionPA3DSCI EXPRESSION "iFunc = itk.GaussianInterpolateImageFunction[itk.PhasedArray3DSpecialCoordinatesImage[itk.F], itk.D].New()" ) diff --git a/wrapping/test/PythonSliceSeriesResample.py b/wrapping/test/PythonSliceSeriesResample.py new file mode 100644 index 0000000..ef78c76 --- /dev/null +++ b/wrapping/test/PythonSliceSeriesResample.py @@ -0,0 +1,57 @@ +#========================================================================== +# +# Copyright NumFOCUS +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0.txt +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#==========================================================================*/ + +import math +import itk +import argparse + +parser = argparse.ArgumentParser(description="Estimate three back-scatter coefficients.") +parser.add_argument("-i", "--input-image", required=True) +parser.add_argument("-o", "--output-image", required=True) +args = parser.parse_args() + +itk.auto_progress(2) + +# define the types we will use +pixel_type = itk.UC +dimension = 3 +slice_type = itk.Image[pixel_type, dimension - 1] +transform_type = itk.Euler3DTransform[itk.D] +image_type = itk.SliceSeriesSpecialCoordinatesImage[slice_type, transform_type] + +# read the image +reader = itk.ImageFileReader[image_type].New() +reader.SetImageIO(itk.HDF5UltrasoundImageIO.New()) +reader.SetFileName(args.input_image) +reader.Update() +image = reader.GetOutput() + +# add transforms with monotonic translation +image.DisconnectPipeline() +for k in range(image.GetBufferedRegion().GetSize()[2]): + transform = transform_type.New() + transform.Translate([0, 0, k]) + image.SetSliceTransform(k, transform) + +print("Verify resampling works with SliceSeriesSpecialCoordinatesImage input") +output_size = [128, 150, 100] +output_spacing = [2.0] * dimension +output_origin = [0.0] * dimension +result = itk.resample_image_filter(image, size=output_size, output_spacing=output_spacing, output_origin=output_origin) +itk.imwrite(result, args.output_image) +print(f"Image written to {args.output_image}")