报错处理 ITK only supports orthonormal direction cosines. No orthonormal definition found

在使用SimpleITK处理MRI医学图像数据的时候遇到了以下问题:

  File "d:\PythonProgramme\GenerateDatasetTxt\xx.py", line 12, in <module>
    img = sitk.ReadImage("0000264276/T2.nii.gz")
  File "D:\Program Files\Anaconda3\envs\simpleitk\lib\site-packages\SimpleITK\extra.py", line 346, in ReadImage
    return reader.Execute()
  File "D:\Program Files\Anaconda3\envs\simpleitk\lib\site-packages\SimpleITK\SimpleITK.py", line 8015, in Execute
    return _SimpleITK.ImageFileReader_Execute(self)
RuntimeError: Exception thrown in SimpleITK ImageFileReader_Execute: C:\Miniconda\envs\bld\conda-bld\work\b\ITK\Modules\IO\NIFTI\src\itkNiftiImageIO.cxx:1980:
ITK ERROR: ITK only supports orthonormal direction cosines.  No orthonormal definition found!

简单翻译过来是 “ITK只支持标准正交方向。没有找到标准正交定义!”,这是一个发生在读取数据的错误,直接第一步扼杀你想处理数据的欲望。

这里先说一下解决方案,

方案一:
SimpleITK的版本转换至2.0.2
但如果你使用ANTsPy这种内置ITK的库对数据进行处理,就没办法通过切换版本解决了。

方案二:
使用nibabel库,读取nii数据的qform信息和sform信息,然后再将这些信息写回数据,并保存一份新的数据,然后就可以对新保存的数据进行SimpleITKANTsPy的读取了。
以下是处理代码,非常简单,甚至有点傻。

import nibabel as nib
img = nib.load("xxxxx.nii.gz")
qform = img.get_qform()
img.set_qform(qform)
sfrom = img.get_sform()
img.set_sform(sfrom)
nib.save(img, "xxxxx.nii.gz")

方案一是网上给出的一个解决方案,而方案二由本人自己摸索,这里简单的描述一下方案二的摸索过程,并不高深。

首先

首先一个最直接想法就是:找到源码的报错位置C:\Miniconda\envs\bld\conda-bld\work\b\ITK\Modules\IO\NIFTI\src\itkNiftiImageIO.cxx直接把这个相关报错的代码删了
可惜我的电脑不存在这个路劲,而且是cxx文件,大概是c语言的代码,经过cython还是什么其他的过程编译成了无法修改代码的形式。

然后

那就只好去网上的官方github上看看源码,看看触发错误的条件,将数据处理成不会触发错误的形式。
这是源码网址,相关报错代码在第1980
在这里插入图片描述
往上看,从1789行到1981行的代码都与报错代码处于同一个函数NiftiImageIO::SetImageIOOrientationFromNIfTI
在这里插入图片描述
妄想看懂这么多代码不现实,本人水平有限,但可以确定的是函数内有大量关于qformsform的判断语句,我截选了一些,如下所示(觉得不适可以忽视):
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总的来说,如果这些判断一个都不符合,就无法跳出该函数从而“触碰”到最后的报错代码。

再者

那么qformsform是啥,这里出于经验上判断,去使用ITK-SNAP直接查看数据的metadata
在这里插入图片描述
可以发现qform的信息有点异常,NIFTI_XFORM_UNKNOWN正好出现在源码的判断中。
依旧是直接想法,把这个信息改了。

最后

因为SimpleITK无法读取,这里借助nibabel 库,去官方文档查阅一下是否有修改的函数。
这是官方文档:https://nipy.org/nibabel/reference/nibabel.nifti1.html
在这里插入图片描述

在这里插入图片描述

好耶,有修改的函数,可以直接设置参数codeqform_codesform_code替换成了非0值,也就是非NIFTI_XFORM_UNKNOWN。不过红色方框的自适应设置貌似更好,但需要接收一个affine参数。
那很好办,那原本affine是什么,就设置成什么就行了,毕竟目的只是修改qform_codesform_code

import nibabel as nib
img = nib.load("xxxxx.nii.gz")
qform = img.get_qform()
img.set_qform(qform)
sfrom = img.get_sform()
img.set_sform(sfrom)
nib.save(img, "xxxxx.nii.gz")

在这里插入图片描述
再新保存文件的metadata,果然修改成了希望的效果,随后使用SimpleITKANTsPy就可以顺利读取了。
后续N4矫正,配准都没有报错,效果也ok,因此我认为算是解决。

  • 48
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值