Search code examples
pythonscipyndimage

How to specify a periodic connection for features of scipy.ndimage.label?


Given an N*N array of 0 and 1, I want to build the list of clusters (a cluster being a set of connected points labeled by 1).

scipy.ndimage.label is very useful because it tells you which points are connected.

But I would like also to have periodic boundary conditions on my array, i.e. points (0,j) and (N,j) are identified (like a plane that I glue to make a cylinder). So I need to tell scipy.ndimage.label that features are connected through the boundary.

For example, if my original array is:

In[187]: a = [[1, 1, 0, 0, 0, 0, 1, 1],[1, 1, 0, 1, 0, 0, 1, 1],[1, 1, 0, 0, 0, 1, 1, 1]] 

labels = measurements.label(a)
print(labels)
Out [187]: (array([[1, 1, 0, 0, 0, 0, 2, 2],
   [1, 1, 0, 3, 0, 0, 2, 2],
   [1, 1, 0, 0, 0, 2, 2, 2]], dtype=int32), 3)

and I would like:

(array([[1, 1, 0, 0, 0, 0, 1, 1],
   [1, 1, 0, 3, 0, 0, 1, 1],
   [1, 1, 0, 0, 0, 1, 1, 1]], dtype=int32), 2)

The structure parameter of label allows to specify connection (e.g. features connected even if they touch diagonally), could it be also used for that purpose?


Solution

  • Here is an example for imposing a periodic boundary condition on the left and right boundaries. Each label on the right side is identified with the corresponding label on the left side (if it exists).

    for y in range(label_image.shape[0]):
        if label_image[y, 0] > 0 and label_image[y, -1] > 0:
            label_image[label_image == label_image[y, -1]] = label_image[y, 0]
    

    You can do a similar thing for the upper and lower boundaries. You can also come up with any other boundary condition, iterate over the boundary pixels in your for loop and check the condition in your if statement in a similar manner.