将活动值的轮廓覆盖在另一个二维数组上

Drape outline of active values over another 2D array

假设我有一个简单的 2D numpy 数组,我用 imshow():

显示
import numpy as np
import random
import matplotlib.pyplot as plt

a = np.random.randint(2, size=(10,10))
im = plt.imshow(a, cmap='spring', interpolation='none', vmin=0, vmax=1, aspect='equal')
plt.show()

我还有另一个 2D numpy 数组,如下所示:

bnd = np.zeros((10,10))
bnd[2,3] = bnd[3,2:5] = bnd[4,3] = 1
bnd[6,6] = bnd[7,5:8] = bnd[8,6] = 1

plt.imshow(bnd)
plt.show()

如何生成bnd中“1”的所有连续值的轮廓,然后在a上叠加绘制,所以我得到类似下面的东西(我手动添加了黑色下面示例中的行)?

您可以通过查找连续索引的起始索引和结束索引并将它们转换为具有图像坐标的边界段来计算蒙版的边界。

设置图像和遮罩

import numpy as np
import matplotlib.pyplot as plt

a = np.random.randint(2, size=(10,10))
plt.imshow(a, cmap='spring', interpolation='none', vmin=0, vmax=1, aspect='equal')

bnd = np.zeros((10,10))
kernel = [[0,1,0],
          [1,1,1],
          [0,1,0]]
bnd[2:5, 2:5] = bnd[6:9, 5:8] = kernel

查找索引并将其转换为图像的坐标

# indices to vertical segments
v = np.array(np.nonzero(np.diff(bnd, axis=1))).T
vs = np.repeat(v, 3, axis=0) - np.tile([[1, 0],[0, 0],[np.nan, np.nan]], (len(v),1))

# indices to horizontal segments
h = np.array(np.nonzero(np.diff(bnd, axis=0))).T
hs = np.repeat(h, 3, axis=0) - np.tile([[0, 1],[0, 0],[np.nan, np.nan]], (len(h),1))

# convert to image coordinates
bounds = np.vstack([vs,hs])
x = np.interp(bounds[:,1], plt.xlim(), (0, bnd.shape[1]))
y = np.interp(bounds[:,0], sorted(plt.ylim()), (0, bnd.shape[0]))

plt.plot(x, y, color=(.1, .1, .1, .6), linewidth=5)
plt.show()

输出