Elastix masking registration

Hi all,

I am using Elastix to register two breast CTs. I have cropped volume to proper size and built masks to each volume. But the registration still failed indicating that “Description: itk::ERROR: AdvancedMattesMutualInformationMetric(00000000037346C0): Too many samples map outside moving image buffer: 473 / 2048”. And I am not sure about the error log messages (shown below). Could you give some advice? Your help is highly appreciated!

Crayon

Log

bool __cdecl qSlicerSubjectHierarchyFolderPlugin::resolveHierarchies(void) : Unable to find subject hierarchy item for hierarchy node AnnotationHierarchy_1
bool __cdecl qSlicerSubjectHierarchyFolderPlugin::resolveHierarchies(void) : Unable to find subject hierarchy item for hierarchy node AnnotationHierarchy Copy
bool __cdecl qSlicerSubjectHierarchyFolderPlugin::resolveHierarchies(void) : Unable to find subject hierarchy item for hierarchy node AnnotationHierarchy_1
bool __cdecl qSlicerSubjectHierarchyFolderPlugin::resolveHierarchies(void) : Unable to find subject hierarchy item for hierarchy node AnnotationHierarchy Copy
Traceback (most recent call last):
File “C:/Users/Administrator/AppData/Roaming/NA-MIC/Extensions-28431/SlicerElastix/lib/Slicer-4.11/qt-scripted-modules/Elastix.py”, line 335, in onApplyButton
forceDisplacementFieldOutputTransform = self.forceDisplacementFieldOutputChecbox.checked)
File “C:/Users/Administrator/AppData/Roaming/NA-MIC/Extensions-28431/SlicerElastix/lib/Slicer-4.11/qt-scripted-modules/Elastix.py”, line 779, in registerVolumes
self.logProcessOutput(ep)
File “C:/Users/Administrator/AppData/Roaming/NA-MIC/Extensions-28431/SlicerElastix/lib/Slicer-4.11/qt-scripted-modules/Elastix.py”, line 719, in logProcessOutput
raise subprocess.CalledProcessError(return_code, “elastix”)
subprocess.CalledProcessError: Command ‘elastix’ returned non-zero exit status 1.

01
02

This is probably the most common cause of early registration failures and discussed exhaustively in ITK and Elastix forums.

To give a short summary: The error occurs when random point sampling fails. It may happen if input images do not overlap enough; or if masked region is much smaller than the image. I assume your images are already pre-aligned, so most likely you have problems because of the small mask. There may be strategies to make the sampler more tolerant to small masked regions (force it to try more samples), but the most efficient solution is to crop your image so that it is not much larger than the masked area.

1 Like

Hi all,

I am a bit confused about the ErodeMask in Elastix parameters setting. What’s the difference between “false” (serves as region of interest) and “true” (indicates which pixels are valid)? Shown below.

description

// If you use a mask, this option is important.
// If the mask serves as region of interest, set it to false.
// If the mask indicates which pixels are valid, then set it to true.
// If you do not use a mask, the option doesn’t matter.
(ErodeMask “false”)

I need to register two images which have noncorresponding region. So I want to try the mask function. And I have made labelmap volume (outside noncorresponding region be 1 and inside be 0) both in moving and fixed images. I want to use them as mask but don’t know which setting is proper.

Does anyone know about the difference? Hope for some suggestions. Thanks a lot!

Crayon

From the description, my understanding is that you need to set ErodeMask to false if zero mask regions should be ignored.

It is recommended to crop input images before registration so that they approximately covert the same region. If you don’t do it then computation time and chance that registration does not converge to the correct solution may increase significantly.

Masking is mainly for setting non-rectangular shaped region of interest (mask out a tool in an intra-operative image, mask out a removed tumor in a post-operative image, etc).

Thanks for your reply. Sorry but I am still stuck in setting the mask related to my problem.

Left is the fixed image and I only want to focus on the breast ROI which needs to subtract (tumor+1) region for tumor resection. I need to know how the rest of the breast tissue move and determine the location of contour of tumor+2(or further) in moving image through registration. Right is the moving image. Doctors have already contoured the removed tumor region and breast ROI (although not exactly the same range as in fixed image).

I want to set the breast-(tumor+1) as fixed mask (=1) and parameter file “ErodeFixedMask false”. But I am not sure about the moving mask and the ErodeMovingMask setting.

I have tried setting breast-tumorbed (tumorbed means removed tumor region) and whole-tumorbed (which just maskout the noncorresponding tumorbed region in whole moving image) to mask (=1). And (1)when I set breast-tumorbed to mask=1, both ErodeMovingMask setting (true or false) run in error. [Description: itk::ERROR: AdvancedMattesMutualInformationMetric(00000000037437E0): Too many samples map outside moving image buffer: 0 / 34491] (2)when I set whole-tumorbed to mask=1, both setting can run without error. But “ErodeFixedMask false” setting seems not to consider my moving mask (the log file indicates that “Setting the moving masks took: 0 ms”).

Now I can run with fixed mask=breast-(tumor+1) (=1) and “ErodeFixedMask false”; moving mask=whole-tumorbed (=1) and “ErodeMovingMask true”. And I just don’t know the difference, especially the “true” setting. How does it consider the mask region?

I have looked through the elastix manual 5.4 Masks but still have no idea. The details are shown below.

Description

