neuroanatomy / reorient

A tool for reorienting and cropping MRI data

Home Page:https://neuroanatomy.github.io/reorient

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

BUG: Interpolation bias or affine adjustment issue when reorienting LAS image

pauldmccarthy opened this issue · comments

Thank you for your feedback.

Hi again @r03ert0 and @katjaq :) I think I've found a slight issue with the way that the reorient tool resamples an image, or constructs the voxel-to-world affine, when reorienting an image with LAS voxel storage order (the MNI152 2mm standard template which comes as part of FSL has this voxel storage order).

The reorient tool appears to be invariant to the voxel-storage order of loaded images (i.e. how the voxel coordinate system axes map to the LR/AP/IS anatomical coordinate system axes), and seems to always output images with a RAS voxel storage order. Overall I think this is a very good thing, as images with non LAS/RAS voxel storage orders are a common source of registration failure, so forcing all output images to have a consistent and standard storage order will help to prevent such failures.

However, there appears to be an issue in the interpolation/resampling implemented within reorient when working with an image which originally has LAS voxel storage order (i.e. where a left-right flip is encoded into the voxel-to-world affine matrix). Steps to reproduce are outlined below.

Current behaviour

  1. Load an image with LAS voxel storage order into reorient - here is an example. It is the MNI152 2mm standard template from FSL, downsampled by a factor of ~2, to make the effect clearer.
  2. Use the Select tool to crop the image. I cropped the image using this selection box (this file has had a new line added as per #3)
  3. Save the result out to disk - here is what I get
  4. View the results in an image viewer which aligns images according to their voxel-to-world affine (e.g. FSLeyes).

Here is a screencast demonstrating the result in FSLeyes (apologies for the clunkiness). I have the original MNI152 2mm template, the downsampled version, and then the re-oriented version on top:

screencast

Expected behaviour

Version information (for bug reports)

  • Browser + version: Firefox 80.0.1
  • Your OS + version: Ubuntu 18.04

I think it's fixed now : )

There were several things. We created a series of very small nifti files, with different matrices, voxel shape, etc. I'll post some examples.

The display of the crop-box was not accurate to the pixel, the image display was using nearest neighbour interpolation only, and the size of the image was also not pixel-accurate.

Here's the result on the same downsampled image:

out

Another thing that seemed to contribute to the bias was the volume translation. Volumes resampled using reorient had by default a translation that was an integer number of voxel dimensions. In FSLEyes, moving to the (0,0,0) coordinate, for example, will put the axis cross in the middle of the voxel. The source downsampled image (MNI152...) had a different displacement. Because voxels were so big, this contributed to the "shift" effect. Here's a zoom on the previous GIF showing this:
voxel_shift

Additionally, the GIF shows the isotropic resampling of reorient compared with the original anisotropic voxels.

If the voxels of the source MNI152 volume are made to be isotropic and the translation rounded to voxel size in world space (just by changing the affine matrix), the position of the voxels and their values match perfectly, showing that the code works correctly now :)
perfect
(I used the "copper" colourmap, otherwise, there's no difference)

One more test: a small volume with 234 voxels is associated to 6 different affine matrices, representing different encodings for the voxels. For each volume the image shows that the rendering is the same as in FSLEyes (L/R radiological in FSLEyes, but neurological in Reorient). The corresponding affine matrices are displayed in each subplot.

orientation 001

This image shows that the crop result is well aligned with the original image for all 6 affine matrices. Each time the crop-box is the same. In the cases where the crop-box includes voxels outside the original nifti volume, the space is filled with 0. The cropped result is displayed using the copper colourmap (otherwise, the grey levels are exactly the same).

orientation 002

We have more test images, in particular, testing the interpolation with anisotropic voxels, but the results are similar to those from the comment 4h ago. I'll close the issue : )
Thank you @pauldmccarthy for pointing it out!

Amazing work, sorry to have caused you all this hassle!

on the contrary! thank you so much for accepting to review our code 🙏