How to co-register mask on neuroimage generated from RTStruct dicom file?

Dear Simple ITK Team,

We have two DICOM series and two RTSTRUCT masks which are converted into Nifti files. The original dimension of the nifti files are (256, 256, 216). We are trying to do registration and resampling to a new dimension (240, 240, 155) using Simple ITK library. When we are doing registration and resampling of the original nifti file into the new dimension (240, 240, 155), the masks are not matching with the tumor. There is mismatch of mask with the tumor image. The mask started 15 slices ahead than it appears in real tumor image.

When we are doing only resampling without registration using Simple ITK the generated mask and tumor in the images are matching.

Why we see such a discrepancy? Are we doing something wrong.

Your guidance will be highly appreciated.

Best regards,
Sunita

Hello @Sunita_Patel,

If I understand correctly, there are two images and their corresponding segmentations: fixed_image, fixed_image_segmentation, moving_image, moving_image_segmentation

You then perform a registration:

tx = register(fixed_image, moving_image)

The transform tx maps points from the fixed_image coordinate system to the moving_image coordinate system. We can use it to resample moving_image_segmentation onto the fixed_image grid:

# use nearest neighbor interpolation so we don't introduce labels that weren't in the original data
moving_image_segmentation_resampled = sitk.Resample(moving_image_segmentation, fixed_image, tx, sitk.sitkNearestNeighbor) 

If we want to resample the fixed_image_segmentation onto the moving_image grid we need to invert the transformation, if it is a global transformation call GetInverse, otherwise it is slightly more complicated, see this notebook:

tx_inverted = tx.GetInverse()
fixed_image_segmentation_resampled = sitk.Resample(fixed_image_segmentation, moving_image, tx_inverted, sitk.sitkNearestNeighbor)
1 Like

Hi Zivy,

We tried resampling the way you suggested but got empty mask. We have five nii files to perform the task.

SRI (240, 240, 155)
T1C_img (256, 256, 216), T1C_mask (256, 256, 216)
Flair_img (256, 256, 216), Flair_mask (256, 256, 216)

step 1: We are doing registration and resampling of T1C_img (moving) with SRI (fixed) to obtained similar dimension as SRI.

step 2: Registration and resampling of T1C_img (fixed, 240,240,155) with Flair_img (moving, 256, 256, 216)

step 3: Resampling of T1C_img (fixed, 240, 240, 155) with T1C_mask (moving, 256, 256, 216) using transform map obtained from step 1.

step 4: Resampling of Flair_jmg (fixed, 240, 240, 155) with Flair_mask (moving, 256, 256, 216) using transform map obtained from step 2.

It is generating the resampled T1C_mask and Flair_mask of 240,240,155 dimension but these are essentially empty masks.

Pls suggest where we are doing wrong.

Would you like to go through the code?

Thank you so much Zivy for your guidance.
Sunita

Hi Zivy,

Could you pls guide on how to do registration and resampling of image with mask. I followed your suggestions but got empty mask.

Awaiting your reply.

Best regards,
Sunita

Hello @Sunita_Patel,

If I understand your goal, you would like to transform all the information to be coincident with the spatial grid of the SRI image:

# register sri and t1c image
tx_sri_t1c = register(fixed_image=sri, moving_image=t1c_image)

# register sri and flair image
tx_sri_flair = register(fixed_image=sri, moving_image=flair_image)

# if for some reason you have to register the t1c to flair and can't do the sri to flair directly you can obtain it as below
#tx_t1c_flair = register(fixed_image=t1c_image, moving_image=flair_image)
#tx_sri_flair = sitk.CompositeTransform([tx_t1c_flair, tx_sri_t1c])

t1c_image_resampled = sitk.Resample(t1c_image, sri, tx_sri_t1c )
t1c_mask_resampled = sitk.Resample(t1c_mask, sri, tx_sri_t1c, sitk.sitkNearestNeighbor)

flair_image_resampled = sitk.Resample(flair_image, sri, tx_sri_flair )
flair_mask_resampled = sitk.Resample(flair_mask, sri, tx_sri_flair, sitk.sitkNearestNeighbor)