Blob features
Find connected regions (blobs) in a grey-scale image.
- class machinevisiontoolbox.ImageBlobs.ImageBlobsMixin[source]
- blobs(**kwargs)[source]
Find and describe blobs in image
- Returns
blobs in the image
- Return type
Find all blobs in the image and return an object that contains geometric information about them. The object behaves like a list so it can be indexed and sliced.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> type(blobs) <class 'machinevisiontoolbox.ImageBlobs.Blobs'> >>> len(blobs) 2 >>> print(blobs) ┌───┬────────┬──────────────┬──────────┬───────┬───────┬────────┬────────┬────────┐ │id │ parent │ centroid │ area │ touch │ perim │ circul │ orient │ aspect │ ├───┼────────┼──────────────┼──────────┼───────┼───────┼────────┼────────┼────────┤ │ 0 │ -1 │ 371.2, 355.2 │ 7.59e+03 │ False │ 556.6 │ 0.343 │ -11.7° │ 0.584 │ │ 1 │ -1 │ 171.2, 155.2 │ 7.59e+03 │ False │ 556.6 │ 0.343 │ -11.7° │ 0.584 │ └───┴────────┴──────────────┴──────────┴───────┴───────┴────────┴────────┴────────┘
- References
Robotics, Vision & Control for Python, Section 12.1.2.1, P. Corke, Springer 2023.
Represent blobs
This object contains the features of every blob in the image.
- class machinevisiontoolbox.ImageBlobs.Blobs(image=None, **kwargs)[source]
Find blobs and compute their attributes
- Parameters
image (
Image
, optional) – image to use, defaults to None
Uses OpenCV functions
findContours
to find a hierarchy of regions represented by their contours, andboundingRect
,moments
to compute moments, perimeters, centroids etc.This class behaves like a list and each blob is an element of the list
>>> from machinevisiontoolbox import Image >>> img = Image.Read('sharks.png') >>> blobs = img.blobs() >>> len(blobs) 4 >>> blobs[0] ┌───┬────────┬──────────────┬──────────┬───────┬───────┬────────┬────────┬────────┐ │id │ parent │ centroid │ area │ touch │ perim │ circul │ orient │ aspect │ ├───┼────────┼──────────────┼──────────┼───────┼───────┼────────┼────────┼────────┤ │ 0 │ -1 │ 245.6, 425.9 │ 1.85e+04 │ False │ 811.2 │ 0.392 │ -1.0° │ 0.561 │ └───┴────────┴──────────────┴──────────┴───────┴───────┴────────┴────────┴────────┘ >>> blobs.area array([18465.5, 7509.5, 7523. , 14356. ])
The list can be indexed, sliced or used as an iterator in a for loop or comprehension, for example:
>>> for blob in blobs: >>> # do a thing >>> areas = [blob.area for blob in blobs]
However the last line can also be written as:
>>> areas = blobs.area
since all methods return a scalar if applied to a single blob:
>>> blobs[1].area
or a list if applied to multiple blobs:
>>> blobs.area
Note
A color image is internally converted to greyscale.
- References
Robotics, Vision & Control for Python, Section 12.1.2.1, P. Corke, Springer 2023.
- Seealso
filter
sort
opencv.moments, opencv.boundingRect, opencv.findContours
- filter(area=None, circularity=None, color=None, touch=None, aspect=None)[source]
Filter blobs
- Parameters
area (scalar or array_like(2), optional) – area minimum or range, defaults to None
circularity (scalar or array_like(2), optional) – circularity minimum or range, defaults to None
color (bool, optional) – color/polarity to accept, defaults to None
touch (bool, optional) – blob touch status to accept, defaults to None
aspect (scalar or array_like(2), optional) – aspect ratio minimum or range, defaults to None
- Returns
set of filtered blobs
- Return type
Return a set of blobs that match the filter criteria.
Parameter
Description
"area"
Blob area
"circularity"
Blob circularity
"aspect"
Aspect ratio of equivalent ellipse
"touch"
Blob edge touch status
The filter parameter arguments are:
a scalar, representing the minimum acceptable value
a array_like(2), representing minimum and maximum acceptable value
Example:
Traceback (most recent call last): File "<input>", line 1, in <module> NameError: name 'blobs' is not defined
- References
Robotics, Vision & Control for Python, Section 12.1.2.1, P. Corke, Springer 2023.
- Seealso
- sort(by='area', reverse=False)[source]
Sort blobs
- Parameters
by (str, optional) – parameter to sort on, defaults to “area”
reverse (bool, optional) – sort in ascending order, defaults to False
- Returns
set of sorted blobs
- Return type
Return a blobs object where the blobs are sorted according to the sort parameter:
Parameter
Description
"area"
Blob area
"circularity"
Blob circularity
"perimeter"
Blob external perimeter length
"aspect"
Aspect ratio of equivalent ellipse
"touch"
Blob edge touch status
Example:
>>> from machinevisiontoolbox import Image >>> img = Image.Read('sharks.png') >>> blobs = img.blobs() >>> blobs.sort() ┌───┬────────┬──────────────┬──────────┬───────┬────────┬────────┬────────┬────────┐ │id │ parent │ centroid │ area │ touch │ perim │ circul │ orient │ aspect │ ├───┼────────┼──────────────┼──────────┼───────┼────────┼────────┼────────┼────────┤ │ 1 │ -1 │ 502.3, 183.9 │ 7.51e+03 │ False │ 514.8 │ 0.396 │ -30.9° │ 0.562 │ │ 2 │ -1 │ 82.9, 159.6 │ 7.52e+03 │ False │ 513.4 │ 0.399 │ 28.9° │ 0.562 │ │ 3 │ -1 │ 297.0, 180.0 │ 1.44e+04 │ False │ 1235.4 │ 0.132 │ -95.6° │ 0.701 │ │ 0 │ -1 │ 245.6, 425.9 │ 1.85e+04 │ False │ 811.2 │ 0.392 │ -1.0° │ 0.561 │ └───┴────────┴──────────────┴──────────┴───────┴────────┴────────┴────────┴────────┘
- References
Robotics, Vision & Control for Python, Section 12.1.2.1, P. Corke, Springer 2023.
- Seealso
- property area
Area of the blob
- Returns
area in pixels
- Return type
int
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].area 7590.5 >>> blobs.area array([7590.5, 7590.5])
- property u
u-coordinate of the blob centroid
- Returns
u-coordinate (horizontal)
- Return type
float
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].u 371.2073205542015 >>> blobs.u array([371.2073, 171.2073])
- property v
v-coordinate of the blob centroid
- Returns
v-coordinate (vertical)
- Return type
float
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].v 355.18802011286033 >>> blobs.v array([355.188, 155.188])
- property centroid
Centroid of blob
- Returns
centroid of the blob
- Return type
2-tuple
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].bboxarea 122400 >>> blobs.bboxarea array([122400, 20800])
- property p
Centroid point of blob
- Returns
centroid of the blob
- Return type
2-tuple
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].bboxarea 122400 >>> blobs.bboxarea array([122400, 20800])
- property bbox
Bounding box
- Returns
bounding
- Return type
ndarray(4)
The bounding box is a 1D array [umin, umax, vmin, vmax].
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].bbox array([299, 445, 300, 408]) >>> blobs.bbox [array([299, 445, 300, 408]), array([ 99, 245, 100, 208])]
Note
The bounding box is the smallest box with vertical and horizontal edges that fully encloses the blob.
- property umin
Minimum u-axis extent
- Returns
maximum u-coordinate of the blob
- Return type
int
Returns the u-coordinate of the left side of the bounding box.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].umin 299 >>> blobs.umin array([299, 99])
- property umax
Maximum u-axis extent
- Returns
maximum u-coordinate of the blob
- Return type
int
Returns the u-coordinate of the right side of the bounding box.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].umin 299 >>> blobs.umin array([299, 99])
- property vmin
Maximum v-axis extent
- Returns
maximum v-coordinate of the blob
- Return type
int
Returns the v-coordinate of the top side of the bounding box.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].vmin 299 >>> blobs.vmin array([299, 99])
- property vmax
Minimum v-axis extent
- Returns
maximum v-coordinate of the blob
- Return type
int
Returns the v-coordinate of the bottom side of the bounding box.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].vmax 853 >>> blobs.vmax array([853, 453])
- property bboxarea
Area of the bounding box
- Returns
area of the bounding box in pixels
- Return type
int
Return the area of the bounding box which is invariant to blob position.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].bboxarea 122400 >>> blobs.bboxarea array([122400, 20800])
Note
The bounding box is the smallest box with vertical and horizontal edges that fully encloses the blob.
- Seealso
- property fillfactor
Fill factor, ratio of area to bounding box area
- Returns
fill factor
- Return type
int
Return the ratio, \(\le 1\), of the blob area to the area of the bounding box. This is a simple shape metric which is invariant to blob position and scale.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].fillfactor 0.06201388888888889 >>> blobs.fillfactor array([0.062 , 0.3649])
Note
The bounding box is the smallest box with vertical and horizontal edges that fully encloses the blob.
- Seealso
- property a
Radius of equivalent ellipse
- Returns
largest ellipse radius
- Return type
float
Returns the major axis length which is invariant to blob position and orientation.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].a 69.53272449306235 >>> blobs.a array([69.5327, 69.5327])
- property b
Radius of equivalent ellipse
- Returns
smallest ellipse radius
- Return type
float
Returns the minor axis length which is invariant to blob position and orientation.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].b 40.59882970386957 >>> blobs.b array([40.5988, 40.5988])
- property aspect
Blob aspect ratio
- Returns
ratio of equivalent ellipse axes
- Return type
float
Returns the ratio of equivalent ellipse axis lengths, \(<1\), which is invariant to blob position, orientation and scale.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].aspect 0.5838808992436407 >>> blobs.aspect array([0.5839, 0.5839])
- property orientation
Blob orientation
- Returns
Orientation of equivalent ellipse (in radians)
- Return type
float
Returns the orientation of equivalent ellipse major axis with respect to the horizontal axis, which is invariant to blob position and scale.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].orientation -0.2046350254173464 >>> blobs.orientation array([-0.2046, -0.2046])
- property touch
Blob edge touch status
- Returns
blob touches the edge of the image
- Return type
bool
Returns true if the blob touches the edge of the image.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].touch False >>> blobs.touch array([False, False])
- property level
Blob level in hierarchy
- Returns
blob level in hierarchy
- Return type
int
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('multiblobs.png') >>> blobs = im.blobs() >>> blobs[2].level 2 >>> blobs.level array([0, 1, 2, 2, 1, 0, 1, 1, 0, 1])
- property color
Blob color
- Returns
blob color
- Return type
int
Blob color in a binary image. This is inferred from the level in the blob hierarchy. The background blob is black (0), the first-level child blobs are white (1), etc.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('multiblobs.png') >>> blobs = im.blobs() >>> blobs[2].color 0 >>> blobs.color array([0, 1, 0, 0, 1, 0, 1, 1, 0, 1])
- property parent
Parent blob
- Returns
index of this blob’s parent
- Return type
int
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('multiblobs.png') >>> blobs = im.blobs() >>> print(blobs) ┌───┬────────┬───────────────┬──────────┬───────┬────────┬────────┬─────────┬────────┐ │id │ parent │ centroid │ area │ touch │ perim │ circul │ orient │ aspect │ ├───┼────────┼───────────────┼──────────┼───────┼────────┼────────┼─────────┼────────┤ │ 0 │ -1 │ 907.9, 735.1 │ 1.94e+05 │ False │ 2219.0 │ 0.551 │ -103.6° │ 0.814 │ │ 1 │ 0 │ 1025.0, 813.7 │ 1.06e+05 │ False │ 1386.9 │ 0.770 │ -90.0° │ 0.802 │ │ 2 │ 1 │ 938.1, 855.2 │ 1.72e+04 │ False │ 489.7 │ 1.005 │ -12.5° │ 0.945 │ │ 3 │ 1 │ 988.1, 697.2 │ 1.21e+04 │ False │ 411.5 │ 0.999 │ -102.8° │ 0.919 │ │ 4 │ 0 │ 846.0, 511.7 │ 1.75e+04 │ False │ 495.9 │ 0.996 │ -90.1° │ 0.871 │ │ 5 │ -1 │ 291.7, 377.8 │ 1.7e+05 │ False │ 1711.6 │ 0.811 │ -102.9° │ 0.775 │ │ 6 │ 5 │ 312.7, 472.1 │ 1.75e+04 │ False │ 494.5 │ 1.001 │ -90.2° │ 0.87 │ │ 7 │ 5 │ 241.9, 245.0 │ 1.75e+04 │ False │ 495.9 │ 0.996 │ -90.1° │ 0.871 │ │ 8 │ -1 │ 1228.0, 254.3 │ 8.14e+04 │ False │ 1214.2 │ 0.772 │ -102.9° │ 0.651 │ │ 9 │ 8 │ 1225.2, 220.0 │ 1.75e+04 │ False │ 495.9 │ 0.996 │ -90.0° │ 0.871 │ └───┴────────┴───────────────┴──────────┴───────┴────────┴────────┴─────────┴────────┘ >>> blobs[5].parent -1 >>> blobs[6].parent 5
A parent of -1 is the image background.
- property children
Child blobs
- Returns
list of indices of this blob’s children
- Return type
list of int
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('multiblobs.png') >>> blobs = im.blobs() >>> blobs[5].children [6, 7]
- property moments
Moments of blobs
- Returns
moments of blobs
- Return type
named tuple or list of named tuples
Compute multiple moments of each blob and return them as a named tuple with attributes
Moment type
attribute name
moments
m00
m10
m01
m20
m11
m02
m30
m21
m12
m03
central moments
mu20
mu11
mu02
mu30
mu21
mu12
mu03
|normalized central moments
nu20
nu11
nu02
nu30
nu21
nu12
nu03
|
- property humoments
Hu image moment invariants of blobs
- Returns
Hu image moments
- Return type
ndarray(7) or ndarray(N,7)
Computes the seven Hu image moment invariants of the image. These are a robust shape descriptor that is invariant to position, orientation and scale.
- Seealso
- property perimeter_length
Perimeter length of the blob
- Returns
perimeter length in pixels
- Return type
float
Return the length of the blob’s external perimeter. This is an 8-way connected chain of edge pixels.
Example:
>>> from machinevisiontoolbox import Image >>> import numpy as np >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].perimeter_length 556.5706294775009 >>> blobs.perimeter_length array([556.5706, 556.5706])
Note
The length of the internal perimeter is found from summing the external perimeter of each child blob.
- property circularity
Blob circularity
- Returns
circularity
- Return type
float
Circularity, computed as \(\rho = \frac{A}{4 \pi p^2} \le 1\). Circularity is one for a circular blob and < 1 for all other shapes, approaching zero for a line.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].circularity 0.34258515276788193 >>> blobs.circularity array([0.3426, 0.3426])
Note
Kulpa’s correction factor is applied to account for edge discretization:
Area and perimeter measurement of blobs in discrete binary pictures. Z.Kulpa. Comput. Graph. Image Process., 6:434-451, 1977.
Methods to Estimate Areas and Perimeters of Blob-like Objects: a Comparison. Proc. IAPR Workshop on Machine Vision Applications., December 13-15, 1994, Kawasaki, Japan L. Yang, F. Albregtsen, T. Loennestad, P. Groettum
- Seealso
- property perimeter
Perimeter of the blob
- Returns
Perimeter, one point per column
- Return type
ndarray(2,N)
Return the coordinates of the pixels that form the blob’s external perimeter. This is an 8-way connected chain of edge pixels.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].perimeter.shape (2, 471) >>> with np.printoptions(threshold=10): ... blobs[0].perimeter ... blobs.perimeter ... array([[367, 366, 365, ..., 370, 369, 368], [300, 301, 301, ..., 300, 300, 300]], dtype=int32) [array([[367, 366, 365, ..., 370, 369, 368], [300, 301, 301, ..., 300, 300, 300]], dtype=int32), array([[167, 166, 165, ..., 170, 169, 168], [100, 101, 101, ..., 100, 100, 100]], dtype=int32)]
Note
The perimeter is not closed, that is, the first and last point are not the same.
- Seealso
- perimeter_approx()[source]
Approximate perimeter of the blob
- Parameters
epsilon (int) – maximum distance between the original curve and its approximation, default is exact contour
- Returns
Perimeter, one point per column
- Return type
ndarray(2,N)
The result is a low-order polygonal approximation to the original perimeter. Increasing
epsilon
reduces the number of perimeter points.Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs[0].perimeter.shape (2, 471) >>> blobs[0].perimeter_approx(5).shape (2, 15) >>> with np.printoptions(threshold=10): ... blobs[0].perimeter_approx(5) ... array([[367, 316, 299, ..., 411, 369, 368], [300, 345, 377, ..., 337, 326, 300]], dtype=int32)
which in this case has reduced the number of perimeter points from 471 to 15.
Note
The perimeter is not closed, that is, the first and last point are not the same.
- Seealso
- polar()[source]
Boundary in polar cooordinate form
- Parameters
N (int, optional) – number of points around perimeter, defaults to 400
- Returns
Contour, one point per column
- Return type
ndarray(2,N)
Returns a polar representation of the boundary with respect to the centroid. Each boundary point is represented by a column \((r, \theta)\). The polar profile can be used for scale and orientation invariant matching of shapes.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> p = blobs[0].polar() >>> p.shape (2, 400)
Note
The points are evenly spaced around the perimeter but are not evenly spaced in subtended angle.
- Seealso
- polarmatch(target)[source]
Compare polar profiles
- Parameters
target (int) – the blob index to match against
- Returns
similarity and orientation offset
- Return type
ndarray(N), ndarray(N)
Performs cross correlation between the polar profiles of blobs. All blobs are matched against blob index
target
. Blob indextarget
is included in the results.There are two return values:
Similarity is a 1D array, one entry per blob, where a value of one indicates maximum similarity irrespective of orientation and scale.
Orientation offset is a 1D array, one entry per blob, is the relative orientation of blobs with respect to the
target
blob. Thetarget
blob has an orientation offset of 0.5. These values lie in the range [0, 1), equivalent to \([0, 2\pi)\) and wraps around.
Example:
>>> from machinevisiontoolbox import Image >>> im = Image.Read('shark2.png') >>> blobs = im.blobs() >>> blobs.polarmatch(1) ([0.9999999999999999, 0.9999999999999999], array([0.5, 0.5]))
Note
Can be considered as matching two functions defined over \(S^1\).
Orientation is obtained by cross-correlation of the polar-angle profile.
- Seealso
polar
contour
- plot_box(**kwargs)[source]
Plot a bounding box for the blob using Matplotlib
- Parameters
kwargs – arguments passed to
plot_box
Plot a bounding box for every blob described by this object.
Example:
- Seealso
plot_labelbox
plot_centroid
plot_perimeter
plot_box
- plot_labelbox(**kwargs)[source]
Plot a labelled bounding box for the blob using Matplotlib
- Parameters
kwargs – arguments passed to
plot_labelbox
Plot a labelled bounding box for every blob described by this object. The blobs are labeled by their blob index.
- plot_centroid(label=False, **kwargs)[source]
Draw the centroid of the blob using matplotlib
- Parameters
label (bool) – add a sequential numeric label to each point, defaults to False
kwargs – other arguments passed to
plot_point
If no marker style is given then it will be an overlaid “o” and “x” in blue.
- Seealso
plot_box
plot_perimeter
plot_point
- plot_perimeter(**kwargs)[source]
Plot perimeter of blob using Matplotlib
- Parameters
kwargs – line style parameters passed to
plot
Highlights the perometer of a blob or blobs on the current plot.
- Seealso
- label_image(image=None)[source]
Create label image from blobs
- Parameters
image (
Image
, optional) – image to draw into, defaults to new image- Returns
greyscale label image
- Return type
Image
The perimeter information from the blobs is used to generate a greyscale label image where the greyvalue of each region corresponds to the blob index.
- Seealso
labels_binary
- dotfile(filename=None, direction=None, show=False)[source]
Create a GraphViz dot file
- Parameters
filename (str, optional) – filename to save graph to, defaults to None
direction (str, optional) – graph drawing direction, defaults to top to bottom
show (bool, optional) – compile the graph and display in browser tab, defaults to False
Creates the specified file which contains the GraphViz code to represent the blob hierarchy as a directed graph. By default output is to the console.
Note
If
filename
is a file object then the file will not be closed after the GraphViz model is written.