我有个面具里面可能有洞。我想从面具的外部侵蚀(所以不是洞),水平的,一定数量的像素。
诀窍是,如果我向内侵蚀5px,在某一点上,从边缘有一个3px洞,我想要腐蚀这3px,然后剩下的2px通过洞。因此,我总是侵蚀每一侧5便士,实质上是跳过任何洞。
例如,使用此掩码:

这些灰色地带将被侵蚀:

我可以看到如何通过遍历每一行来实现这一点,如下所示:
erode_px = 5
for y, row in enumerate(mask):
idxs = np.nonzero(row)[0]
if idxs.size:
if idxs.size < erode_px * 2:
mask[y] = 0
else:
mask[y, :idxs[erode_px]] = 0
mask[y, idxs[-erode_px]:] = 0但我正在处理非常大的面具,这需要有效率。是否有一种方法可以实现这一点,而不对Python中的每一行进行循环?最好只使用OpenCV / numpy。
发布于 2021-07-04 13:46:12
您可以使用累积和完成所需的任务:
计算沿水平lines.
n.
。
这将取消沿每条线设置的第一个n集像素。若要从右侧边缘应用该操作,请翻转矩阵,应用上面的操作,并翻转结果。
以下代码演示了该操作:
import numpy as np
import matplotlib.pyplot as plt
def erode_left(mask, n):
return np.logical_and(np.cumsum(mask, axis=1) > n, mask)
def erode_both(mask, n):
mask = erode_left(mask, n)
mask = np.fliplr(erode_left(np.fliplr(mask), n))
return mask
mask = np.array([[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0],
[0,1,1,1,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0],
[0,1,1,1,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,0],
[0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]], dtype=bool)
f, axarr = plt.subplots(2,2)
axarr[0,0].imshow(mask)
axarr[0,0].title.set_text('Input')
axarr[0,1].imshow(erode_left(mask, 5))
axarr[0,1].title.set_text('Eroded left side')
axarr[1,0].imshow(erode_both(mask,5))
axarr[1,0].title.set_text('Eroded both sides')
axarr[1,1].imshow(erode_both(mask,5) + 2*mask)
axarr[1,1].title.set_text('Overlay')
plt.show()

发布于 2021-07-04 07:08:35
我必须承认,这不是最好的解决方案,我也不确定它能实现你想要做的事情,但有一种方法可以像你所说的那样:
import numpy as np
from skimage.morphology import closing, erosion
from matplotlib import pyplot as plt
np.random.seed(0)
idxs = np.random.randint(0, 15 ,(2, 30))
mask = np.ones((15, 15))
mask[:2] = 0
mask[-2:] = 0
mask[:, :2] = 0
mask[:, -2:] = 0
mask[idxs[0], idxs[1]] = 0
mask_cls = closing(mask, selem = np.ones((2, 2)))
mask_erd = erosion(mask_cls, selem = np.ones((3, 3)))
mask_erd_out = mask*mask_erd输出:

https://stackoverflow.com/questions/68241209
复制相似问题