我有一个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。
或者如果您对此任务有更好的解决方案,我将不胜感激。
答案 0 :(得分:4)
您可能想看看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]])
答案 1 :(得分:2)
我的解决方案与现有解决方案相似,但是我使用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
这也会产生预期的结果。