【问题标题】:How to go from a contour to an image mask in with Matplotlib如何使用 Matplotlib 从轮廓到图像蒙版
【发布时间】:2013-06-03 06:00:44
【问题描述】:

如果我绘制一个二维数组并对其进行轮廓化,我可以通过cs = plt.contour(...); cs.allsegs 访问分割图,但它被参数化为一条线。我想要一个线内部的 segmap 布尔掩码,所以我可以说,快速总结该轮廓内的所有内容。

非常感谢!

【问题讨论】:

  • 您无法访问生成等高线图的原始data 吗?然后,您应该能够通过执行data > threshold 来生成所需的布尔掩码,其中阈值是等高线处的值。
  • 这在某些情况下会起作用,但是如果数据中有多个峰值,您可以为相同的值设置多条等高线。使用阈值将选择所有这些等高线内的数据。

标签: python matplotlib plot mask contour


【解决方案1】:

我认为没有真正简单的方法,主要是因为您想混合栅格和矢量数据。幸运的是,Matplotlib 路径有一种方法可以检查一个点是否在路径内,对所有像素执行此操作会生成一个遮罩,但我认为这种方法对于大型数据集可能会变得非常慢。

import matplotlib.patches as patches
from matplotlib.nxutils import points_inside_poly
import matplotlib.pyplot as plt
import numpy as np

# generate some data
X, Y = np.meshgrid(np.arange(-3.0, 3.0, 0.025), np.arange(-3.0, 3.0, 0.025))
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)

fig, axs = plt.subplots(1,2, figsize=(12,6), subplot_kw={'xticks': [], 'yticks': [], 'frameon': False})

# create a normal contour plot
axs[0].set_title('Standard contour plot')
im = axs[0].imshow(Z, cmap=plt.cm.Greys_r)
cs = axs[0].contour(Z, np.arange(-3, 4, .5), linewidths=2, colors='red', linestyles='solid')

# get the path from 1 of the contour lines
verts = cs.collections[7].get_paths()[0]

# highlight the selected contour with yellow
axs[0].add_patch(patches.PathPatch(verts, facecolor='none', ec='yellow', lw=2, zorder=50))

# make a mask from it with the dimensions of Z
mask = verts.contains_points(list(np.ndindex(Z.shape)))
mask = mask.reshape(Z.shape).T

axs[1].set_title('Mask of everything within one contour line')
axs[1].imshow(mask, cmap=plt.cm.Greys_r, interpolation='none')

# get the sum of everything within the contour
# the mask is inverted because everything within the contour should not be masked
print np.ma.MaskedArray(Z, mask=~mask).sum()

请注意,默认情况下在不同边缘“离开”绘图的等高线不会形成遵循这些边缘的路径。这些行需要一些额外的处理。

【讨论】:

  • 这是一个很好的答案。我最终改用了scipy.ndimage.measurements.label,它基本上制作了我需要的轮廓蒙版。使用另一个包当然是我希望做的,但还是谢谢你!
  • 你认为你可以在帖子上分享你的方法吗?
【解决方案2】:

另一种可能更直观的方法是来自scipy.ndimagebinary_fill_holes 函数。

import numpy as np
import scipy


image = np.zeros((512, 512))
image[contour1[:, 0], contour1[:, 1]] = 1
masked_image = scipy.ndimage.morphology.binary_fill_holes(image)
```

【讨论】:

    猜你喜欢
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-20
    • 2021-01-05
    • 2013-09-19
    • 2019-06-28
    相关资源
    最近更新 更多