3

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?

2
  • Is it an array of only ones and zeros, or are there other values? Commented Mar 13, 2015 at 8:39
  • yes, its just 1s and 0s Commented Mar 13, 2015 at 9:41

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

8 Comments

Why would you need "a positive and non-zero kernel"? I can't see any reason why, and the documentation does not mention this either (docs.scipy.org/doc/scipy/reference/generated/…).
You don't for the convolve2d, but you do for the method to work (specifically, the > 0).
@HenryGomersall Thanks for your answer. Could you explain me why you have used kernel of (5,5).
That creates a 5x5 array of ones. Are you familiar with convolution? It's probably a bit involved to explain in a comment, but in essence, the 5x5 shape is what you desire at the output for a single 1 in the input.
It's worth mentioning that the 2D kernel is separable, so you can do this with a pair of 1D kernels along each dimension, which would be faster if that's an issue.
|
1

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.