# How to \`itk.resample\_image\_filter\` with a \`BSplineTransform\` with 3D images?

**URL:** https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987
**Category:** Beginner Questions
**Tags:** itk, bspline, registration, python
**Created:** [May 13, 2022, 3:44pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987 "2022-05-13T15:44:44Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![edgar](https://discourse.itk.org/letter_avatar_proxy/v4/letter/e/b487fb/32.png) [@edgar](https://discourse.itk.org/u/edgar)
#### Post date: [May 13, 2022, 3:44pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/1 "2022-05-13T15:44:44Z")

</div>

## Table of Contents

- [1. How to `itk.resample_image_filter` with a `BSplineTransform` with 3D images?](#org1d085b1)
  - [1.1. What I have tried](#org2ffab1c)
    - [1.1.1. Inputs (data)](#orgdff05a1)
    - [1.1.2. Failed attempt with `resample_image_filter`](#org078fedf)
    - [1.1.3. Useless result with `ResampleImageFilter`](#orge3be0d5)
    - [1.1.4. Error with `ResampleImageFilter` and `GetCoefficientImages()`](#orgbe66ac5)
    - [1.1.5. Error with `ResampleImageFilter` and `GetCoefficientImages()[0]`](#org5ea7456)

  - [1.2. Software](#63f76fae-7b1a-4915-aa10-7aab54616d66)

## 1. How to `itk.resample_image_filter` with a `BSplineTransform` with 3D images?

Hello, everyone!

I am trying to use parts of the [`DeformableRegistration15.cxx`](https://itk.org/Doxygen/html/Examples_2RegistrationITKv4_2DeformableRegistration15_8cxx-example.html) in Python, but I don’t know what to do when `ResampleImageFilter` is combined with `GetCoefficientImages` (from a `BSplineTransform`).

### 1.1. What I have tried

#### 1.1.1. Inputs (data)

Listing 1: Block to print the input to `ResampleImageFilter` and `resample_image_filter`.
```
print("moving\_image\_type:\t", moving_image_type)print("coord\_type:\t", moving_image_type)print("identity\_transform:\t", identity_transform)print("bspline\_transform\_coarse\t", bspline_transform_coarse)print("bspline\_transform\_fine\t", bspline_transform_fine)
interpolator_fine = itk.BSplineResampleImageFunction[
    moving_image_type, coord_type].New()
```

```
moving_image_type: <class 'itk.itkImagePython.itkImageF3'>
coord_type: <class 'itk.itkImagePython.itkImageF3'>
identity_transform: IdentityTransform (0x55a08d43e540)
  RTTI typeinfo: itk::IdentityTransform<double, 3u>
  Reference Count: 1
  Modified Time: 127
  Debug: Off
  Object Name:
  Observers:
    none

bspline_transform_coarse BSplineTransform (0x55a08c2b42b0)
  RTTI typeinfo: itk::BSplineTransform<double, 3u, 3u>
  Reference Count: 3
  Modified Time: 14797
  Debug: Off
  Object Name:
  Observers:
    none
  CoefficientImage: [0x55a08cd32630, 0x55a08cd328f0, 0x55a08cade1e0]
  TransformDomainOrigin: [0, 0, 0]
  TransformDomainPhysicalDimensions: [99, 99, 9]
  TransformDomainDirection: 1 0 0
0 1 0
0 0 1

  TransformDomainMeshSize: [2, 2, 2]
  GridSize: [5, 5, 5]
  GridOrigin: [-49.5, -49.5, -4.5]
  GridSpacing: [49.5, 49.5, 4.5]
  GridDirection: 1 0 0
0 1 0
0 0 1

bspline_transform_fine BSplineTransform (0x55a08f8fa480)
  RTTI typeinfo: itk::BSplineTransform<double, 3u, 3u>
  Reference Count: 1
  Modified Time: 14848
  Debug: Off
  Object Name:
  Observers:
    none
  CoefficientImage: [0x55a08f198a00, 0x55a08f198cc0, 0x55a08f198f80]
  TransformDomainOrigin: [0, 0, 0]
  TransformDomainPhysicalDimensions: [99, 99, 9]
  TransformDomainDirection: 1 0 0
0 1 0
0 0 1

  TransformDomainMeshSize: [2, 2, 2]
  GridSize: [5, 5, 5]
  GridOrigin: [-49.5, -49.5, -4.5]
  GridSpacing: [49.5, 49.5, 4.5]
  GridDirection: 1 0 0
0 1 0
0 0 1
```

#### 1.1.2. Failed attempt with `resample_image_filter`

Listing 2: This block fails probably because I don’t know how to provide the `GetCoefficientImages`.
```
# https://examples.itk.org/src/filtering/imagegrid/resampleavectorimage/documentationupsampler= itk.resample_image_filter(
    bspline_transform_coarse.GetCoefficientImages(),
    interpolator=interpolator_fine,
    transform=identity_transform,
    size=bspline_transform_fine.GetCoefficientImages())
```

```
swig/python detected a memory leak of type 'itk::FixedArray< itk::SmartPointer< itk::Image< double,3 > >,3 > *', no destructor found.
swig/python detected a memory leak of type 'itk::FixedArray< itk::SmartPointer< itk::Image< double,3 > >,3 > *', no destructor found.
Traceback (most recent call last):
  File "<string>", line 17, in __PYTHON_EL_eval
  File "<string>", line 2, in <module>
  File "/usr/lib/python3.10/site-packages/itk/support/helpers.py", line 176, in image_filter_wrapper
    return image_filter(*args, **kwargs)
  File "/usr/lib/python3.10/site-packages/itk/itkResampleImageFilterPython.py", line 5542, in resample_image_filter
    instance = itk.ResampleImageFilter.New(*args, **kwargs)
  File "/usr/lib/python3.10/site-packages/itk/support/template_class.py", line 734, in New
    raise itk.TemplateTypeError(self, input_type)
itk.support.extras.TemplateTypeError: itk.ResampleImageFilter is not wrapped for input type `None`.

To limit the size of the package, only a limited number of
types are available in ITK Python. To print the supported
types, run the following command in your python environment:

    itk.ResampleImageFilter.GetTypes()

Possible solutions:
* If you are an application user:
** Convert your input image into a supported format (see below).
** Contact developer to report the issue.
* If you are an application developer, force input images to be
loaded in a supported pixel type.

    e.g.: instance = itk.ResampleImageFilter[itk.Image[itk.SC,2], itk.Image[itk.SC,2]].New(my_input)

* (Advanced) If you are an application developer, build ITK Python yourself and
turned to `ON` the corresponding CMake option to wrap the pixel type or image
dimension you need. When configuring ITK with CMake, you can set
`ITK_WRAP_${type}` (replace ${type} with appropriate pixel type such as
`double`). If you need to support images with 4 or 5 dimensions, you can add
these dimensions to the list of dimensions in the CMake variable
`ITK_WRAP_IMAGE_DIMS`.

Supported input types:

itk.Image[itk.SC,2]
itk.Image[itk.SC,3]
itk.Image[itk.SC,4]
itk.Image[itk.SS,2]
itk.Image[itk.SS,3]
itk.Image[itk.SS,4]
itk.Image[itk.UC,2]
itk.Image[itk.UC,3]
itk.Image[itk.UC,4]
itk.Image[itk.US,2]
itk.Image[itk.US,3]
itk.Image[itk.US,4]
itk.Image[itk.F,2]
itk.Image[itk.F,3]
itk.Image[itk.F,4]
itk.Image[itk.D,2]
itk.Image[itk.D,3]
itk.Image[itk.D,4]
itk.Image[itk.Vector[itk.D,2],2]
itk.Image[itk.Vector[itk.D,2],3]
itk.Image[itk.Vector[itk.D,2],4]
itk.Image[itk.Vector[itk.D,3],2]
itk.Image[itk.Vector[itk.D,3],3]
itk.Image[itk.Vector[itk.D,3],4]
itk.Image[itk.Vector[itk.D,4],2]
itk.Image[itk.Vector[itk.D,4],3]
itk.Image[itk.Vector[itk.D,4],4]
itk.Image[itk.Vector[itk.F,2],2]
itk.Image[itk.Vector[itk.F,2],3]
itk.Image[itk.Vector[itk.F,2],4]
itk.Image[itk.Vector[itk.F,3],2]
itk.Image[itk.Vector[itk.F,3],3]
itk.Image[itk.Vector[itk.F,3],4]
itk.Image[itk.Vector[itk.F,4],2]
itk.Image[itk.Vector[itk.F,4],3]
itk.Image[itk.Vector[itk.F,4],4]
itk.Image[itk.RGBPixel[itk.UC],2]
itk.Image[itk.RGBPixel[itk.UC],3]
itk.Image[itk.RGBPixel[itk.UC],4]
itk.Image[itk.RGBPixel[itk.US],2]
itk.Image[itk.RGBPixel[itk.US],3]
itk.Image[itk.RGBPixel[itk.US],4]
itk.Image[itk.RGBAPixel[itk.UC],2]
itk.Image[itk.RGBAPixel[itk.UC],3]
itk.Image[itk.RGBAPixel[itk.UC],4]
itk.Image[itk.RGBAPixel[itk.US],2]
itk.Image[itk.RGBAPixel[itk.US],3]
itk.Image[itk.RGBAPixel[itk.US],4]
itk.VectorImage[itk.UC,2]
itk.VectorImage[itk.SC,2]
itk.VectorImage[itk.SS,2]
itk.VectorImage[itk.US,2]
itk.VectorImage[itk.F,2]
itk.VectorImage[itk.D,2]
itk.VectorImage[itk.UC,3]
itk.VectorImage[itk.SC,3]
itk.VectorImage[itk.SS,3]
itk.VectorImage[itk.US,3]
itk.VectorImage[itk.F,3]
itk.VectorImage[itk.D,3]
itk.VectorImage[itk.UC,4]
itk.VectorImage[itk.SC,4]
itk.VectorImage[itk.SS,4]
itk.VectorImage[itk.US,4]
itk.VectorImage[itk.F,4]
itk.VectorImage[itk.D,4]
```

#### 1.1.3. Useless result with `ResampleImageFilter`

Listing 3: This block works.
```
# https://examples.itk.org/src/filtering/imagegrid/resampleavectorimage/documentationupsampler= itk.ResampleImageFilter[moving_image_type, moving_image_type].New()print(upsampler)
```

```
ResampleImageFilter (0x55a08bde5270)
  RTTI typeinfo: itk::ResampleImageFilter<itk::Image<float, 3u>, itk::Image<float, 3u>, double, double>
  Reference Count: 1
  Modified Time: 15126
  Debug: Off
  Object Name:
  Observers:
    none
  Inputs:
    Primary: (0) *
    ReferenceImage: (0)
    Transform: (0x55a08ffa49c0) *
  Indexed Inputs:
    0: Primary (0)
    1: ReferenceImage (0)
  Required Input Names: Primary, Transform
  NumberOfRequiredInputs: 1
  Outputs:
    Primary: (0x55a08ee2f840)
  Indexed Outputs:
    0: Primary (0x55a08ee2f840)
  NumberOfRequiredOutputs: 1
  Number Of Work Units: 32
  ReleaseDataFlag: Off
  ReleaseDataBeforeUpdateFlag: Off
  AbortGenerateData: Off
  Progress: 0
  Multithreader:
    RTTI typeinfo: itk::PoolMultiThreader
    Reference Count: 1
    Modified Time: 15106
    Debug: Off
    Object Name:
    Observers:
      none
    Number of Work Units: 32
    Number of Threads: 8
    Global Maximum Number Of Threads: 128
    Global Default Number Of Threads: 8
    Global Default Threader Type: itk::MultiThreaderBaseEnums::Threader::Pool
    SingleMethod: 0
    SingleData: 0
  DynamicMultiThreading: On
  CoordinateTolerance: 1e-06
  DirectionTolerance: 1e-06
  DefaultPixelValue: 0
  Size: [0, 0, 0]
  OutputStartIndex: [0, 0, 0]
  OutputSpacing: [1, 1, 1]
  OutputOrigin: [0, 0, 0]
  OutputDirection: 1 0 0
0 1 0
0 0 1

  Transform: 0x55a08f6d3800
  Interpolator: 0x55a08fd5e4b0
  Extrapolator: 0
  UseReferenceImage: Off
```

#### 1.1.4. Error with `ResampleImageFilter` and `GetCoefficientImages()`

Listing 4: This block will not work, because of my wrong call to `GetCoefficientImages`.
```
# https://examples.itk.org/src/filtering/imagegrid/resampleavectorimage/documentationupsampler= itk.ResampleImageFilter[moving_image_type, moving_image_type].New(
    Input=bspline_transform_coarse.GetCoefficientImages(),
    Interpolator=interpolator_fine,
    Transform=identity_transform,
    Size=bspline_transform_fine.GetCoefficientImages())
```

```
Traceback (most recent call last):
  File "<string>", line 17, in __PYTHON_EL_eval
  File "<string>", line 2, in <module>
  File "/usr/lib/python3.10/site-packages/itk/itkResampleImageFilterPython.py", line 516, in New
    template_class.New(obj, *args, **kargs)
  File "/usr/lib/python3.10/site-packages/itk/support/template_class.py", line 800, in New
    itk.set_inputs(self, args, kargs)
  File "/usr/lib/python3.10/site-packages/itk/support/extras.py", line 1543, in set_inputs
    attrib(itk.output(value))
TypeError: Expecting argument of type itkImageF3 or itkImageSourceIF3.
Additional information:
Wrong number or type of arguments for overloaded function 'itkImageToImageFilterIF3IF3_SetInput'.
  Possible C/C++ prototypes are:
    itkImageToImageFilterIF3IF3::SetInput(itkImageF3 const *)
    itkImageToImageFilterIF3IF3::SetInput(unsigned int,itkImageF3 const *)
```

#### 1.1.5. Error with `ResampleImageFilter` and `GetCoefficientImages()[0]`

Listing 5: This block will not work, because of my wrong call to `GetCoefficientImages` (or trying to access an inexisting element).
```
# https://examples.itk.org/src/filtering/imagegrid/resampleavectorimage/documentationupsampler= itk.ResampleImageFilter[moving_image_type, moving_image_type].New(
    Input=bspline_transform_coarse.GetCoefficientImages()[0],
    Interpolator=interpolator_fine,
    Transform=identity_transform,
    Size=bspline_transform_fine.GetCoefficientImages())
```

```
swig/python detected a memory leak of type 'itk::FixedArray< itk::SmartPointer< itk::Image< double,3 > >,3 > *', no destructor found.
Traceback (most recent call last):
  File "<string>", line 17, in __PYTHON_EL_eval
  File "<string>", line 3, in <module>
TypeError: 'SwigPyObject' object is not subscriptable
```

### 1.2. Software

```
importitkimportsysprint("Self-compiled version of ITK:\t", itk. __version__ )print("Python version:\t", sys.version)
```

```
Self-compiled version of ITK: 5.3.0
Python version: 3.10.4 (main, Mar 23 2022, 23:05:40) [GCC 11.2.0]
```

---

<div class="post-metadata">

### Author: ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)
#### Post date: [May 13, 2022, 4:56pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/2 "2022-05-13T16:56:45Z")

</div>

Hi @edgar ,

To resample an image with `itk.resample_image_filter` and a b-spline transform, pass the transform in as the `transform` argument.

For the input, use the moving image. The sampling grid can be specified with a reference image, e.g. the fixed image, or by the parameters of the sampling gride, including the ‘size’.

HTH,  
Matt

---

<div class="post-metadata">

### Author: ![edgar](https://discourse.itk.org/letter_avatar_proxy/v4/letter/e/b487fb/32.png) [@edgar](https://discourse.itk.org/u/edgar)
#### Post date: [May 16, 2022, 11:33am UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/3 "2022-05-16T11:33:37Z")

</div>

Hi and thanks, @matt.mccormick. Sorry for the wall of text. In [`DeformableRegistration15.cxx`](https://itk.org/Doxygen/html/Examples_2RegistrationITKv4_2DeformableRegistration15_8cxx-example.html), `GetCoefficientImages()[k]` is used within a loop to provide the input image. How can I access that image in Python? I get an error if I try (see above). Thanks!

---

<div class="post-metadata">

### Author: ![edgar](https://discourse.itk.org/letter_avatar_proxy/v4/letter/e/b487fb/32.png) [@edgar](https://discourse.itk.org/u/edgar)
#### Post date: [May 23, 2022, 5:21pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/4 "2022-05-23T17:21:26Z")

</div>

Hi, I’m sure everyone is busy, and it’s alright. If someone has the time, I would appreciate the help. Thanks.

---

<div class="post-metadata">

### Author: ![Pranjal\_Sahu](https://discourse.itk.org/user_avatar/discourse.itk.org/pranjal_sahu/32/2698_2.png) [@Pranjal\_Sahu](https://discourse.itk.org/u/Pranjal_Sahu)
#### Post date: [May 27, 2022, 3:35pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/5 "2022-05-27T15:35:29Z")

</div>

> [@edgar](#):
>
> ```auto
> Wrong number or type of arguments for overloaded function 'itkImageToImageFilterIF3IF3_SetInput'.
> Possible C/C++ prototypes are:
> itkImageToImageFilterIF3IF3::SetInput(itkImageF3 const *)
> itkImageToImageFilterIF3IF3::SetInput(unsigned int,itkImageF3 const *)
> 
> ```

Can you please check if the data type is correct ?  
It expects float format as per the error message.

---

<div class="post-metadata">

### Author: ![Pranjal\_Sahu](https://discourse.itk.org/user_avatar/discourse.itk.org/pranjal_sahu/32/2698_2.png) [@Pranjal\_Sahu](https://discourse.itk.org/u/Pranjal_Sahu)
#### Post date: [May 27, 2022, 3:40pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/6 "2022-05-27T15:40:01Z")

</div>

> [@edgar](#):
>
> `itkImageToImageFilterIF3IF3`

Also please post a minimum end-to-end Python code to reproduce the error.

---

<div class="post-metadata">

### Author: ![edgar](https://discourse.itk.org/letter_avatar_proxy/v4/letter/e/b487fb/32.png) [@edgar](https://discourse.itk.org/u/edgar)
#### Post date: [May 29, 2022, 8:19pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/7 "2022-05-29T20:19:51Z")

</div>

About the code: sure, here it is.

```
#!/usr/bin/env python
# This code is partially based on
# DeformableRegistration15.cxx
# which holds the Apache 2.0 license (see below).
#
# Copyright 2022 edgar
# License:
#
# This program is free software: you can redistribute it
# and/or modify it under the terms of the GNU General
# Public License as published by the Free Software
# Foundation, version 3 of the License.
#
# This program is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General
# Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
# Copyright Insight Software Consortium
#
# 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
#
# http://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 sys
import itk
import numpy as np
from distutils.version import StrictVersion as VS
from scipy import ndimage as ndi
from skimage.morphology import disk
from scipy.ndimage import shift

if VS(itk.Version.GetITKVersion()) < VS("5.3.0"):
    print("ITK 5.3.0 is required.")
    sys.exit(1)

# Draw a 3D disk
side_size = 10
obj2d = disk(side_size / 2, dtype=np.uint8)
obj3d = np.asarray([disk(side_size / 2, dtype=np.uint8)
                    for idx in range(5)])
# Create 4 frames
series_length = 4
holder = np.asarray([obj3d for idx in range(series_length)])
# Move the last frame
holder[-1] = shift(holder[-1],
                   (series_length - 1, 0, 0))

fixed_image_arr = holder[0].transpose((2, 1, 0))
moving_image_arr = holder[-1].transpose((2, 1, 0))
fixed_image = itk.image_from_array(
    fixed_image_arr.astype(np.float32))
moving_image = itk.image_from_array(
    moving_image_arr.astype(np.float32))

spatial_dim = fixed_image.GetImageDimension()
fixed_image_type = type(fixed_image)
moving_image_type = type(moving_image)

origin = [0] * spatial_dim
length_per_px_ratios = [1] * spatial_dim
[dict(img).update({
    # Set origin ([0, 0, 0]); fixed_image.GetOrigin()
    "origin": origin,
    # Axial scale (length unit / pixel for each axis)
    "spacing": length_per_px_ratios,
    # Set orientation of axes; fixed_image.GetDirection()
    "direction": np.eye(spatial_dim)})
 for img in (fixed_image, moving_image)]

coord_type = itk.D
versor_type = coord_type
versor_transform_class = itk.VersorRigid3DTransform[versor_type]
rigid_transform = versor_transform_class.New()
trnfm_init_class = itk.CenteredTransformInitializer[
    # versor_transform_class,
    itk.VersorRigid3DTransform[itk.D],
    fixed_image_type,
    moving_image_type]
optimiser_class = itk.RegularStepGradientDescentOptimizer
optimiser = optimiser_class.New()
metric = itk.MattesMutualInformationImageToImageMetric[
    fixed_image_type, moving_image_type].New(
        NumberOfHistogramBins=50)
metric.ReinitializeSeed(76926294)
metric.SetUseCachingOfBSplineWeights(True)
metric.SetUseExplicitPDFDerivatives(True)
interpolator = itk.LinearInterpolateImageFunction[
    moving_image_type, coord_type].New()
registrant = itk.ImageRegistrationMethod[
    fixed_image_type, moving_image_type].New(
        Metric=metric,
        Optimizer=optimiser,
        Interpolator=interpolator,
        FixedImage=fixed_image,
        MovingImage=moving_image)

identity_transform = itk.IdentityTransform[
    coord_type, spatial_dim].New()

initialiser = trnfm_init_class.New(
    Transform=rigid_transform,
    FixedImage=fixed_image,
    MovingImage=moving_image)
initialiser.MomentsOn()
initialiser.InitializeTransform()
fixed_region = fixed_image.GetBufferedRegion()
number_of_pixels = fixed_region.GetNumberOfPixels()
registrant.SetFixedImageRegion(fixed_region)
registrant.SetInitialTransformParameters(
    rigid_transform.GetParameters())
registrant.SetTransform(rigid_transform)

translation_scale = 1 / 1000
optimiser_scales = [1.0, 1.0, 1.0,
                    translation_scale,
                    translation_scale,
                    translation_scale]
optimiser.SetScales(optimiser_scales)
optimiser.SetMaximumStepLength(0.2000)
optimiser.SetMinimumStepLength(0.0001)
optimiser.SetNumberOfIterations(200)

metric.SetNumberOfSpatialSamples(int(10000))
registrant.Update()
rigid_transform.SetParameters(registrant.GetLastTransformParameters())

affine_transform_class = itk.AffineTransform[
    coord_type, spatial_dim]
affine_transform = affine_transform_class.New(
    Center=rigid_transform.GetCenter(),
    Translation=rigid_transform.GetTranslation(),
    Matrix=rigid_transform.GetMatrix())
registrant.SetTransform(affine_transform)
registrant.SetInitialTransformParameters(
    affine_transform.GetParameters())
optimiser.SetScales([1] * 9 + [translation_scale] * 3)
optimiser.SetMaximumStepLength(0.2)
optimiser.SetMinimumStepLength(1e-4)
optimiser.SetNumberOfIterations(200)
metric.SetNumberOfSpatialSamples(int(50000))

registrant.Update()

affine_transform.SetParameters(registrant.GetLastTransformParameters())

spline_order = 3
deformable_transform_class = itk.BSplineTransform[
    coord_type, spatial_dim, spline_order]
bspline_transform_coarse = deformable_transform_class.New()
grid_nodes_1_dim_coarse = int(5)
fixed_origin = fixed_image.GetOrigin()
fixed_physical_dimensions = [fixed_image.GetSpacing()[idx] * (
    fixed_image.GetLargestPossibleRegion().GetSize()[idx] - 1)
                             for idx in range(spatial_dim)]
bspline_transform_coarse.SetTransformDomainOrigin(fixed_origin)
bspline_transform_coarse.SetTransformDomainPhysicalDimensions(
    fixed_physical_dimensions)
mesh_size = \
    bspline_transform_coarse.GetTransformDomainMeshSize()
mesh_size.Fill(grid_nodes_1_dim_coarse - spline_order)
bspline_transform_coarse.SetTransformDomainMeshSize(mesh_size)
bspline_transform_coarse.SetTransformDomainDirection(
    fixed_image.GetDirection())
number_of_bspline_param = \
    bspline_transform_coarse.GetNumberOfParameters()
optimiser.SetScales(
    [1.0 for idx in range(number_of_bspline_param)])
composite_transform_class = itk.CompositeTransform[
    coord_type, spatial_dim]
composite_transform = composite_transform_class.New()
composite_transform.AddTransform(affine_transform)
composite_transform.AddTransform(bspline_transform_coarse)
composite_transform.SetOnlyMostRecentTransformToOptimizeOn()
bspline_transform_coarse.GetParameters().Fill(1.0)
registrant.SetInitialTransformParameters(
    bspline_transform_coarse.GetParameters())
registrant.SetTransform(composite_transform)

optimiser.SetMaximumStepLength(10.0)
optimiser.SetMinimumStepLength(0.01)
optimiser.SetRelaxationFactor(0.7)
optimiser.SetNumberOfIterations(50)

metric.SetNumberOfSpatialSamples(number_of_bspline_param * 100)
registrant.Update()
final_parameters = registrant.GetLastTransformParameters()
bspline_transform_coarse.SetParameters(final_parameters)

bspline_transform_fine = deformable_transform_class.New(
    TransformDomainOrigin=fixed_origin,
    TransformDomainPhysicalDimensions=fixed_physical_dimensions,
    TransformDomainMeshSize=mesh_size,
    TransformDomainDirection=fixed_image.GetDirection())
grid_nodes_1_dim_fine = int(20)
mesh_size.Fill(grid_nodes_1_dim_fine - spline_order)
number_of_bspline_param = \
    bspline_transform_fine.GetNumberOfParameters()

interpolator_fine = itk.BSplineResampleImageFunction[
    moving_image_type, coord_type].New()

upsampler = itk.ResampleImageFilter[moving_image_type, moving_image_type].New(
    Input=bspline_transform_coarse.GetCoefficientImages(),
    Interpolator=interpolator_fine,
    Transform=identity_transform,
    Size=bspline_transform_fine.GetCoefficientImages())

upsampler = itk.resample_image_filter[moving_image_type, moving_image_type](
    Input=bspline_transform_coarse.GetCoefficientImages()[0],
    interpolator=interpolator_fine,
    transform=identity_transform,
    size=bspline_transform_fine.GetCoefficientImages())

```

About the data, the idea is to use `GetCoefficientImages` as the input (just as in the example), but let me know if this is the information that you need:

```
moving_image_type: <class 'itk.itkImagePython.itkImageF3'>
fixed_image_type: <class 'itk.itkImagePython.itkImageF3'>

```

Thank you!

---

<div class="post-metadata">

### Author: ![Pranjal\_Sahu](https://discourse.itk.org/user_avatar/discourse.itk.org/pranjal_sahu/32/2698_2.png) [@Pranjal\_Sahu](https://discourse.itk.org/u/Pranjal_Sahu)
#### Post date: [June 2, 2022, 1:28pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/8 "2022-06-02T13:28:34Z")

</div>

If I print the object using the following code,

```auto
t1 = bspline_transform_coarse.GetCoefficientImages()
print(t1)

```

I get:

```auto
<Swig Object of type 'itk::FixedArray< itk::SmartPointer< itk::Image< double,3 > >,3 > *' at 0x7f0e70fa7480>

```

which is a fixed array of image with double type. So you can’t directly pass this as input.

---

<div class="post-metadata">

### Author: ![edgar](https://discourse.itk.org/letter_avatar_proxy/v4/letter/e/b487fb/32.png) [@edgar](https://discourse.itk.org/u/edgar)
#### Post date: [June 2, 2022, 7:28pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/9 "2022-06-02T19:28:35Z")

</div>

Thanks. In [https://itk.org/Doxygen/html/Examples\_2RegistrationITKv4\_2DeformableRegistration15\_8cxx-example.html](https://itk.org/Doxygen/html/Examples_2RegistrationITKv4_2DeformableRegistration15_8cxx-example.html), they use  
`bspline_transform_coarse.GetCoefficientImages()[k]`. Is there a way to do the same with Python? How to access the k^{th} element? Is it even possible?

---

<div class="post-metadata">

### Author: ![Pranjal\_Sahu](https://discourse.itk.org/user_avatar/discourse.itk.org/pranjal_sahu/32/2698_2.png) [@Pranjal\_Sahu](https://discourse.itk.org/u/Pranjal_Sahu)
#### Post date: [June 2, 2022, 8:09pm UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/10 "2022-06-02T20:09:16Z")

</div>

> [@edgar](#):
>
> [ITK: Examples/RegistrationITKv4/DeformableRegistration15.cxx](https://itk.org/Doxygen/html/Examples_2RegistrationITKv4_2DeformableRegistration15_8cxx-example.html)

You can first get the deformation field and then upsample it and then decompose it to BSpline.

```auto
convertFilter = itk.TransformToDisplacementFieldFilter.IVF33D.New()
convertFilter.SetTransform(bsplineTransform)
convertFilter.UseReferenceImageOn()
convertFilter.SetReferenceImage(fixedImage)
convertFilter.Update()
field = convertFilter.GetOutput()
field = np.array(field)
np.save('displacement_field.npy', field)

```

Here, upsample the field and then pass it as input to the [itk::BSplineDecompositionImageFilter](https://itk.org/Doxygen/html/classitk_1_1BSplineDecompositionImageFilter.html) to create a new B-spline transform for next iteration.

I will have to check if there is a way to image from GetCoefficientImages method in Python.

---

<div class="post-metadata">

### Author: ![edgar](https://discourse.itk.org/letter_avatar_proxy/v4/letter/e/b487fb/32.png) [@edgar](https://discourse.itk.org/u/edgar)
#### Post date: [June 3, 2022, 7:52am UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/11 "2022-06-03T07:52:22Z")

</div>

> [@Pranjal\_Sahu](#):
>
> I will have to check if there is a way to image from GetCoefficientImages method in Python.

Ok, thanks.

---

<div class="post-metadata">

### Author: ![edgar](https://discourse.itk.org/letter_avatar_proxy/v4/letter/e/b487fb/32.png) [@edgar](https://discourse.itk.org/u/edgar)
#### Post date: [August 16, 2022, 9:06am UTC](https://discourse.itk.org/t/how-to-itk-resample-image-filter-with-a-bsplinetransform-with-3d-images/4987/12 "2022-08-16T09:06:57Z")

</div>

Will there be an implementation?
