# ITK vs PyTorch calculation for Mutual Information

**URL:** https://discourse.itk.org/t/itk-vs-pytorch-calculation-for-mutual-information/7365
**Category:** Beginner Questions
**Tags:** itk
**Created:** [December 30, 2024, 5:50am UTC](https://discourse.itk.org/t/itk-vs-pytorch-calculation-for-mutual-information/7365 "2024-12-30T05:50:48Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![thanuja](https://discourse.itk.org/letter_avatar_proxy/v4/letter/t/b487fb/32.png) [@thanuja](https://discourse.itk.org/u/thanuja)
#### Post date: [December 30, 2024, 5:50am UTC](https://discourse.itk.org/t/itk-vs-pytorch-calculation-for-mutual-information/7365/1 "2024-12-30T05:50:48Z")

</div>

Hi All,

I’m calculating the mutual information metric value between two 3D images using ITK and PyTorch and getting two different values for the same bin size. The sample values are (ITK and Pytorch):

1. 0.5314091942961909, 0.5432233810424805
2. 0.578950776982905, 0.46988388895988464
3. 0.576229949241947, 0.4693763554096222

Please refer below for the functions of ITK (5.3.0) and PyTorch (2.0.1) versions:

```auto
# Computes similarity between two images using ITK
def get_metric(fixed, moving):
    fixed = convert_image_type(fixed, itk.UC, itk.F)
    moving = convert_image_type(moving, itk.UC, itk.F)
    if similarity_metric == "NCC":
        metric = itk.CorrelationImageToImageMetricv4[
            fixed, moving
        ].New()
    elif similarity_metric == "MI":
        metric = itk.MattesMutualInformationImageToImageMetricv4[
            fixed, moving
        ].New()
        metric.SetNumberOfHistogramBins(no_of_bins_MI)
    elif similarity_metric == "MSE":
        metric = itk.MeanSquaresImageToImageMetricv4[
            fixed, moving
        ].New()
    transform = itk.Euler3DTransform[itk.D].New()
    interpolator = itk.LinearInterpolateImageFunction[type(
        fixed), itk.D].New()
    metric.SetFixedImage(fixed)
    metric.SetMovingImage(moving)
    metric.SetTransform(transform)
    metric.SetMovingInterpolator(interpolator)
    metric.Initialize()
    return metric

```

```auto
# Computes MI similarity between two images using PyTorch
def get_mi_metric(image_1, image_2):   
    bins = no_of_bins_MI
    joint_hist = torch.histc(image_1 * bins + image_2, bins=bins*bins, min=0, max=bins*bins-1)
    joint_hist = joint_hist.view(bins, bins)
    
    joint_prob = joint_hist / torch.sum(joint_hist)
    
    x_hist = torch.sum(joint_hist, dim=1)
    y_hist = torch.sum(joint_hist, dim=0)
    
    x_prob = x_hist / torch.sum(x_hist)
    y_prob = y_hist / torch.sum(y_hist)
    
    mutual_info = 0.0
    for i in range(bins):
        for j in range(bins):
            if joint_prob[i, j] > 0:
                mutual_info += joint_prob[i, j] * torch.log(joint_prob[i, j] / (x_prob[i] * y_prob[j] + 1e-10) + 1e-10)
    
    return -1 * mutual_info

```

Could you please point out why there is a difference between these two values?

Thank you!

---

<div class="post-metadata">

### Author: ![thanuja](https://discourse.itk.org/letter_avatar_proxy/v4/letter/t/b487fb/32.png) [@thanuja](https://discourse.itk.org/u/thanuja)
#### Post date: [January 31, 2025, 3:32am UTC](https://discourse.itk.org/t/itk-vs-pytorch-calculation-for-mutual-information/7365/2 "2025-01-31T03:32:53Z")

</div>

@dzenanz Could you please tell what equation was used for the Mattes mutual information metric? I implemented and tested many different versions of MI using PyTorch and still couldn’t get the same value as ITK.

Thanks in advance!

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [January 31, 2025, 2:35pm UTC](https://discourse.itk.org/t/itk-vs-pytorch-calculation-for-mutual-information/7365/3 "2025-01-31T14:35:05Z")

</div>

That is implemented in this file:

> <https://github.com/InsightSoftwareConsortium/ITK/blob/master/Modules/Registration/Common/include/itkMattesMutualInformationImageToImageMetric.hxx>

The formula is obscured (spread out over the file) due to multi-threading and other optimizations.

---

<div class="post-metadata">

### Author: ![dzenanz](https://discourse.itk.org/user_avatar/discourse.itk.org/dzenanz/32/1093_2.png) [@dzenanz](https://discourse.itk.org/u/dzenanz)
#### Post date: [January 31, 2025, 2:41pm UTC](https://discourse.itk.org/t/itk-vs-pytorch-calculation-for-mutual-information/7365/4 "2025-01-31T14:41:06Z")

</div>

You could also search for related discussions on this forum. E.g:

- [Search results for 'mutual information reproducibility order:latest' - ITK](https://discourse.itk.org/search?q=mutual%20information%20reproducibility%20order%3Alatest)
- [Calculating mutual information of two images](https://discourse.itk.org/t/calculating-mutual-information-of-two-images/4931)
- [Search results for 'registration randomness order:latest' - ITK](https://discourse.itk.org/search?q=registration%20randomness%20order%3Alatest)
