在 python 数组中查找并替换子数组

Find and replace subarray in python array

我有一个代表黑白图像的 6600X5100 numpy 数组。 我想从黑色像素噪声中清除此图像 - 删除所有短于 2 像素的黑色像素线(垂直和水平)。

所以如果我有这样的事情:

[0,  0,  0,   0,   0, 255]
[0, 255,255, 255, 255, 0 ]
[0, 255,255, 255,  0,  0 ]
[0, 255,255 ,255,  0, 255]
[0, 255,255, 255,  0, 255]
[0,  0,  0,   0,   0,  0 ]

输出数组将是这样的:

[0,  0,  0,   0,   0,  0 ]
[0, 255,255, 255,  0 , 0 ]
[0, 255,255, 255,  0,  0 ]
[0, 255,255 ,255,  0,  0 ]
[0, 255,255, 255,  0,  0 ]
[0,  0,  0,   0,   0,  0 ]

性能在这里很重要,因此对数组进行简单的循环是行不通的。 有没有办法快速查找和替换数组中的子数组? 因此,如果 [0, 255, 255, 0] 或 [0, 255, 0] 在图像数组中,请将这些部分替换为 0.

或者如果您对此任务有更好的解决方案,我将不胜感激。

您可能想看看 scikit-image 的形态过滤器。

您可以定义简单的过滤器并使用opening 功能来清理图像。您将不得不使用过滤器来完全按照您的需要获取它们,但是库速度非常快。

import numpy as np
from skimage.morphology import opening

img = np.array([[0,  0,  0,   0,   0, 255],
                [0, 255,255, 255, 255, 0 ],
                [0, 255,255, 255,  0,  0 ],
                [0, 255,255 ,255,  0, 255],
                [0, 255,255, 255,  0, 255],
                [0,  0,  0,   0,   0,  0 ]])


# horizontal and vertical filters
hf = np.array([[0,0,0,0,0],
               [0,1,1,1,0],
               [0,0,0,0,0]])
vf = hf.T

# apply each filter in turn
out = opening(opening(img, hf),vf)

out
# returns:
array([[  0,   0,   0,   0,   0,   0],
       [  0, 255, 255, 255,   0,   0],
       [  0, 255, 255, 255,   0,   0],
       [  0, 255, 255, 255,   0,   0],
       [  0, 255, 255, 255,   0,   0],
       [  0,   0,   0,   0,   0,   0]])

我的解决方案与现有解决方案类似,但我使用 2d 卷积:

import numpy as np
from scipy.signal import convolve2d as conv2

in_arr = np.array([
    [0,  0,  0,   0,   0, 255],
    [0, 255,255, 255, 255, 0 ],
    [0, 255,255, 255,  0,  0 ],
    [0, 255,255 ,255,  0, 255],
    [0, 255,255, 255,  0, 255],
    [0,  0,  0,   0,   0,  0 ]])

padded = np.pad(in_arr, 1, mode='constant', constant_values=0)

# Create a kernel
kern = np.ones((1, 3))

# Perform convolution
mask = np.logical_and((conv2(in_arr, kern,   mode='same') // 255) >= 2,
                      (conv2(in_arr, kern.T, mode='same') // 255) >= 2)

# Apply mask:
out_arr = in_arr * mask

这也产生了预期的结果。