6

I'm performing a image analysis and generated seeds in the form of a boolean array :

import numpy as np

# Example output array
a = np.array([[False, False, False], [False, True, False], [False, False, False]])

>>> a
array([[False, False, False],
       [False,  True, False],
       [False, False, False]])

As I want to do a subsequent analysis on the area surrounding the True value, I want to expand it (by a certain number, say pixels). This would result in the following:

>>> a
array([[False, True, False],
       [True, True, True],
       [False, True, False]])

Is there any function or simple way of solving my 'radial expansion' problem?

Thanks in advance, BBQuercus

Rozakos
  • 608
  • 2
  • 6
  • 20
BBQuercus
  • 819
  • 1
  • 11
  • 28

3 Answers3

6

Why not simply use scipy.ndimage.binary_dilation?

import numpy as np
from scipy import ndimage

a = np.array([
    [False, False, False],
    [False,  True, False],
    [False, False, False],
])
b = ndimage.binary_dilation(a, [
    [False, True, False],
    [ True, True,  True],
    [False, True, False],
])

Results:

>>> a
array([[False, False, False],
       [False,  True, False],
       [False, False, False]])
>>> b
array([[False,  True, False],
       [ True,  True,  True],
       [False,  True, False]])
LemmeTestThat
  • 498
  • 7
  • 17
5

Solution with scipy.signal.convolve2d:

import numpy as np
from scipy.signal import convolve2d


# Example input
# [[False False False False False]
#  [False False  True  True False]
#  [False False False False False]
#  [False False False False False]
#  [False False False False  True]]
in_array = np.zeros((5, 5), dtype=bool)
in_array[1,2] = True
in_array[1,3] = True
in_array[4,4] = True

# Kernel: here you should define how much the True "dilates"

kernel = np.asarray([[False, True, False],
                     [True, True, True],
                     [False, True, False]])

# Convolution happens here
# Convolution is not possible for bool values though, so we convert to int and
# back. That works because bool(N) == True if N != 0.
result = convolve2d(in_array.astype(int), kernel.astype(int), mode='same').astype(bool)
print(result)

# Result:
# [[False False  True  True False]
#  [False  True  True  True  True]
#  [False False  True  True False]
#  [False False False False  True]
#  [False False False  True  True]]
Leporello
  • 638
  • 4
  • 12
0

A simple way i could suggest would be to create a larger array and embed the smaller one into it, as explained in:

How to "embed" a small numpy array into a predefined block of a large numpy array?

Ive just started trying to answer questions on stackoverflow, so i am a beginner. Therefore please forgive me if my answer is too simple or isn't what you were looking for.

  • 1
    Unfortunately I can't embed it in a larger array – I have the same image sizes (pixels) on all images. Embedding would therefore skew / hinder the further analysis. I might still be able to use some of it. Thanks – BBQuercus Jun 24 '19 at 12:07