# Dice score and Hausdorff distance for inter-modal image registration

**URL:** https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268
**Category:** Beginner Questions
**Tags:** registration, python, simpleitk
**Created:** [October 29, 2023, 6:16am UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268 "2023-10-29T06:16:32Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![debapriya](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/bc79bd/32.png) [@debapriya](https://discourse.itk.org/u/debapriya)
#### Post date: [October 29, 2023, 6:16am UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/1 "2023-10-29T06:16:32Z")

</div>

I have 3D CT and MR images of the brain. I want to register these images and find out Dice score, Hausdorff distance, Jaccard index as measure of registration accuracy.  
I have segmented the whole brain (both CT and MR images). I have also prepared binary masks of the whole brain (both CT and MR). Samples of segmentations and masks are shown below.

![image](https://discourse.itk.org/uploads/default/original/2X/9/91d3b0bfd489f97f2ad67ec0e12c47a1b09fccd5.png) ![image](https://discourse.itk.org/uploads/default/original/2X/4/4f6cbfd4ed178e78f4a9530614f3f419ddd1c79a.png)

![image](https://discourse.itk.org/uploads/default/original/2X/6/618f9f2e7ae8682111a87a0d4988e7fd5e8bf135.png) ![image](https://discourse.itk.org/uploads/default/original/2X/f/f949d72389fdbcd8b947d1e2abca9675ddbe09c5.png)

I studied a similar registration code given in SimpleITK `notebooks/65_Registration_FFD.ipynb`. This code is for intra-modal lung registration. It uses a utility called `lung_label`, to extract the lung from the whole mask.

How can I prepare a similar label for my case?  
Is there any example code for inter-modal registration, where Dice score and Hausdorff distance are computed?

---

<div class="post-metadata">

### Author: ![debapriya](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/bc79bd/32.png) [@debapriya](https://discourse.itk.org/u/debapriya)
#### Post date: [October 30, 2023, 7:13am UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/2 "2023-10-30T07:13:24Z")

</div>

I am using my own metric for registration. So I cannot use an existing registration algorithm for the job.

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [October 30, 2023, 12:52pm UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/3 "2023-10-30T12:52:12Z")

</div>

Hello @debapriya,

Not sure what is the problem you are encountering. The computation of the segmentation measures is independent of the inter/intra modal aspect of the registration or the type of transformation estimated via registration. All that is required is the estimated transformation.

The pseudo-code for what you want to do is:

```auto
fixed_image = 
fixed_image_segmentation = 
moving_image = 
moving_image_segmentation = 
# Whatever the segmentation label of interest is. There can be multiple labels/structures in the segmentation image so identify which one we are interested in. 
# Value is likely 1 but can be any arbitrary value e.g. 42.
segmentation_label_of_interest =  

# register the images and resample the moving_image_segmentation
tx = register(fixed_image, moving_image)
moving_image_segmentation_pre_registration = sitk.Resample(moving_image_segmentation,
                                                    fixed_image_segmentation,
                                                    sitk.Transform(),
                                                    sitk.sitkNearestNeighbor)

moving_image_segmentation_post_registration = sitk.Resample(moving_image_segmentation,
                                                    fixed_image_segmentation,
                                                    tx,
                                                    sitk.sitkNearestNeighbor)

label_overlap_measures_filter = sitk.LabelOverlapMeasuresImageFilter()
label_overlap_measures_filter.Execute(fixed_image_segmentation, moving_image_segmentation_pre_registration)
print(
f"Dice coefficient before registration: {label_overlap_measures_filter.GetDiceCoefficient(segmentation_label_of_interest):.2f}"
)
label_overlap_measures_filter.Execute(fixed_image_segmentation, moving_image_segmentation_post_registration)
print(
f"Dice coefficient after registration: {label_overlap_measures_filter.GetDiceCoefficient(segmentation_label_of_interest):.2f}"
)
...

```

---

<div class="post-metadata">

### Author: ![debapriya](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/bc79bd/32.png) [@debapriya](https://discourse.itk.org/u/debapriya)
#### Post date: [October 30, 2023, 5:08pm UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/4 "2023-10-30T17:08:08Z")

</div>

Thank you @zivy for this lucid explanation. It is very helpful.

Following your instructions, I set `segmentation_label_of_interest = 100` and executed the code. I am running into the following error.

 ![image](https://discourse.itk.org/uploads/default/original/2X/2/2aa5360d5bb3bc6d10c3f8a88280623ed6d579d8.png)

My `fixed_image` size is `512, 512, 26` and `moving_image` size is `276, 384, 21`. `fixed_mask` and `moving_mask` sizes are same as `fixed_image` and `moving_image` sizes respectively.

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [October 30, 2023, 7:03pm UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/5 "2023-10-30T19:03:11Z")

</div>

Hello @debapriya,

There was an assumption in the original pseudo-code that the fixed and moving segmentations had the same metadata (origin, spacing…). This was incorrect.

We need to resample the original moving image segmentation onto the fixed image grid using the identity transform so that we can compare the fixed and moving segmentations prior to registration. The pseudo-code was updated accordingly. Please see the updated code above.

---

<div class="post-metadata">

### Author: ![debapriya](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/bc79bd/32.png) [@debapriya](https://discourse.itk.org/u/debapriya)
#### Post date: [October 31, 2023, 6:07am UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/6 "2023-10-31T06:07:48Z")

</div>

Thank you @zivy . I updated the code. Now I am getting a different error about pixel type not being supported.

 ![image](https://discourse.itk.org/uploads/default/original/2X/3/39a0d7a895afb73adab59c639276ce7be2ebdc59.png)

Code for loading data and masks is given below

```auto
#Load image

fixed_image = sitk.ReadImage("Data/M_CT.mha", sitk.sitkFloat64)
moving_image = sitk.ReadImage("Data/M_MR.mha", sitk.sitkFloat64)

# Load mask

fixed_mask = sitk.ReadImage("Data/M_CT_Mask.mha", sitk.sitkFloat64)
moving_mask = sitk.ReadImage("Data/M_MR_Mask.mha", sitk.sitkFloat64)

```

I tried with `sitkFloat32` as well. I am getting the same error.

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [October 31, 2023, 1:03pm UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/7 "2023-10-31T13:03:42Z")

</div>

Hello @debapriya,

A label image is an image with integer types (`sitkUInt8`, `sitkUInt16`…). The way the masks are read in the provided code snippet is incorrect. The easiest is to not specify the pixel type and if it is indeed a label image it will be one of the integer types:

```auto
fixed_mask = sitk.ReadImage("Data/M_CT_Mask.mha")
moving_mask = sitk.ReadImage("Data/M_MR_Mask.mha")

```

---

<div class="post-metadata">

### Author: ![debapriya](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/bc79bd/32.png) [@debapriya](https://discourse.itk.org/u/debapriya)
#### Post date: [October 31, 2023, 4:58pm UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/8 "2023-10-31T16:58:25Z")

</div>

How can I make sure that my mask is a label image?

I am using `Slicer 5.4.0` to create the mask. I am selecting `0` as `Outside fill value` and `100` as `Inside fill value`. I am choosing `Create New LabelMapVolume as...` from the dropdown.

 ![image](https://discourse.itk.org/uploads/default/original/2X/a/ace9a859ab56e18eae33c185d91d39a6b9523871.png)

I am saving the data as a `.mha` volume

![image](https://discourse.itk.org/uploads/default/original/2X/0/08fe1a1f98cd6fd33784b188e847e96426f7ebaa.png)

I am still getting the following error

 ![image](https://discourse.itk.org/uploads/default/original/2X/0/07f3df54ebb10767c50084db9a457821b9d310ad.png)

---

<div class="post-metadata">

### Author: ![zivy](https://discourse.itk.org/user_avatar/discourse.itk.org/zivy/32/1726_2.png) [@zivy](https://discourse.itk.org/u/zivy)
#### Post date: [November 2, 2023, 2:44pm UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/9 "2023-11-02T14:44:22Z")

</div>

Hello @debapriya,

I suspect you are saving it as a labelmap which is different from a label image. Pixel type of `sitkLabelUInt8` vs. `sitkUInt8` (see all pixel types [here](https://simpleitk.org/doxygen/v2_1/html/namespaceitk_1_1simple.html#ae40bd64640f4014fba1a8a872ab4df98)). Try casting to `sitkUInt8` when reading (e.g. `fixed_mask = sitk.ReadImage("Data/M_CT_Mask.mha", sitk.sitkUInt8)`).

If this doesn’t address the issue, please share a sample dataset so that we can help you resolve the issue.

---

<div class="post-metadata">

### Author: ![debapriya](https://discourse.itk.org/letter_avatar_proxy/v4/letter/d/bc79bd/32.png) [@debapriya](https://discourse.itk.org/u/debapriya)
#### Post date: [November 8, 2023, 12:03pm UTC](https://discourse.itk.org/t/dice-score-and-hausdorff-distance-for-inter-modal-image-registration/6268/10 "2023-11-08T12:03:42Z")

</div>

Casting to `sitkUInt8` solved my purpose. Thank you @zivy.
