1

I have 2d binary numpy arrays of varying size, which contain certain patterns. Just like this:

import numpy
a = numpy.zeros((6,6), dtype=numpy.int)
a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1

Here the "image" contains two patches one with 2 and one with 3 connected cells.

print a
array([[0, 0, 0, 0, 0, 0],
       [0, 0, 1, 1, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 1, 0],
       [0, 0, 0, 0, 1, 0]])


I want to know how often a non-zero cell borders another non-zero cell ( neighbours defined as rook's case, so the cells to the left, right, below and above each cell) including their pseudo-replication (so vice-versa).

A previous approach for inner boundaries returns wrong values (5) as it was intended to calculate outer boundaries.

numpy.abs(numpy.diff(a, axis=1)).sum()

So for the above test array, the correct total result would be 6 (The upper patch has two internal borders, the lower four ).

Grateful for any tips!

EDIT:

  • Mistake: The lower obviously has 4 internal edges (neighbouring cells with the same value)

  • Explained the desired neighbourhood a bit more

Community
  • 1
  • 1
Curlew
  • 1,022
  • 18
  • 39

1 Answers1

3

I think the result is 8 if it's 8-connected neighborhood. Here is the code:

import numpy
a = numpy.zeros((6,6), dtype=numpy.int)
a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1

from scipy.ndimage import convolve

kernel = np.ones((3, 3))
kernel[1, 1] = 0
b = convolve(a, kernel, mode="constant")
b[a != 0].sum()

but you said rook's case.

edit

Here is the code for 4-connected neighborhood:

import numpy as np
a = np.zeros((6,6), dtype=np.int)
a[1,2] = a[1,3] = 1
a[4,4] = a[5,4] = a[4,3] = 1

from scipy import ndimage
kernel = ndimage.generate_binary_structure(2, 1)
kernel[1, 1] = 0

b = convolve(a, kernel, mode="constant")
b[a != 0].sum()
HYRY
  • 94,853
  • 25
  • 187
  • 187
  • Sorry for misunderstanding. I want to know a simple 4x4 neighboorhood (so no diagonal connections, eg. left,right,above, below). I edited my question above as the correct answer is indeed **6** and not *8* (the total number of equal neighbors in the lower half is 4) – Curlew Apr 02 '16 at 09:02
  • I tried to adapt your example, but it doesn't seem to be that easy... ```s = ndimage.generate_binary_structure(2,2) s[0,0] = s[0,2] = s[2,0] = s[2,2] = 0 b = ndimage.convolve(a, s, mode="constant") b[a != 0].sum() # equals 11 ``` – Curlew Apr 02 '16 at 09:09
  • Whop, that does the trick. Forgot to replace the center cell... Thanks! – Curlew Apr 02 '16 at 10:12