diff --git a/CMakeLists.txt b/CMakeLists.txt index f66ce4d..dccdf1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,10 @@ project(Ultrasound) cmake_minimum_required(VERSION 3.16.3) +if(POLICY CMP0135) + cmake_policy(SET CMP0135 NEW) +endif() + set(Ultrasound_LIBRARIES Ultrasound) if(NOT ITK_SOURCE_DIR) diff --git a/include/itkSliceSeriesSpecialCoordinatesImage.h b/include/itkSliceSeriesSpecialCoordinatesImage.h index a8a9939..361ddeb 100644 --- a/include/itkSliceSeriesSpecialCoordinatesImage.h +++ b/include/itkSliceSeriesSpecialCoordinatesImage.h @@ -272,7 +272,7 @@ class ITK_TEMPLATE_EXPORT SliceSeriesSpecialCoordinatesImage : public SpecialCoo slicePoint[ii] = nextPoint[ii]; } ContinuousIndex sliceIndex = - this->m_SliceImage->TransformPhysicalPointToContinuousIndex(slicePoint); + this->m_SliceImage->template TransformPhysicalPointToContinuousIndex(slicePoint); for (unsigned int ii = 0; ii < SliceImageType::ImageDimension; ++ii) { index[ii] = sliceIndex[ii]; diff --git a/test/Baseline/ScanConvertSliceSeriesTestOutput.mha.sha512 b/test/Baseline/ScanConvertSliceSeriesTestOutput.mha.sha512 new file mode 100644 index 0000000..eeebb5e --- /dev/null +++ b/test/Baseline/ScanConvertSliceSeriesTestOutput.mha.sha512 @@ -0,0 +1 @@ +517f382d498571f325ac804602aa373fd6db0786d25cd9e38c6097dd8251ea17f735b28670036bfab26cdddc94312486ef48899d089c8f4314baa41a6645b1ff 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..07e853a 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}/ScanConvertSliceSeriesTestOutput.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..2ab23de --- /dev/null +++ b/wrapping/test/PythonSliceSeriesResample.py @@ -0,0 +1,50 @@ +#========================================================================== +# +# 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.UltrasoundImageFileReader[image_type].New() +reader.SetFileName(args.input_image) +reader.Update() +image = reader.GetOutput() +image.DisconnectPipeline() + +print("Verify resampling works with SliceSeriesSpecialCoordinatesImage input") +output_size = [46, 55, 82] +output_spacing = [1.0] * dimension +output_origin = [0.0, -27.2693, -40.6222] +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}")