我有一个数组,其中包含一系列形状的大小和位置信息:数组为零,没有形状,数组不为零,有一个形状。不同的形状由零分隔 - 因此,如果要绘制数组中的每个点,您将看到各种形状的地图。我希望这是有道理的,如果不是这里是一个包含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()
答案 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)
传递给structure
的{{1}}参数确定哪些相邻元素被视为“已连接”(请参阅上面链接的文档)。如果您希望对角相邻的元素被视为已连接,则可以传递3x3数组:
scipy.ndimage.label