3

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?

Njha
  • 73
  • 8
  • Welcome to SO! I don't think the structure parameter will help you since it is the local structuring element. What you want is to go over the image boundaries and set labels to be the same according to your boundary conditions. – buzjwa May 02 '19 at 13:58
  • By the way, you can improve your question by adding example code to help the community reproduce your problem. In this case an example of a label image (i.e. the output of `scipy.ndimage.label`) and your expected output would be helpful. – buzjwa May 02 '19 at 14:05

1 Answers1

4

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.

buzjwa
  • 2,632
  • 2
  • 24
  • 37
  • Yes, that's perfect, thank you ! I did not know you can find where the list elements equals some value this way, that's very nice :D – Njha May 02 '19 at 14:32
  • That's called 'logical indexing'. It's a super-useful feature of NumPy arrays (inspired by MATLAB) and you should definitely learn to master it! – buzjwa May 02 '19 at 14:36
  • If this answers your question you can accept the answer by clicking the green checkmark. And if you think this answer is well written you can upvote too :) – buzjwa May 02 '19 at 14:39