报错处理 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,因此我认为算是解决。

### 使用 SimpleITK 处理 NIfTI (`.nii`) 文件格式的方法 SimpleITK 是一个用于医学图像分析的强大工具包,支持多种常见的医学图像格式,其中包括 NIfTI (`*.nii` 或 `*.nii.gz`)。以下是有关如何使用 SimpleITK 来加载、保存以及处理 `.nii` 文件的具体方法。 #### 加载 `.nii` 文件 通过调用 `sitk.ReadImage()` 方法可以直接读取 `.nii` 文件并将其作为 SimpleITK 的 Image 对象返回。如果文件路径有效,则该函数能够成功执行[^2]: ```python import SimpleITK as sitk file_path = "example.nii" image = sitk.ReadImage(file_path) print(f"Loaded image size: {image.GetSize()}") # 输出图像尺寸 ``` 上述代码片段展示了如何利用 SimpleITK 将指定路径下的 `.nii` 文件加载到内存中,并打印其大小信息。 #### 解决方向余弦不正交问题 某些情况下,在尝试加载 `.nii` 文件时可能会遇到如下错误提示:“ITK only supports orthonormal direction cosines”。这是因为 ITK 和 SimpleITK 不支持非标准的方向矩阵。为了修复此问题,可以通过 NiBabel 库重新设置文件的方向参数后再进行加载操作[^1]: ```python import nibabel as nib import os def fix_cosine_problem(input_file, output_file=None): if not output_file: base_name, ext = os.path.splitext(input_file) if ext == ".gz": base_name, _ = os.path.splitext(base_name) output_file = f"{base_name}_fixed{ext}" try: image = sitk.ReadImage(input_file) # 验证是否能正常加载 except RuntimeError: print("Cosine problem detected. Attempting to fix...") img_nib = nib.load(input_file) qform = img_nib.get_qform() sform = img_nib.get_sform() if qform is None and sform is None: raise ValueError("Both QForm and SForm are missing.") new_img = nib.Nifti1Image(img_nib.dataobj, affine=qform if qform is not None else sform) nib.save(new_img, output_file) print(f"File has been fixed and saved at: {output_file}") return True return False ``` 以上代码定义了一个名为 `fix_cosine_problem` 的辅助函数来检测和修正可能存在的方向余弦问题。它接受输入文件名及其可选的目标输出位置作为参数。当发现异常情况时,程序会自动调整头文件中的变换矩阵以满足兼容性需求。 #### 存储修改后的 `.nii` 数据 完成必要的预处理之后,可以再次借助 `sitk.WriteImage()` 函数将更新过的图像对象写回到磁盘上形成新的 `.nii` 文件: ```python new_image = ... # 假设这是经过某种方式加工得到的新图像实例 output_filepath = "./processed_example.nii" if isinstance(new_image, sitk.Image): sitk.WriteImage(new_image, output_filepath) else: raise TypeError("The provided object must be a valid SimpleITK Image instance.") print(f"New processed .nii file written successfully to '{output_filepath}'.") ``` 这段示例说明了怎样把最终的结果存储下来供后续进一步研究或者分享给他人使用。 --- ###
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值