对象'尺寸沿尺寸?

时间:2016-03-24 12:57:48

标签: python image-processing scipy ndimage

我有一个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数组表示每个维度中的表面,而不是表示标记对象体积的1维吗?表示每个平面上的表面的30-D数组也可以,但我更喜欢第一个选项。

1 个答案:

答案 0 :(得分:2)

您可以使用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)

您还可以使用切片从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]])