是否有一种方法来执行类似于OpenCV中的侵蚀的过程,如果的任何邻居的是非零的,而不是要求其所有的邻居都是非零的,它是否保留了给定的像素?
这里的邻居,我指的是任何像素与abs(x1-x2)+abs(y1-y2)==1,但这是很容易控制通过侵蚀内核。
当然,我总是可以使用for循环并从零开始实现这种行为,但是我更喜欢OpenCV能够提供它的库的速度。
它能倒置图像,进行侵蚀,然后倒转吗?
我的另一个想法是将内核与一个空中心进行转换,然后将所有值剪辑到0到1之间,为此我将使用scipy.ndimage.convolve。
我使用的是一个二进制NumPy数组,其类型为np.float32 (即值为0.0或1.0),形状为512。
发布于 2021-09-03 04:44:31
完成您的目标的一个简单方法是使用一个正方形的3x3内核。对于每个像素,您现在都知道它的邻域中有多少前景像素(包括它本身)。阈值在2 (>= 2),以获得所有像素,其中至少有2个前景像素在邻里。最后,逻辑和原始图像将提供所有前景像素,其中至少有一个前景邻居。
下面是一个例子:
import scipy.ndimage
import numpy as np
img = np.array([[0., 0., 0., 0., 0., 0., 0., 1., 1., 1.],
[0., 1., 0., 0., 0., 0., 0., 1., 1., 1.],
[0., 0., 0., 0., 0., 0., 0., 0., 1., 1.],
[0., 0., 0., 0., 0., 0., 1., 0., 1., 1.],
[0., 0., 0., 0., 0., 0., 1., 0., 0., 0.],
[0., 0., 1., 0., 0., 0., 0., 0., 0., 0.],
[0., 1., 1., 0., 0., 0., 0., 0., 0., 0.],
[0., 1., 1., 0., 1., 0., 0., 0., 0., 0.],
[0., 1., 1., 0., 0., 0., 0., 0., 0., 0.],
[0., 1., 1., 0., 0., 0., 0., 0., 0., 0.],
[0., 1., 1., 0., 0., 0., 0., 0., 0., 0.],
[0., 0., 0., 1., 0., 0., 0., 1., 1., 0.],
[0., 0., 0., 0., 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., 1.],
[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.]], dtype=np.float32)
tmp = scipy.ndimage.convolve(img, np.ones((3,3)), mode='constant')
out = np.logical_and(tmp >= 2, img).astype(np.float32)产出如下:
[[0. 0. 0. 0. 0. 0. 0. 1. 1. 1.]
[0. 0. 0. 0. 0. 0. 0. 1. 1. 1.]
[0. 0. 0. 0. 0. 0. 0. 0. 1. 1.]
[0. 0. 0. 0. 0. 0. 1. 0. 1. 1.]
[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 1. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 1. 1. 0.]
[0. 0. 0. 0. 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.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]当然,一些成像库将具有专门为此目的而设计的功能。我不知道OpenCV、ndimage或scikit映像是否有这样的功能,我对这些库还不够了解。但是DIPlib有 (公开:我是作者):
import diplib as dip
out = img - dip.GetSinglePixels(img > 0)img > 0部件是将浮点数组转换为逻辑数组,DIPlib对二进制图像的期望。这大约是512x512图像的另一个解决方案的5倍。
发布于 2021-09-03 10:14:25
假设你有
src = np.uint8([
[ 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 255, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 255, 0, 0],
[ 0, 0, 0, 0, 0, 0, 255, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0]])(你可以想办法从你的花车上得到这个)
您正在寻找非零像素,而不是所有的邻居都是0。您可以从几个操作中构造所需的结果。
您可以将MORPH_HITMISS用于正条件(所有邻居为0),然后将其与否定结合起来。
您可以使用这个内核:
kernel = np.int8([ # 0 means "don't care", all others have to match
[-1, -1, -1],
[-1, +1, -1],
[-1, -1, -1],
])
neighbors_all_zero = cv.morphologyEx(src=src, op=cv.MORPH_HITMISS, kernel=kernel)
result = src & ~neighbors_all_zero结果:
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],
[ 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 255, 0, 0],
[ 0, 0, 0, 0, 0, 0, 255, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0]], dtype=uint8)小心价值观本身。OpenCV有时假定掩码为0或255个,而在其他时候则假设为0和非零.当我用0和1代替0和255时,我得到了一些有趣的结果。不过,我相信这些都是可以解决的。
https://stackoverflow.com/questions/69039257
复制相似问题