问题
I have a binary image as follows:
data = np.array([[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
[0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
[0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
[0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
[0, 0 , 0 , 0 , 0 , 0 , 0 , 0]])
For pixels having 1s values, I want to make buffer zone of two pixels with value 1s surrounded in every four directions. The expected result would be:
result=np.array([[1, 1 , 1 , 1 , 1 , 1 , 1 , 1],
[1, 1 , 1 , 1 , 1 , 1 , 1 , 1],
[1, 1 , 1 , 1 , 1 , 1 , 1 , 1],
[1, 1 , 1 , 1 , 1 , 1 , 1 , 1],
[1, 1 , 1 , 1 , 1 , 1 , 1 , 1],
[1, 1 , 1 , 1 , 1 , 1 , 1 , 1],
[1, 1 , 1 , 1 , 1 , 1 , 1 , 1]])
How can I do it?
回答1:
If you only have ones and zeros on the input and output array, you can do it with a 2D convolution, which is simple and works.
from scipy.signal import convolve2d
data = np.array([[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
[0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
[0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
[0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
[0, 0 , 0 , 0 , 0 , 0 , 0 , 0]])
# the kernel doesn't need to be ones, it just needs to be positive and
# non-zero.
kernel = np.ones((5, 5))
result = np.int64(convolve2d(data, kernel, mode='same') > 0)
Which gives you the output you want. You need to define what you want to happen at the edges - in this version, the output array is the same size as the input array.
It might be possible you can do something faster if you have a sparse array.
If you have other values than one and zero in your array, more thought would be needed.
回答2:
You can also do it using morphological dilation operator (which dilates the ones
in this case).
from skimage.morphology import square, dilation
data = np.array([[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
[0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
[0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
[0, 0 , 1 , 1 , 1 , 1 , 0 , 0],
[0, 0 , 0 , 0 , 0 , 0 , 0 , 0],
[0, 0 , 0 , 0 , 0 , 0 , 0 , 0]])
result = dilation(data, square(5))
Note that square(5)
is equivalent to np.ones((5,5))
in this case. Dilation operator works by dilating True
or 1
pixels with the element passed as a second parameter (in this case, a 5x5
square centered at each pixel).
来源:https://stackoverflow.com/questions/29027249/create-buffer-zone-within-a-numpy-array