用于标识对象的可变区域阈值 - python

时间:2014-08-08 14:54:52

标签: python arrays python-2.7 numpy

我有一个数组,其中包含一系列形状的大小和位置信息:数组为零,没有形状,数组不为零,有一个形状。不同的形状由零分隔 - 因此,如果要绘制数组中的每个点,您将看到各种形状的地图。我希望这是有道理的,如果不是这里是一个包含4种不同形状的示例数组:

np.array([[0, 0, 0, 1, 0, 0, 0],
          [0, 0, 0, 0, 0, 0, 0],
          [1, 1, 0, 0, 1, 0, 0],
          [1, 1, 0, 0, 0, 1, 1],
          [0, 0, 0, 0, 0, 1, 1],
          [3, 5, 2, 0, 0, 0, 0]])

我需要计算和识别这些形状,但我只想包含面积超过某个阈值的那些。 我希望区域阈值是该区域中最大形状区域的1/15。 (在上面的例子中,最大的区域是5。

问题是:我怎样才能找到(使用python)字段中最大形状的区域而不单独识别每个形状?

修改

为了澄清“形状”的含义,下面的代码绘制了数组的图像,显​​示了4个不同的对象:

import numpy as np
import matplotlib.pyplot as plt

a = np.array([[0, 0, 0, 1, 0, 0, 0],
              [0, 0, 0, 0, 0, 0, 0],
              [1, 1, 0, 0, 1, 0, 0],
              [1, 1, 0, 0, 0, 1, 1],
              [0, 0, 0, 0, 0, 1, 1],
              [1, 1, 1, 0, 0, 0, 0]])
ind = np.nonzero(arr)
x = ind[0]
y = ind[1]
plt.imshow(arr)
plt.show()

1 个答案:

答案 0 :(得分:1)

您可以使用scipy.ndimage.label查找数组中已连接的非零区域,然后使用scipy.ndimage.sum查找每个区域的区域:

from scipy import ndimage

labels, nshapes = ndimage.label(a)
areas = ndimage.sum(a, labels=labels, index=range(1, nshapes))

idx = np.argmax(areas)
biggest_shape = labels == (idx + 1)

在你的例子中,恰好有两个“形状”具有相同的区域:

from matplotlib import pyplot as plt

fig, (ax1, ax2, ax3) = plt.subplots(1, 3)

ax1.imshow(a, cmap=plt.cm.jet)
ax2.imshow(labels, cmap=plt.cm.jet)
ax3.imshow(biggest_shape, cmap=plt.cm.jet)

enter image description here

更新

传递给structure的{​​{1}}参数确定哪些相邻元素被视为“已连接”(请参阅​​上面链接的文档)。如果您希望对角相邻的元素被视为已连接,则可以传递3x3数组:

scipy.ndimage.label

enter image description here