nipy / nibabel

Python package to access a cacophony of neuro-imaging file formats
http://nipy.org/nibabel/
Other
634 stars 258 forks source link

BUG: wrong origin location in orthoview, update OrthoSlicer3D._set_position in viewers.py #1319

Open gjpcbecq opened 2 months ago

gjpcbecq commented 2 months ago

correct a bug with image.orthoview() from class nibabel.viewers.OrthoSlicer3D

There is a wrong selection of indices from original data using the inverse affine transform, leading to weird selection of voxels

This bug is also related to strange behavior with special acquisition, for example with small animal settings such as rodents where PA and IS axis are transposed (LSA system), leading to wrong location of origin (0,0,0) with image.orthoview()

For example, this small example will generate wrong localization of the referential with the main code and will result in good representation with the proposed correction:

data1 = np.random.rand(20, 20, 40)
data1[10, 10, :] = 0
data1[10, :, 30] = 0
data1[:, 10, 30] = 0
aff1 = np.array([[1, 0, 0, -10], [0, 0, 1, -30], [0, 1, 0, -10], [0, 0, 0, 1]])
nib.viewers.OrthoSlicer3D(data1, aff1)
effigies commented 2 months ago

Thanks for this! Would it be possible to get a test that clearly demonstrates the error before and is fixed after?

codecov[bot] commented 2 months ago

Codecov Report

All modified and coverable lines are covered by tests :white_check_mark:

Project coverage is 90.34%. Comparing base (64b26e1) to head (47ea032).

Additional details and impacted files ```diff @@ Coverage Diff @@ ## master #1319 +/- ## ========================================== - Coverage 92.23% 90.34% -1.90% ========================================== Files 99 99 Lines 12460 12461 +1 Branches 2557 2557 ========================================== - Hits 11493 11258 -235 - Misses 644 881 +237 + Partials 323 322 -1 ```

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

gjpcbecq commented 2 months ago

Thanks for this! Would it be possible to get a test that clearly demonstrates the error before and is fixed after?

Hi Chris, You can try this code in a module for example test_ortho.py:

import matplotlib
matplotlib.use('Qt5Agg') # or any functional backend. 
import matplotlib.pyplot as plt
import nibabel as nib
import numpy as np
data1 = np.random.rand(10, 20, 40)
data1[5, 10, :] = 0
data1[5, :, 30] = 0
data1[:, 10, 30] = 0
aff1 = np.array([[1, 0, 0, -5], [0, 0, 1, -30], [0, 1, 0, -10], [0, 0, 0, 1]])
o1 = nib.viewers.OrthoSlicer3D(data1, aff1)
o1.show()

This creates a 3D array containing random values, with more elements in the third dimension than in the others dimensions. Values for the axes of the frame of reference and origin at (5, 30, 10) are set to 0. The affine transform to the RAS system associates LR with dim 0, PA to dim 2 and IS to dim 1.

\mbox{Aff}_1 = 
\left(\begin{array}{cccc}
1 & 0 & 0 & -5 \\
0 & 0 & 1 & -30 \\
0 & 1 & 0 & -10 \\
0 & 0 & 0 & 1 \end{array}\right)

using OrthoSlicer3D the referential in green should override the black lines in the volume. The visual result of the use of this code is given in Fig.1 : a) with the initial version of the code, the green lines are not aligned with the black lines in the volume. b) with the proposed correction, the green lines are aligned with the black lines in the volume.

Fig.1

Fig.1

It seems to have other bugs in the OrthoSlicer3D that I try to fix. This will be proposed in other pull requests.