对象沿维度的大小?
Objects' sizes along dimension?
我有一个 3D 标签矩阵。
使用 ndimage.sum
我可以获得标记的对象大小,这对于基于体积的过滤非常有用。
我的问题是:我能否轻松获得沿每个轴的对象大小,以消除仅在一个平面上的对象,例如?
一点代码可能会更清楚...
from scipy import ndimage
labmat,n = ndimage.label(np.random.rand(30,30,30) > 0.99)
sizes = ndimage.sum(labmat.astype(bool),labmat,range(n+1))
现在有没有办法让 3D 数组在每个维度上表示它们的表面,而不是用一维来表示标记对象的体积?一个 30 维数组表示它们在每个平面中的表面也可以,但我更喜欢第一个选项。
您可以使用 ndimage.find_objects
找到每个标签的边界框。边界框由切片元组给出。例如,
data_slices = ndimage.find_objects(labmat)
# [(slice(0L, 1L, None), slice(4L, 5L, None), slice(28L, 29L, None)),
# (slice(0L, 1L, None), slice(25L, 26L, None), slice(19L, 20L, None)),
# (slice(0L, 1L, None), slice(27L, 28L, None), slice(10L, 11L, None)),
# (slice(0L, 1L, None), slice(28L, 29L, None), slice(7L, 8L, None)),
# ...
然后您可以使用
找到每个边界框的大小
sizes = np.array([[s.stop-s.start for s in object_slice]
for object_slice in data_slices])
# array([[1, 1, 1],
# [1, 1, 1],
# [1, 1, 1],
# [1, 1, 1],
# ...
并创建一个布尔掩码,对于所有 3 个维度的长度都大于 1 的每个框都为 True:
mask = (sizes > 1).all(axis=1)
使用np.flatnonzero
查找对应的索引:
idx = np.flatnonzero(mask)
您还可以使用切片 select 来自 labmat
(或原始数组)的值区域。例如,
for i in idx:
print(labmat[data_slices[i]])
import numpy as np
from scipy import ndimage
np.random.seed(2016)
labmat, n = ndimage.label(np.random.rand(30,30,30) > 0.5)
data_slices = ndimage.find_objects(labmat)
sizes = np.array([[s.stop-s.start for s in object_slice]
for object_slice in data_slices])
mask = (sizes > 1).all(axis=1)
idx = np.flatnonzero(mask)
for i in idx:
print(labmat[data_slices[i]])
我有一个 3D 标签矩阵。
使用 ndimage.sum
我可以获得标记的对象大小,这对于基于体积的过滤非常有用。
我的问题是:我能否轻松获得沿每个轴的对象大小,以消除仅在一个平面上的对象,例如?
一点代码可能会更清楚...
from scipy import ndimage
labmat,n = ndimage.label(np.random.rand(30,30,30) > 0.99)
sizes = ndimage.sum(labmat.astype(bool),labmat,range(n+1))
现在有没有办法让 3D 数组在每个维度上表示它们的表面,而不是用一维来表示标记对象的体积?一个 30 维数组表示它们在每个平面中的表面也可以,但我更喜欢第一个选项。
您可以使用 ndimage.find_objects
找到每个标签的边界框。边界框由切片元组给出。例如,
data_slices = ndimage.find_objects(labmat)
# [(slice(0L, 1L, None), slice(4L, 5L, None), slice(28L, 29L, None)),
# (slice(0L, 1L, None), slice(25L, 26L, None), slice(19L, 20L, None)),
# (slice(0L, 1L, None), slice(27L, 28L, None), slice(10L, 11L, None)),
# (slice(0L, 1L, None), slice(28L, 29L, None), slice(7L, 8L, None)),
# ...
然后您可以使用
找到每个边界框的大小sizes = np.array([[s.stop-s.start for s in object_slice]
for object_slice in data_slices])
# array([[1, 1, 1],
# [1, 1, 1],
# [1, 1, 1],
# [1, 1, 1],
# ...
并创建一个布尔掩码,对于所有 3 个维度的长度都大于 1 的每个框都为 True:
mask = (sizes > 1).all(axis=1)
使用np.flatnonzero
查找对应的索引:
idx = np.flatnonzero(mask)
您还可以使用切片 select 来自 labmat
(或原始数组)的值区域。例如,
for i in idx:
print(labmat[data_slices[i]])
import numpy as np
from scipy import ndimage
np.random.seed(2016)
labmat, n = ndimage.label(np.random.rand(30,30,30) > 0.5)
data_slices = ndimage.find_objects(labmat)
sizes = np.array([[s.stop-s.start for s in object_slice]
for object_slice in data_slices])
mask = (sizes > 1).all(axis=1)
idx = np.flatnonzero(mask)
for i in idx:
print(labmat[data_slices[i]])