Challenge¶
Observe the following binary image.
Design and implement an algorithm that segments each object. The output should be a 2-D array, the same shape as the input, where each element is labelled
- 0 if the pixel represents background,
- 1 if the pixel is part of the first object
- 2 if the pixel is part of the second object
- ...
- K if the pixel is part of the Kth object
For example, if this were the input...
then this should be the output 👇
Starter Code¶
Pixel Connectivity¶
Have a look at these 9 pixels.
Is pixel E connected to pixel A? In other words, would you consider A a neighbor of E?
This is something you get to decide. Typically, people use 4-connectivity or 8-connectivity .
Hint 1
Hint 2
Solution¶
This problem is known as Connected Component Labelling. Wikipedia describes two algorithmic solutions:
Two-pass Algorithm
In this algorithm, you iterate over each cell in the array, in row-major order two times.
During the first pass, while observing the current cell...
-
If the cell is background, give it label 0
-
If the cell is foreground, look at this cell's neighbors which have already been passed. (In my solution below, I use 8-connectivity, so I observe neighbors to the northwest, north, northeast, and west.)
-
If all of those neighbors are background (0), give this cell a new, unique label.
-
Otherwise, identify and use the minimum label amongst those neighbors.
If at least two neighbors use a different, non-zero label, take note of their equivalence, since they belong to the same connected component.
-
During the second pass, while observing the current cell...
- If the cell is not background, look up its equivalent labels and assign it the minimum equivalent label.
After the second pass, every component should be segmented with a distinct label. However, the labels won't necessarily be the unique integers 0, 1, 2, ... So, we perform a final step, mapping the unique labels onto the set {0, 1, ... K}.
Checking the result
We can look at each labelled component, individually, like this
Plot of the first object (i.e. the pixels with label 1)
Or we can plot all components on the same chart using Matplotlib, like this