Problem by registration of an MRI Head image and an CT Head Image

Hello,

I am new to image registration and I want to register an MRI Head Image with a CT image.

I began with the example from this Topic to understand how image registration is working in SITK:

But when I applied the code on my MRI and CT images the result look like the input image.
As an input(fixed image) I chose the MRI image and the moving image is the CT image. Both images have the same size(512x512).
Here is my fixed image:

Here ist the moving image:

And here is the result:


def multires_registration(fixed_image, moving_image, initial_transform):
        
    registration_method = sitk.ImageRegistrationMethod()
    registration_method.SetInterpolator(sitk.sitkBSpline)
    registration_method.SetMetricAsMattesMutualInformation(numberOfHistogramBins=50)
    registration_method.SetMetricSamplingStrategy(registration_method.RANDOM)
    registration_method.SetMetricSamplingPercentage(0.01)
    registration_method.SetOptimizerAsGradientDescent(learningRate=0.5, numberOfIterations=100, convergenceMinimumValue=1e-6, convergenceWindowSize=10)
    registration_method.SetOptimizerScalesFromPhysicalShift() 
    registration_method.SetShrinkFactorsPerLevel(shrinkFactors = [2,1]) 
    registration_method.SetSmoothingSigmasPerLevel(smoothingSigmas = [1,0]) 
    registration_method.SmoothingSigmasAreSpecifiedInPhysicalUnitsOn()

    optimized_transform = sitk.AffineTransform(2)
    registration_method.SetMovingInitialTransform(initial_transform)   
    registration_method.SetInitialTransform(optimized_transform, inPlace=False)

    #registration_method.AddCommand(sitk.sitkStartEvent, registration_callbacks.metric_start_plot)
    #registration_method.AddCommand(sitk.sitkEndEvent, registration_callbacks.metric_end_plot)
    #registration_method.AddCommand(sitk.sitkMultiResolutionIterationEvent, registration_callbacks.metric_update_multires_iterations) 
    #registration_method.AddCommand(sitk.sitkIterationEvent, lambda: registration_callbacks.metric_plot_values(registration_method))

    optimized_transform = registration_method.Execute(fixed_image, moving_image)
        
    print('Final metric value: {0}'.format(registration_method.GetMetricValue()))
    print('Optimizer\'s stopping condition, {0}'.format(registration_method.GetOptimizerStopConditionDescription()))
    print('Optimized Transform from Multires:')
    print(optimized_transform)

    return (optimized_transform)
sitk.Show(resample_Atlas_Image2, 'fixed')
sitk.Show(phantom_image2, 'moving')
sitk.Show(sitk.Resample(phantom_image2, resample_Atlas_Image2, sitk.Transform()), 'identity transform')

# Centered 2D affine transform and show the resampled moving_image using this transform.
registration_transform = sitk.CenteredTransformInitializer(resample_Atlas_Image2, 
                                                      phantom_image2, 
                                                      sitk.AffineTransform(2), 
                                                      sitk.CenteredTransformInitializerFilter.GEOMETRY)
sitk.Show(sitk.Resample(phantom_image2, resample_Atlas_Image2, registration_transform), 'initial affine transform')


# Register using 2D affine initial transform that is overwritten
# and show the resampled moving_image using this transform.
multires_registration(resample_Atlas_Image2, phantom_image2, registration_transform)
sitk.Show(sitk.Resample(phantom_image2, resample_Atlas_Image2, registration_transform), 'final affine transform')


Could anybody help me with this?
Thank you very much!

Hello @sunshine123,

Not sure what is the expectation that isn’t fulfilled. Does the registration converge? What was the optimizer’s stopping condition? Is the final transformation the identity and the expectation is that it be something else?

The input images are a bit strange. It looks like the moving image is not the original, but a resampling of the original. Also, the 2D slices don’t match in terms of the anatomical structures, they belong to different parts of the head so no matter what alignment is obtained it isn’t a correct one.

Steps to debug:

  1. Read the fundamental concepts and registration overview.
  2. Confirm that the inputs make sense.
  3. Run a simpler registration, without the multi-resolution structure, and see that it converges to something reasonable.

Hello zivy,

My idea was that I want to register different CT datasets to one MRI reference image so that every CT image has the same orientation as the MRI image. (I want that the Nose of all CT-head images is always pointing up in anterior direction)
My expectation was that the bone structures of the nose are pointing up in the anterior direction.

In general, my problem is that I have many different CT datasets where the head can be tilted and have a different orientation. Now I want to compare these datasets and for this, all CT images should have the same orientation.
I had the idea to use an MRI Atlas of the brain and register the bones of the MRI atlas with the bones of the different CT datasets, so that every CT-dataset has the same orientation as the MRI atlas.
DO you have any idea/tips on how I can register different CT datasets to one MRI reference dataset?

Thank you so much. I will read the docs and search for a solution.

Hello @sunshine123,

If the CTs are in DICOM format and the Patient Position tag is correct, then just reading the image should allow you to orient it correctly. If the issue is the head being titled, then why not select one CT which is in the desired orientation and register all others to it? There doesn’t seem to be a need for MR here.

Also, the images should be dealt with using their native dimensionality, a single 3D volume and not a collection of 2D slices.

1 Like

Hello zivy,

yes, the CTs are in DICOM. I already thought about using a CT image. But I would like to have an official Atlas Dataset as a Reference Image (BIC - The McConnell Brain Imaging Centre: ICBM 152 N Lin 2009). And I don’t found yet an Atlas Head CT dataset. So I had the idea of using an MRI Atlas. But I think a CT Atlas would be the better solution.

Do you have maybe an example of how I can use the DICOM tag Patient Position in the registration process or in which line I can use it?

Thank you so much for your help.

Read the DICOM series as a 3D image, that will handle the Z position implicitly during registration.

ok thank you so much. But I need the DICOM header of the fixed and moving image right?

Take a look at the example. If you follow this pattern, the resulting fixed and moving images should have all the relevant metadata from the DICOM header.

Perfect Thank you so much for your help and the example!! I will try now to solve my problems and get hopefully a proper registration result.