Python中ROI的质心计算

2 投票
1 回答
2261 浏览
提问于 2025-04-18 17:42

我有一个Nifti文件,里面包含了一些感兴趣区域(ROIs),这个文件的大小是192 x 192 x 12的数组。我想找到整个数组的质心,以及每一片(总共12片)的质心。我正在使用

cm = join(dname, 'cardiac_roi.nii')
roi_img = nib.load(cm)
roi_data = roi_img.get_data()
CM = ndimage.measurements.center_of_mass(roi_data)

但是我遇到了这个错误:

TypeError: 'numpy.float64' object is not iterable

当我只尝试处理一片的时候,也会出现同样的情况。

CM = ndimage.measurements.center_of_mass(roi_data[:,:,1])

我该怎么解决这个问题呢?

1 个回答

2

你可以通过把这一行替换成下面的几行来解决这个问题:

CM = ndimage.measurements.center_of_mass(roi_data)

替换成:

import numpy  # Unnecessary if you've already done this.
CM = ndimage.measurements.center_of_mass(numpy.array(roi_data))

解释一下:根据你的评论,roi_data 是一个 NumPy 的 内存映射数组。而 ndimage.measurements.center_of_mass 这个函数需要的是一个普通的 NumPy 数组,也就是 ndarray 类型。理论上说,因为内存映射数组的类型是 memmap,而 memmapndarray 的一个子类,所以你原来的代码应该可以正常工作;但实际上它失败了(正如你发现的那样),解决办法就是明确地把内存映射数组转换成普通的 NumPy 数组。你的代码不工作的原因违反了 里斯科夫替换原则,这说明 NumPy 或 SciPy 中可能存在一个 bug(很可能是前者)。

查看 ndimage 的源代码后,我发现行为上的差异是因为对于一个内存映射数组 xx.sum() 的结果是另一个(零维)数组,而对于一个普通的 NumPy ndarray xx.sum() 的结果是一个标量(比如说是 numpy.float64 的一个实例)。这个 NumPy 的 bug 报告 看起来是相关的。

撰写回答