📚 The CoCalc Library - books, templates and other resources
License: OTHER
Segmentation
Segmentation is the division of an image into "meaningful" regions. If you've seen The Terminator, you've seen image segmentation:
In scikit-image
, you can find segmentation functions in the segmentation
package, with one exception: the watershed
function is in morphology
, because it's a bit of both. We'll use watershed and region boundary agglomeration. Functions such as segmentation.slic
are useful for images in which the objects you want to segment have different colors. We won't cover them here but you should be aware they exist.
Segmenting with filters
In many images, the contrast between regions is not sufficient to distinguish them, but there is a clear boundary between them. Using an edge detector on these images, followed by a watershed, often gives very good segmentation. For example, look at the output of the Sobel filter on the coins image:
The watershed algorithm finds the regions between these edges. It does so by envisioning the pixel intensity as height on a topographic map. It then "floods" the map from the bottom up, starting from seed points. These flood areas are called "watershed basins" and when they meet, they form the image segmentation.
Let's look at a one-dimensional example:
Let's find some seeds for coins
. First, we compute the distance transform of a thresholded version of edges
:
Then, we find the peaks in that image--the background points furthest away from any edges--which will act as the seeds.
We are now ready to perform the watershed:
Examining the resulting segmentation
That's pretty good! Some coins are perfectly segmented, with only one missing. We can't do much about the missing one (yet), but we can merge regions to fix the remaining coins, and the background.
Because mean boundary agglomeration won't be available until scikit-image 0.13, we have to monkey patch the RAG class to use it.
Now we can make a RAG that will be mergeable:
Look at the skimage.future.graph.merge_hierarchical
API. Although it's still being worked on (that's why it's in future
, you can use it now!
Note that it needs both a merge function and a weight function, which together define how merging nodes affects the graph. In our case, we want any edges to reflect the mean of the pixels at their boundary.
Joining the seeds of doubt
Watershed combined with region agglomeration makes a very good segmentation, but we missed a coin. How can we improve this result?