Extracting boundary of a numpy array Extracting boundary of a numpy array numpy numpy

Extracting boundary of a numpy array


One trick to get the contour would be to use binary dilation with 3x3 ones array as the kernel on the negated mask and look for the common ones between it and input. For 4-connected boundary, it would be all ones array and for 8-connected a plus-shaped ones array -

from scipy.ndimage.morphology import binary_dilationk = np.ones((3,3),dtype=int) # for 4-connectedk = np.zeros((3,3),dtype=int); k[1] = 1; k[:,1] = 1 # for 8-connectedout = binary_dilation(a==0, k) & a

Sample run -

Input array :

In [384]: aOut[384]: array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],       [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],       [0, 0, 1, 1, 1, 1, 0, 0, 0, 0],       [0, 0, 1, 1, 1, 1, 0, 0, 0, 0],       [0, 0, 1, 1, 1, 0, 0, 0, 0, 0],       [0, 1, 1, 1, 1, 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, 0, 0, 0, 0, 0, 0, 0, 0]])In [385]: from scipy.ndimage.morphology import binary_dilation

Solve for 4-connected :

In [386]: k = np.ones((3,3),dtype=int)In [390]: binary_dilation(a==0, k) & aOut[390]: array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],       [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],       [0, 0, 1, 1, 0, 1, 0, 0, 0, 0],       [0, 0, 1, 0, 1, 1, 0, 0, 0, 0],       [0, 0, 1, 0, 1, 0, 0, 0, 0, 0],       [0, 1, 1, 1, 1, 0, 0, 0, 0, 0],       [0, 1, 0, 1, 0, 0, 0, 0, 0, 0],       [0, 1, 1, 1, 0, 0, 0, 0, 0, 0],       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

Solve for 8-connected :

In [411]: k = np.zeros((3,3),dtype=int); k[1] = 1; k[:,1] = 1In [412]: kOut[412]: array([[0, 1, 0],       [1, 1, 1],       [0, 1, 0]])In [413]: binary_dilation(a==0, k) & aOut[413]: array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],       [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],       [0, 0, 1, 0, 0, 1, 0, 0, 0, 0],       [0, 0, 1, 0, 0, 1, 0, 0, 0, 0],       [0, 0, 1, 0, 1, 0, 0, 0, 0, 0],       [0, 1, 0, 0, 1, 0, 0, 0, 0, 0],       [0, 1, 0, 1, 0, 0, 0, 0, 0, 0],       [0, 1, 1, 1, 0, 0, 0, 0, 0, 0],       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])

We could also use binary_erosion :

from scipy.ndimage.morphology import binary_erosionout = a-binary_erosion(a,k)