BioMedIA / MIRTK

The Medical Image Registration ToolKit (MIRTK), the successor of the IRTK, contains common CMake build configuration files, core libraries, and basic command-line tools. Extension packages are hosted by the MIRTK GitHub group at
https://github.com/MIRTK
Apache License 2.0
179 stars 71 forks source link

evaluate-similarity yields unexpected results when images are on different grids #700

Closed soundray closed 4 years ago

soundray commented 4 years ago

For the appended session log, I fed two images with different grids to evaluate-similarity. The source image is read wrong, as shown by the variance and entropy being zero, both for the original command and for the command where source and target are swapped. A workaround is to force the geometry of the target image onto the source image with edit-image -- the edited image yields expected results. Expected behaviour is to yield correct output independent of the geometry of the pair (like evaluation in IRTK) or to abort with an error if the images have unequal geometry.

$ evaluate-similarity t1.nii.gz t2.nii.gz -v
Similarity of target image t1 and source image t2:

  No. of samples                = 9.8304e+06
  No. of histogram bins         = 256 x 256
  Size of histogram bins        = 13.715 x 7.7812
  Mean target intensity         = 273.35
  Mean source intensity         = 3.8906
  Target image range            = [0, 3511]
  Source image range            = [0, 1992]
  Target image variance         = 1.5348e+05
  Source image variance         = 0
  Target image entropy          = 2.6967
  Source image entropy          = 0
  Sum of squared differences    = 0.019544
  Peak signal-to-noise ratio    = 17.09
  Covariance                    = 0
  Normalized cross-correlation  = -nan
  Joint entropy                 = 2.6967
  Mutual information            = -1.7764e-14
  Normalized mutual information = 1
  Correlation ratio C(X|Y)      = 7.5788e-31
  Correlation ratio C(Y|X)      = inf
$ evaluate-similarity t2.nii.gz t1.nii.gz -v # Swapped image pair
Similarity of target image t2 and source image t1:

  No. of samples                = 9.8304e+06
  No. of histogram bins         = 256 x 256
  Size of histogram bins        = 7.7812 x 13.715
  Mean target intensity         = 193.6
  Mean source intensity         = 6.8574
  Target image range            = [0, 1992]
  Source image range            = [0, 3511]
  Target image variance         = 53588
  Source image variance         = 0
  Target image entropy          = 3.1361
  Source image entropy          = 0
  Sum of squared differences    = 0.0078
  Peak signal-to-noise ratio    = 16.156
  Covariance                    = 0
  Normalized cross-correlation  = -nan
  Joint entropy                 = 3.1361
  Mutual information            = -7.1054e-15
  Normalized mutual information = 1
  Correlation ratio C(X|Y)      = 3.7685e-31
  Correlation ratio C(Y|X)      = inf
$ edit-image t2.nii.gz t2e.nii.gz -copy-origin-orientation-spacing t1.nii.gz
$ evaluate-similarity t1.nii.gz t2e.nii.gz -v
Similarity of target image t1 and source image t2e:

  No. of samples                = 9.8304e+06
  No. of histogram bins         = 256 x 256
  Size of histogram bins        = 13.715 x 7.7812
  Mean target intensity         = 273.35
  Mean source intensity         = 193.6
  Target image range            = [0, 3511]
  Source image range            = [0, 1992]
  Target image variance         = 1.5348e+05
  Source image variance         = 53588
  Target image entropy          = 2.6967
  Source image entropy          = 3.1361
  Sum of squared differences    = 0.0076608
  Peak signal-to-noise ratio    = 21.157
  Covariance                    = 59603
  Normalized cross-correlation  = 0.43497
  Joint entropy                 = 5.4337
  Mutual information            = 0.39908
  Normalized mutual information = 1.0734
  Correlation ratio C(X|Y)      = 0.48146
  Correlation ratio C(Y|X)      = 0.50721
$ 
schuhschuh commented 4 years ago

The behavior is indeed intended. I agree it would be better to explicitly warn the user if there was no overlap between the image regions, in order to explain the output. The input should be either the same as for the registration command, together with a (intermediate) transformation, or a source image that has already been resampled on the target image grid using a given geometric transformation. By default, the program assumes -dofin to be the identity map.

I have added code to print warning messages to STDERR.

soundray commented 4 years ago

If I understand you correctly, I should expect a meaningful result if I just use the -dofin option with a sensible .dof (your "either"-case). However:

$ register t1.nii.gz t2.nii.gz -dofout t2-t1.dof.gz -model Rigid+Affine >reg-t2-t1.log
$ evaluate-similarity t1.nii.gz t2.nii.gz -dofin t2-t1.dof.gz -v
Similarity of target image t1 and source image t2:

  No. of samples                = 9.8304e+06
  No. of histogram bins         = 256 x 256
  Size of histogram bins        = 13.715 x 7.7812
  Mean target intensity         = 273.35
  Mean source intensity         = 3.8906
  Target image range            = [0, 3511]
  Source image range            = [0, 1992]
  Target image variance         = 1.5348e+05
  Source image variance         = 0
  Target image entropy          = 2.6967
  Source image entropy          = 0
  Sum of squared differences    = 0.024482
  Peak signal-to-noise ratio    = 16.112
  Covariance                    = 0
  Normalized cross-correlation  = -nan
  Joint entropy                 = 2.6967
  Mutual information            = -1.7764e-14
  Normalized mutual information = 1
  Correlation ratio C(X|Y)      = 7.5788e-31
  Correlation ratio C(Y|X)      = inf

Only if I apply the dof "offline" (your "or"-case) do I get what I need:

$ transform-image t2.nii.gz trans-t2-t1.nii.gz -dofin t2-t1.dof.gz -target t1.nii.gz
$ evaluate-similarity t1.nii.gz trans-t2-t1.nii.gz -v
Similarity of target image t1 and source image trans-t2-t1:

  No. of samples                = 9.8304e+06
  No. of histogram bins         = 256 x 256
  Size of histogram bins        = 13.715 x 7.0271
  Mean target intensity         = 273.35
  Mean source intensity         = 140.94
  Target image range            = [0, 3511]
  Source image range            = [0, 1798.9]
  Target image variance         = 1.5348e+05
  Source image variance         = 44601
  Target image entropy          = 2.6967
  Source image entropy          = 2.5187
  Sum of squared differences    = 0.0065408
  Peak signal-to-noise ratio    = 21.844
  Covariance                    = 67541
  Normalized cross-correlation  = 0.66862
  Joint entropy                 = 4.6276
  Mutual information            = 0.58786
  Normalized mutual information = 1.127
  Correlation ratio C(X|Y)      = 0.71127
  Correlation ratio C(Y|X)      = 0.70786

Have I still misunderstood?

schuhschuh commented 4 years ago

These two commands should work as expected and give the same result. I can reproduce the issue and should have a fix soon.

schuhschuh commented 4 years ago

This should be fixed by aafca02. Thanks for reporting!

The issue was that RegisteredImage instance source was initialized (i.e., source.Initialize called) before the input image was even read from disk. This originally was fine and saved some computation, but the latest version of RegisteredImage::Initialize will determine and store the min/max value of the input image and these would be used when interpolating the image (to clamp the output to the input range). As the input was not read yet, the stored min/max values were both zero. When no -dofin is given, the RegisteredImage simply copies the later on loaded image data upon RegisteredImage::Recompute. Hence, the issue was only encountered when using the -dofin option.