Both of these methods are included in the Scikit-Image library for Python. I'm trying to extract certain objects from images and ran into these two methods in a senior dev's code, written for the same purpose.
I have read the documentation for both skimage.morphology.remove_small_holes
and skimage.morphology.remove_small_objects
. But I can't understand what difference these two methods pose when they are run on a ndarray containing an image.
One removes holes (value 0) within objects (any other single value), the other removes objects. Note that it acts on either binary images (ndarray of dtype bool) or segmentation masks (ndarray of dtype int, where each value represents one object). Hopefully this example clarifies their use:
import numpy as np
from skimage import morphology
objects = np.array([
[1, 1, 1, 0, 0],
[1, 0, 1, 0, 0],
[1, 1, 1, 0, 0],
[0, 0, 0, 0, 2],
])
You can see that this array has two objects, object "1" has 8 pixels, and a hole in it of size 1 pixel, while object "2" has only 1 pixel total. Now I do:
print(morphology.remove_small_objects(objects, 2))
This removes objects of size strictly less than 2 pixels, so "2" disappears:
[[1 1 1 0 0]
[1 0 1 0 0]
[1 1 1 0 0]
[0 0 0 0 0]]
Removing holes is a little more complicated, because that function only works with boolean arrays, but the same principle applies. We are going to:
segmentation.watershed
to get objects back — preserving their original IDs.from skimage import segmentation
binary_objects = objects.astype(bool)
binary_filled = morphology.remove_small_holes(binary_objects, 2)
objects_filled = segmentation.watershed(
binary_filled, objects, mask=binary_filled
)
print(objects_filled)
This removes from any object holes of size strictly less than 2, so the hole in the object "1" is removed:
[[1 1 1 0 0]
[1 1 1 0 0]
[1 1 1 0 0]
[0 0 0 0 2]]