You could find some inspiration from IterativeClosestPoint1.cxx example.
Thank you so much . I will definitely look into it.
So I’m trying to convert my moving point list to the pointsets with ITK.F type and I’m getting this runtime error
TypeError: in method ‘itkPointF3___setitem__’, argument 3 of type ‘float’
so basically I’m predefining defining a list p with these parameters
PixelType = itk.F
Dimension = 3
PointSetType = itk.PointSet[PixelType, Dimension]
and then looping this list over the length of my moving points and adding those points onto this predefined list .
Is there a better and efficient way . Its just I don’t know C++ , so everything is python based .
Thanks a lot
That sounds right.
What code line triggers this?
so I have something like this
p = [] # creates an empty list
p = itk.Point[PixelType, Dimension]()
count = 0
for i in range(0,len(moving_points)):
p[i] = moving_points[i] # this line triggers it
moving points are a list of floating points with size of (70,3)
This example has a python version. You need to set each x, y and z coordinate separately to an itk.Point
. Then insert those into an itk.PointSet
.
Thank you so much . Looks like its working .
Is there a way to read the values inside it .When I open it its getting me an error of the variable not being packable .
Thanks
So when I print those points and p list I get this
So can I directly use these p points as my moving image points for b-spline ffd .
Thanks
I think you should be able to use the variable you call PointSet
directly in the registration.
So when I used that variable I’m getting this error message
Can you please provide some insights .
Thanks
You should be using PointSetToPointSetMetric, not ImageToImageMetric
family. As you are not sharing your code, I can only guess what you are doing.
Sorry my bad . This is the code I’m using
def bspline_intra_modal_registration(
fixed_image,
moving_image,
fixed_image_mask=None,
fixed_points=None,
moving_points=None,
):
registration_method = sitk.ImageRegistrationMethod()
# Determine the number of BSpline control points using the physical spacing we want for the control grid.
grid_physical_spacing = [50.0, 50.0, 50.0] # A control point every 50mm
image_physical_size = [
size * spacing
for size, spacing in zip(fixed_image.GetSize(), fixed_image.GetSpacing())
]
mesh_size = [
int(image_size / grid_spacing + 0.5)
for image_size, grid_spacing in zip(image_physical_size, grid_physical_spacing)
]
initial_transform = sitk.BSplineTransformInitializer(
image1=fixed_image, transformDomainMeshSize=mesh_size, order=3
)
registration_method.SetInitialTransform(initial_transform)
registration_method.SetMetricAsMeanSquares()
# Settings for metric sampling, usage of a mask is optional. When given a mask the sample points will be
# generated inside that region. Also, this implicitly speeds things up as the mask is smaller than the
# whole image.
registration_method.SetMetricSamplingStrategy(registration_method.RANDOM)
registration_method.SetMetricSamplingPercentage(0.01)
if fixed_image_mask:
registration_method.SetMetricFixedMask(fixed_image_mask)
# Multi-resolution framework.
registration_method.SetShrinkFactorsPerLevel(shrinkFactors=[4, 2, 1])
registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[2, 1, 0])
registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()
registration_method.SetInterpolator(sitk.sitkLinear)
registration_method.SetOptimizerAsLBFGSB(
gradientConvergenceTolerance=1e-5, numberOfIterations=100
)
# If corresponding points in the fixed and moving image are given then we display the similarity metric
# and the TRE during the registration.
if fixed_points and moving_points:
registration_method.AddCommand(
sitk.sitkStartEvent, rc.metric_and_reference_start_plot
)
registration_method.AddCommand(
sitk.sitkEndEvent, rc.metric_and_reference_end_plot
)
registration_method.AddCommand(
sitk.sitkIterationEvent,
lambda: rc.metric_and_reference_plot_values(
registration_method, fixed_points, moving_points
),
)
return registration_method.Execute(fixed_image, moving_image)
Correspondingly, you should use PointSetToPointSetRegistrationMethod, not ImageRegistrationMethod
.
Thank you so much . Really Appreciated . I will look into that .
Is there a Python version of this registration .
Its just I thought I was doing B-spline FFD image registration which had fixed and moving image , fixed mask ( which I used airway mask ) and fixed and moving points (which are the coordinates of my moving and fixed airway masks at each bifurcations ) .
Sorry for all the trouble I’m giving
Thanks
Oh, it looks like it is not exposed in Python like most of the other registration methods and metrics. Good news: adding it is not hard, see e.g. itkImageRegistrationMethod.wrap.
I just made a PR which should add required Python support:
Thank you .
Sorry , But I don’t see the PR on GitHub .
I converted it into a draft PR, because I realized that my initial attempt does not work
Oh okay . So my question about the Bspine FFD image registration is
What exactly are those fixed and moving points in this example are .
def bspline_intra_modal_registration(
fixed_image,
moving_image,
fixed_image_mask=None,
fixed_points=None,
moving_points=None,
):
registration_method = sitk.ImageRegistrationMethod()
# Determine the number of BSpline control points using the physical spacing we want for the control grid.
grid_physical_spacing = [50.0, 50.0, 50.0] # A control point every 50mm
image_physical_size = [
size * spacing
for size, spacing in zip(fixed_image.GetSize(), fixed_image.GetSpacing())
]
mesh_size = [
int(image_size / grid_spacing + 0.5)
for image_size, grid_spacing in zip(image_physical_size, grid_physical_spacing)
]
initial_transform = sitk.BSplineTransformInitializer(
image1=fixed_image, transformDomainMeshSize=mesh_size, order=3
)
registration_method.SetInitialTransform(initial_transform)
registration_method.SetMetricAsMeanSquares()
# Settings for metric sampling, usage of a mask is optional. When given a mask the sample points will be
# generated inside that region. Also, this implicitly speeds things up as the mask is smaller than the
# whole image.
registration_method.SetMetricSamplingStrategy(registration_method.RANDOM)
registration_method.SetMetricSamplingPercentage(0.01)
if fixed_image_mask:
registration_method.SetMetricFixedMask(fixed_image_mask)
# Multi-resolution framework.
registration_method.SetShrinkFactorsPerLevel(shrinkFactors=[4, 2, 1])
registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas=[2, 1, 0])
registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()
registration_method.SetInterpolator(sitk.sitkLinear)
registration_method.SetOptimizerAsLBFGSB(
gradientConvergenceTolerance=1e-5, numberOfIterations=100
)
# If corresponding points in the fixed and moving image are given then we display the similarity metric
# and the TRE during the registration.
if fixed_points and moving_points:
registration_method.AddCommand(
sitk.sitkStartEvent, rc.metric_and_reference_start_plot
)
registration_method.AddCommand(
sitk.sitkEndEvent, rc.metric_and_reference_end_plot
)
registration_method.AddCommand(
sitk.sitkIterationEvent,
lambda: rc.metric_and_reference_plot_values(
registration_method, fixed_points, moving_points
),
)
return registration_method.Execute(fixed_image, moving_image)
For me I thought I was using this approach where my fixed and moving points are fixed mask image and moving mask image bifurcation points . OR is there a way to implement this approach on my dataset .
Sorry I’m just new to registration and trying to wrap my head around it . Thanks for understanding