Sometimes you are specifically interested in aligning only a part of the image. A possibility to focus on this
part is to crop the image. Cropping, however, restricts the region of interest (ROI) to be a square (2D) or
cube (3D) only. If you need an irregular shaped ROI, you can use masks. A mask is a binary image, filled
with 0’s and 1’s. If you use a mask, you only perform registration on the part of the image that is within
the masks, i.e. where the mask has 1’s.
You can/should use a mask
• when your image contains an artificial edge that has no real meaning. The registration might be
tempted to align these artificial edges, thereby neglecting the meaningful edges. The conic beam edge
in ultrasound images is an example of such an artificial edge.
• when the image contains structures in the neighbourhood of your ROI that may influence the registration
within your ROI. This is for example the case when matching lung data. Usually, you are
interested in the lungs, and not if the rib cage is well aligned. However, the ribs are structures that
for example in CT can have a strong influence on the similarity metric, especially if you use the MSD
metric. In that case, the rib cage may be well aligned at the cost of vessels structures near the border
of the lung with the rib cage. In this case it will help you if you use a dilated lung segmentation as a
mask.
Masks can be used both for the fixed and the moving image. A fixed image mask is sufficient to focus
the registration on a ROI, since samples are drawn from the fixed image. You only want to use a mask for
the moving image when your moving image contains nonsense grey values near the ROI.
In case you are using a mask to prevent bad karma from an artificial edge, you also need to set the
parameter:
(ErodeMask “true”)
If not, then when performing multi-resolution, information from the artificial edge will flow into you ROI
due to the smoothing step. In case the edge around your ROI is meaningful, e.g. in the lung example, you
should set it to false, because this edge will help to guide the registration.
A common exception that elastix throws when drawing samples is: “Could not find enough image
samples within reasonable time. Probably the mask is too small.” The probable cause for this is that your
fixed image mask is too small. See the FAQ for more information.

Do you have any suggestions about my case? Your help is highly appreciated.

Crayon

I have looked through the Elastix FAQ about the common cause of registration failures (for example “Too many samples map outside moving image buffer”). I think the error mentioned above is mainly caused by not overlapping enough.

But I wonder if I can run three kinds of registration in one time (set rigid & affine & b-spline registration within one parameter file). Am I supposed to run rigid/affine registration and also crop in advance? The reason that I don’t want to register pre-aligned moving image to fixed image is that I need to double check the contour which is used for mask in pre-aligned moving image (there may be some inconsistence after transformation and resampling). So what I try now is to set proper mask both in fixed and moving image and run the parameter file in one time.

Is there anything unreasonable? How can I improve my registration? Hope for some advice. Thank you very much.

Crayon

Yes, you can define multiple stages in your ParameterSetDatabase.xml, each defined by a separate parameter file.

I would try cropping and manual rigid alignment. You may find it is easier to do manual alignment by identifying pairs of matching anatomical landmarks and computing transform using Fiducial Registration Wizard in SlicerIGT extension. You may also try warping transform of Fiducial Registration Wizard module to register the deformed breast, just to get an approximate idea about the complexity of the displacement field.

Breast registration is known to be a hard problem because there can be a lot of displacement and deformation. You may get ideas for the registration from parameter sets and publications listed at http://elastix.bigr.nl/wiki/index.php/Parameter_file_database.

Thank you for your reply. I have tried Fiducial registration wizard but I wonder how to computes TRE (as RMS of the distance between fixed points and transformed moving points) using the transform computed by Elastix? Not just rigid/similarity/warping transform as the module provided? I couldn’t find the settings.
I have defined 17 pairs of corresponding points both in fixed and moving image. The pictures are shown below. Hope for some advice.
Besides, could you please post some links of Elastix forum? Thanks a lot!

Crayon

post
post2

The error that Fiducial registration wizard displays is the residual error and is computed as the RMS of the distances between each fixed point and corresponding transformed moving point.

Landmark registration (by Fiducial registration wizard, etc.) is an alternative to intensity-based registration (by Elastix, etc.). You use one or the other, or sometimes you do an approximate rigid landmark registration to prealign images before intensity-based registration.

https://groups.google.com/forum/#!forum/elastix-imageregistration

Thanks for your explanation. I have tried Fiducial registration wizard (warping transform) to get an approximate prealignment of specific points before intensity-based registration (by Elastix) and indeed got a better result. But after intensity-based registration, the pre-aligned points (done by fiducial registration) have been pulled away again. Now I want to try a metric “CorrespondingPointsEuclideanDistanceMetric” which help minimize the distance of two point sets with known correspondence (the explanation is attached in the bottom).

I have searched the elastix forum and found the source code links. Now I have annotated 50 pairs of corresponding points in Markup module. I wonder how to specify them as elastix input? Something like the mask input?

Could you give some suggestions? Thank a lot!

Crayon

If you want to use landmark registration for initial alignment, then do not use warping transform, just rigid transform. Warping would provide the full registration (you don’t need to do any additional intensity-based image registration).

If these landmarks are accurate and reliable enough then probably you can register the images based on these landmarks alone (no need for Elastix).

If you still want to use combined landmark+intensity-based registration in Elastix then you need to slightly modify SlicerElastix Python scripts to pass markup fiducial point coordinates to Elastix. Earlier @stephan made a try to implement this - see this pull request. You can try and test and update this pull request as needed and let us know how it works.