ITADN

`nibabel.orientations.aff2axcodes` potentially returns incorrect results

#1460Closeddkuegler 创建于 2026-02-02
D
dkueglercommented
Hello, I am using `aff2axcodes` to determine the `axcodes` of an affine matrix and the results are a bit convoluted. Specifically, this is about affine matrices, that are rotated around 45 degrees in multiple directions. I do not even know what the "correct" results really should be... Let us consider the following affine matrix: ```python affine = \ [[-0.585182553995787, 0.5048269789762401, -0.6345952251606463, -2.218487624719689], [-0.5327455539210799, 0.35065247835655966, 0.7702110192666194, 2.028722778552794], [-0.6113456904863974, -0.7887918361140193, -0.06374861569935834, 4.227025896592773], [0.0, 0.0, 0.0, 1.0]] ``` This matrix is orthonormal and valid (generated with `scipy.spatial.transform.Rotation.from_rotvec().as_matrix()`): ```python np.linalg.inv(affine[:3,:3]) - affine[:3, :3].T # test for orthonormal, approx zero # [[ 2.22044605e-16 3.33066907e-16 1.11022302e-16], [-3.33066907e-16 -2.22044605e-16 2.22044605e-16], [ 3.33066907e-16 -5.55111512e-16 1.66533454e-16]] np.linalg.norm(affine[:3,:3], axis=0) , np.linalg.norm(affine[:3,:3], axis=1) # test for length of vectors: ([1. 1. 1.], [1. 1. 1.]) ``` an even more extreme affine is ```python affine = \ [[0.14794184343060812, 0.4876343794531119, -0.6167057020473639, -0.38513162667728795], [0.5617554027693318, -0.5045939256658585, -0.26422686774925774, -0.13797634685442106], [0.5500400698329341, 0.38418443768129973, 0.4357272534759381, 0.652584993353186], [0.0, 0.0, 0.0, 1.0]] # scale factors are 0.8, 0.8, 0.8 ``` which following this paradigm is either `'asl'` or `'ars'` --> the second vector may be least aligned with dimension 3, but nonetheless, vectors 1 and 3 are more aligned with the other two directions still. Running `nibabel.orientations.aff2axcodes`: ```python "".join(nib.orientations.aff2axcodes(affine, ("lr", "pa", "is"))) # 'ira' ``` The problem here is, that it really should be `'lia'`!, why: Well, instead of going through the list in `axis=2` direction, the algorithm should go by largest absolute value (technically for normalized column vectors, but column vectors are normalized here). In reality, the issue traces back to `nibabel.orientations.io_orientation`, where the first, second and third direction are identified by the maximum absolute value. Instead, maybe we should consider going by largest absolute value first. I know that in practice, this all is a bit of an edge case, nonetheless, it is currently breaking one of my test cases.
关闭于 2026-02-05 2 条评论