SuperElastix / SimpleElastix

Multi-lingual medical image registration library
http://simpleelastix.github.io
Apache License 2.0
509 stars 149 forks source link

How to solve problem with scale/size differences when registering images #437

Closed MMdeB closed 2 years ago

MMdeB commented 3 years ago

Hi, I'm trying to register two segmentations of proximal femurs, but due to image size differences (and maybe due to a different cut off point), elastix has problems with registering the images.

I am using a similarity transform to also take into account the scaling. Since the images aren't the same size, I have resampled the movingImage to fit the fixedImage, but the movingImage segmentation is much smaller than the fixedImage segmentation.

Does anyone know a (simple?) solution for this? Thanks in advance!

Image: Elastix

Code:

parameterMap = sitk.GetDefaultParameterMap('rigid')
parameterMap['Transform'] = ['SimilarityTransform'] # Scaling is also applied
parameterMap['AutomaticScalesEstimation'] = ['true']

elastixImageFilter = sitk.ElastixImageFilter()
elastixImageFilter.SetFixedImage(fixedImage_box)

movingImage_box = sitk.Resample(projection_box, fixedImage_box)
elastixImageFilter.SetMovingImage(movingImage_box)

elastixImageFilter.SetParameterMap(parameterMap)
elastixImageFilter.LogToConsoleOn() 
elastixImageFilter.Execute()

resultImage = elastixImageFilter.GetResultImage()
transformParameterMap = elastixImageFilter.GetTransformParameterMap()
NHPatterson commented 3 years ago

Your images hopefully have a pixel resolution (i.e., 1 unit/px) associated with it. ITK uses the physical spacing of the image to do most calculations. elastix uses this information, so essentially a pixel at index [2,2] in an image with resolution of 1.5x1.5mm would be at 3x3mm. elastix will compare values to develop registration based on their position in physical space rather than pixel index space. So if you know this information your images shouldn't need to be scaled by the transformation beyond minor changes. You can set this manually:

moving_im.SetSpacing((1.0,1.0))
fixed_im.SetSpacing((2.0,2.0))
MMdeB commented 3 years ago

Thank you, that works! Do you also have a solution for the fact that the moving femur is much longer (in shape) than the fixed femur? Due to this, the registration is sometimes not that good. I now solved this by just increasing the size of the fixed image by adding padded 0's at the bottom, but I don't know if a better solution is available.

NHPatterson commented 2 years ago

You could try adding a binary mask where pixels > 0 are foreground and pixels = 0 are background. The registration will then only pull pixels from within the masked area to develop the alignment, which can help. Just make sure it has the same origin, spacing and size as your image. Here is a nice primer on SimpleITK images and how to get and set this info: https://simpleitk.org/SimpleITK-Notebooks/01_Image_Basics.html

The other thing to look into is AutomaticTransformInitialization in your registration parameters. Check out the elastix manual for a bit on this: https://usermanual.wiki/Document/elastix490manual.1389615963/html

MMdeB commented 2 years ago

Thank you for answering!

I am (now) already using the AutomaticTransformInitialization, that seems to help a bit. The addition of a mask didn't really do anything, probably since the input images are already binary images and sort of boxed to the region of interest.

However, I guess I'm quite content with the results of my solution so I will just keep this approach. There probably isn't a solution that solves everything.