用于识别对象的变量面积阈值 - python
我有一个数组,这个数组里包含了一系列形状的大小和位置的信息:数组中为零的地方没有形状,而非零的地方则有形状。不同的形状之间用零隔开,所以如果你把数组里的每个点都画出来,就能看到各种形状的地图。希望这样解释能让你明白,如果不明白的话,这里有一个包含四个不同形状的示例数组:
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找到场中最大形状的面积,而不需要逐个识别每个形状呢?
编辑
为了更清楚地说明我所说的“形状”,以下代码会绘制出数组的图像,显示出四个不同的物体:
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 个回答
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)
更新
传给 scipy.ndimage.label
的 structure
参数决定了哪些相邻的元素被认为是“连接”的(具体可以查看上面链接的文档)。如果你想让对角线相邻的元素也被视为连接,可以传入一个全是1的3x3数组:
labels, nshapes = ndimage.label(a, structure=np.ones((3, 3)))