用于识别对象的可变区域阈值-Python [英] Variable area threshold for identifying objects - python

查看:68
本文介绍了用于识别对象的可变区域阈值-Python的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an array which contains information of the size and location a series of shapes: where the array is zero, there are no shapes, where the array is not zero there is a shape. Different shapes are separated by zeros - so that if you were to plot every point in the array, you would see a map of the various shapes. I hope that makes sense, if not here is an example array containing 4 different shapes:

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。

I need to count and identify these shapes but I only want to include the ones with an area above a certain threshold. I would like the area threshold to be 1/15 of the area of the largest shape in the field. (In the above example, the largest area would be 5.

问题是:如何在不使用字段的情况下(使用python)找到最大形状的区域?

The question is: How can I find (using python) the area of the maximum shape in the field without individually identifying each shape?

为澄清形状的含义,以下代码绘制数组的图像,该图像显示4个不同的对象:

To clarify what I mean by the 'shapes', the following code plots an image of the array, which shows 4 distinct objects:

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()


推荐答案

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

You can use scipy.ndimage.label to find the connected non-zero regions in your array, then use scipy.ndimage.sum to find the area of each region:

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)

在您的示例中碰巧有两个'形状'具有相同的面积:

In your example there happen to be two 'shapes' with the same area:

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 的参数确定哪些相邻元素被视为已连接(请参阅​​上面的文档)。如果要将对角线相邻的元素视为已连接,则可以传递3x3的元素数组:

The structure argument passed to scipy.ndimage.label determines which neighbouring elements are considered to be 'connected' (see the docs linked above). If you want diagonally adjacent elements to be considered as connected, you can pass a 3x3 array of ones:

labels, nshapes = ndimage.label(a, structure=np.ones((3, 3)))

这篇关于用于识别对象的可变区域阈值-Python的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