【问题标题】:How to locate a particular "region" of values in a 2D numpy array?如何在 2D numpy 数组中定位值的特定“区域”?
【发布时间】:2016-02-15 21:09:52
【问题描述】:

我正在使用由 101x101=10201 值组成的二维 numpy 数组。这些值属于float 类型,范围从0.01.0。该数组有一个X,Y 坐标系,它起源于左上角:因此,位置(0,0) 位于左上角,而位置(101,101) 位于右下角。

这是二维数组的样子(只是摘录):

X,Y,Value
0,0,0.482
0,1,0.49
0,2,0.496
0,3,0.495
0,4,0.49
0,5,0.489
0,6,0.5
0,7,0.504
0,8,0.494
0,9,0.485

我希望能够:

1) 计算值超过给定阈值的单元格区域数(见下图),例如0.3

2) 确定这些区域的视觉中心与坐标为(0,0)的左上角之间的距离。

如何在 Python 2.7 中做到这一点?

这是一个 2D 数组的可视化表示,其中 2 个区域突出显示(颜色越深,值越高):

【问题讨论】:

  • 你可以访问opencv模块cv2吗?这样的任务基本上出现在图像处理领域?
  • 从未听说过。你能告诉我更多细节吗?
  • 我觉得你应该用谷歌搜索一下。

标签: python arrays numpy image-processing scipy


【解决方案1】:

您可以使用简单的布尔条件找到满足您截断的像素,然后使用 scipy.ndimage.labelscipy.ndimage.center_of_mass 找到连接区域并计算它们的质心:

import numpy as np
from scipy import ndimage
from matplotlib import pyplot as plt

# generate some lowpass-filtered noise as a test image
gen = np.random.RandomState(0)
img = gen.poisson(2, size=(512, 512))
img = ndimage.gaussian_filter(img.astype(np.double), (30, 30))
img -= img.min()
img /= img.max()

# use a boolean condition to find where pixel values are > 0.75
blobs = img > 0.75

# label connected regions that satisfy this condition
labels, nlabels = ndimage.label(blobs)

# find their centres of mass. in this case I'm weighting by the pixel values in
# `img`, but you could also pass the boolean values in `blobs` to compute the
# unweighted centroids.
r, c = np.vstack(ndimage.center_of_mass(img, labels, np.arange(nlabels) + 1)).T

# find their distances from the top-left corner
d = np.sqrt(r*r + c*c)

# plot
fig, ax = plt.subplots(1, 2, sharex=True, sharey=True, figsize=(10, 5))
ax[0].imshow(img)
ax[1].hold(True)
ax[1].imshow(np.ma.masked_array(labels, ~blobs), cmap=plt.cm.rainbow)
for ri, ci, di in zip(r, c, d):
    ax[1].annotate('', xy=(0, 0), xytext=(ci, ri),
                   arrowprops={'arrowstyle':'<-', 'shrinkA':0})
    ax[1].annotate('d=%.1f' % di, xy=(ci, ri),  xytext=(0, -5),
                   textcoords='offset points', ha='center', va='top',
                   fontsize='x-large')
for aa in ax.flat:
    aa.set_axis_off()
fig.tight_layout()
plt.show()

【讨论】:

  • rcd 均以像素为单位。
  • 是的,它生成一个 512x512 数组。 rc 指的是该数组中的行和列位置。
  • nlabelslabel() 找到的连通区域数,如labels.max() == nlabels。这都解释了in the documentation for scipy.ndimage.label
  • 计算质心时,您可以将高于阈值的所有像素视为相等(即像素为 1 或 0),或者您可以考虑它们在原始值中的实际值图像,使得具有较大值的像素对每个区域的质心具有更大的影响。在我的代码中,这两种情况相当于分别将blobsimg 作为第一个参数传递给center_of_mass
  • 再看我的代码——我的img变量相当于你的mymatrix,我的blobs相当于你的img。 cmets有点失控了,所以我不打算在这里回答任何问题。
猜你喜欢
  • 2013-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-05
  • 2021-02-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-28
相关资源
最近更新 更多