Uniquely Label Connected Regions
Connected-component labeling (alternatively connected-component analysis, blob extraction, region labeling, blob discovery, or region extraction) uniquely labels connected components in an image. The labeling process scans the image, pixel-by-pixel from top-left to bottom-right, in order to identify connected pixel regions, i.e. regions of adjacent pixels which share the same set of intensity values. For example, let's find the objects in this image:
To identify the objects in this image, use this command:
magick objects.gif -connected-components 4 -auto-level -depth 8 objects.png
The detected objects are uniquely labeled. Use auto leveling to visualize the detected objects:
Object statistics is useful to review. To display them, use this command:
magick objects.gif -define connected-components:verbose=true -connected-components 4 objects.png
Five objects were detected in the source image with these statistics:
Objects (id: bounding-box centroid area mean-color): 0: 256x171+0+0 119.2,80.8 33117 srgb(0,0,0) 2: 120x135+104+18 159.5,106.5 8690 srgb(255,255,255) 3: 50x36+129+44 154.2,63.4 1529 srgb(0,0,0) 4: 21x23+0+45 8.8,55.9 409 srgb(255,255,255) 1: 4x10+252+0 253.9,4.1 31 srgb(255,255,255)
Add -define connected-components:exclude-header=true to show the objects without the header-line. Add -define connected-components:exclude-ids=true. Use -define connected-components:sort=area | width | height | x | y to sort the verbose connected components objects. By default, the objects are listed in decreasing area. Add -define connected-components:sort-order=increasing | decreasing to specify the sort order.
Use -connected-components 8 to visit 8 neighbors rather than 4. By default, neighbor colors must be exact to be part of a unique object. Use the -fuzz option to include pixels as part of an object that are close in color.
You might want to eliminate small objects by merging them with their larger neighbors. If so, use this command:
magick objects.gif -define connected-components:area-threshold=410 -connected-components 4 \ -auto-level objects.jpg
Here are the expected results. Notice, how the small objects are now merged with the background.
Notice how two of the objects were merged leaving three remaining objects:
Objects (id: bounding-box centroid area mean-color): 0: 256x171+0+0 118.0,80.4 33557 srgb(0,0,0) 2: 120x135+104+18 159.5,106.5 8690 srgb(255,255,255) 3: 50x36+129+44 154.2,63.4 1529 srgb(0,0,0)
By default, the labeled image is grayscale. You can instead replace the object color in the labeled image with the mean-color from the source image. Simply add this setting, -define connected-components:mean-color=true, to your command line.
Thresholds can optionally include ranges, e.g. -define connected-components:area-threshold=410-1600. To keep the background object, identify it with -define connected-components:background-id=object-id. The default background object is the object with the largest area.
In addition to area, there is support for these thresholding metrics:
- connected-components:angle-threshold (from equivalent ellipse)
- connected-components:circularity-threshold (4*pi*area/perimeter^2)
- connected-components:diameter-threshold (sqrt(4*area/pi))
- connected-components:eccentricity-threshold (from equivalent ellipse)
- connected-components:major-axis-threshold (diameter from equivalent ellipse)
- connected-components:minor-axis-threshold (diameter from equivalent ellipse)
You may want to remove certain objects. Use -define connected-components:remove-ids=list-of-ids (e.g. -define connected-components:remove-ids=2,4-5). Or use -define connected-components:keep-ids=list-of-ids to keep these objects and merge all others. For convenience, you can keep the top objects with this option: -define connected-components:keep-top=number-of-objects. Rather than object ids, you can instead remove or keep objects identified by there color, e.g. -define connected-components:keep-colors=red;green;blue.
Objects in your image may look homogeneous but have slightly different color values. By default, only pixels that match exactly are considered as part of a particular object. For slight variations of color in an object, use -fuzz. For example,
magick star-map.png -fuzz 5% -define connected-components:verbose=true \ -define connected-components:mean-color=true -connected-components 4 stars.gif
The algorithm walks through the pixels of a component, in the usual row-column order, looking for a component above or to the left. For the component at top-left, there are no components above or to the left to merge into. As a result, there are special cases where you need to rotate, repeat the connected components, then rotate back. For example
magick \ objects.gif \ -define connected-components:verbose=true \ -define connected-components:area-threshold=6000 \ -virtual-pixel None \ -connected-components 4 -rotate 180 \ -connected-components 4 -rotate -180 \ objects.png