A group of connected pixels is commonly called a blob. Here is an example of an image containing a few blobs. The original image is segmented and the connected components are determined and visualized by color.
| Original Image | Segmented Image | Connected Components |
|---|---|---|
![]() |
![]() |
![]() |
Blob analysis takes a set of connected pixels that are usually generated by imaging real-life objects, and calculates features from the pixel set, such as their area, their position, etc.
Often blobs are produced by some segmentation process, and one of the simplest segmentation methods is binary thresholding: every pixel with a value below the threshold is part of the background and every other pixel is part of some blob. Exactly which blob the pixel is a part of is determined by a connectivity analysis process sometimes called labelling or connected components analysis.
The smallest possible blob consists of a single pixel, and larger blobs consist of several connected pixels.

Have a look at the image above: Does this picture contain one or two blobs? It depends on how you look at it. If you only allow connections via horizontal and vertical neighbours, the picture contains two blobs. However, if diagonal connections count as well, the picture contains one blob only.
| 4-connected | 8-connected |
|---|---|
![]() |
![]() |
By convention, one often uses 8-connectedness for the foreground and 4-connectedness for the background pixels. According to this convention, the following picture contains one white object with two black holes.

One can summarize the relations of the above picture with the following table.
The table clearly shows that there are only two useful connectivity configurations:
| foreground connectivity | background connectivity | objects/holes |
|---|---|---|
| 4 | 4 | 7/2 |
| 4 | 8 | 7/0 |
| 8 | 4 | 1/2 |
| 8 | 8 | 1/0 |
- One (white) object with two (black) holes, or
- Seven (white) objects with no holes.
The other possible configurations do not make any sense, regardless how you look at them.
By default, nGI assumes that foreground pixels are 8-connected and background pixels are 4-connected.
nGI uses regions to represent blobs. Blob analysis is then the process of calculating region features. Because of the efficient run-length storage of regions, these features can be calculated very quickly. Since a region does not contain any pixel values, region features do not need to touch pixels. For a surprisingly large number of features pixel values are not necessary, such as the area or the center of gravity. Here is an example of how a region_list can be created by thresholding and connected components analysis:
region foreground = region::segment(img.get_view(),
[] (image_type::value_type const& v) {
return v < 150; });
region_list objects = region_list::connection(foreground);
However, there is also a class of features that can only be calculated when you take pixel values into account, such as the mean brightness of a blob. nGI has a set of functions that can calculate pixel based features as well, but keep in mind that the performance requirements of calculating these features are higher. For pixel-based features, you still need a region to specify the object.
Some features can be calculated directly by calling a member function of
the region. Other features have more complex dependencies and need to be
calculated indirectly. In order to shield the user from these
complexities, the blob_features class (or its worker classes
region_blob and pixel_blob) can be used. The blob_features class
caches all calculated features, so that they must bee calculated only
once. It also knows about the feature dependencies, i.e. it knows that
in order to calculate the centroid, it first needs the normalized
moments, and in order to calculate the normalized moments, it first
needs the raw moments. The following chapters about the features specify
whether they can be calculated given a region or whether they are
better handled using blob_features. Creating a blob_features object
from a region object is done by copy construction or assignment:
blob b = objects[0];
Here is a list of the region features:
| Feature | Description |
|---|---|
| Area | The area as a number of pixels. |
| Left | The leftmost column position (inclusive). |
| Right | The rightmost column position (exclusive). |
| Top | The topmost row position (inclusive). |
| Bottom | The bottommost row position (exclusive). |
| Width | The width (axis parallel). |
| Height | The height (axis parallel). |
| Aspect Ratio | The axis parallel aspect ratio. |
| Bounds | The axis-parallel bounding box. |
| Perimeter | The perimeter. |
| Compactness | The compactness. |
| Convex Hull | The convex hull. |
| Convex Area | The area of the convex hull. |
| Perforation | The perforation. |
| Convexity | The convexity. |
| Convex Perimeter | The perimeter of the convex hull. |
| Maximum Feret Diameter | The maximum diameter of the convex hull. |
| Minimum Feret Diameter | The minimum diameter of the convex hull. |
| Minimum Bounding Circle | The minimum bounding circle of the region. |
| Inner Contour | The inner contour (lies on the blob). |
| Inner Contour Perimeter | The length of the inner contour. |
| Outer Contour | The outer contour (lies on the background). |
| Outer Contour Perimeter | The length of the outer contour. |
| Raw Moments | The moments based on the region. |
| Normalized Moments | The normalized moments based on the region. |
| Centroid | The center of gravity based on the region. |
| Central Moments | The central moments based on the region. |
| Equivalent Ellipse | The equivalent ellipse based on the region. |
| Equivalent Ellipse Eccentricity | he equivalent ellipse based on the region. |
| Scale Invariant Moments | The scale invariant moments based on the region. |
| Hu Moments | Hu moments based on the region. |
| Flusser Moments | Flusser moments based on the region. |
| Holes | The holes of the region in the form of a region_list of connected components. |
| Number of Holes | The number of holes of the region. |
| Area of Holes | The total area of the holes of the region. |
| Fiber Length | A length measurement of fiber-like objects. |
| Fiber Width | A thickness measurement of fiber-like objects. |
| Bounding Rectangle | A bounding rectangle of the region. This rectangle has the same orientation as the equivalent ellipse. |
| Minimum Area Bounding Rectangle | A bounding rectangle of the region. This rectangle has the smallest possible area. |
| Minimum Perimeter Bounding Rectangle | A bounding rectangle of the region. This rectangle has the smallest possible area. |
| Minimum Perimeter Bounding Rectangle | A bounding rectangle of the region. This rectangle has the smallest possible perimeter. |
Here is a list of the pixel based features:
| Feature | Description |
|---|---|
| Minimum Position | The position of the minimum. |
| Minimum | The minimum pixel value. |
| Maximum Position | The position of the maximum. |
| Maximum | The maximum pixel value. |
| Total | The total value. |
| Mean | The mean value. |
| Standard Deviation | The standard deviation. |
| Skewness | The skewness. |
| Channel Minimum | The per-channel minimum pixel value. |
| Channel Maximum | The per-channel maximum pixel value. |
| Contrast | The contrast. |
| Weber Contrast | The contrast according to Weber's formula. |
| Michelson Contrast | The conrast according to Michelson's formula. |
| Horizontal Profile | The horizontal profile. |
| Vertical Profile | The vertical profile. |
| Histogram | The histogram. |
| Raw Moments | The moments based on the grey values. |
| Normalized Moments | The normalized moments based on the grey values. |
| Centroid | The center of gravity based on the grey values. |
| Central Moments | The central moments based on the grey values. |
| Equivalent Ellipse | The equivalent ellipse based on the grey values. |
| Equivalent Ellipse Eccentricity | he equivalent ellipse based on the grey values. |
| Scale Invariant Moments | The scale invariant moments based on the grey values. |
| Hu Moments | Hu moments based on the grey values. |
| Flusser Moments | Flusser moments based on the grey values. |
Region Features
The simplest feature you may want to calculate - which is not a region feature in the strict sense - could be the number of objects in an image.
size_t number_of_objects = objects.size();
The second simplest feature is the region area, and now we are really talking about region features.
Area
The area of a region is an integer value and specifies the number of pixels in the object. It is calculated efficiently by summing the lengths of all region chords together.
size_t area = objects[0].get_area();
The area property is often used to filter out small or large objects. Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
size_t area = b.get_area();
The area of the blob in picture blob.png is 835.
Left
This calculates the minimal x coordinate (inclusive) of the region.
int left = objects[0].get_left();
Regions that have a left value of 0 (or \<0) are regions touching (or crossing) the left border. This feature is sometimes used to filter out objects touching the left border.
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
int left = b.get_left();

Since this is an integer coordinate, it is conceptually in the middle of the leftmost pixel.
The left value of the blob in picture blob.png is 9.
Right
This calculates the maximal x coordinate (exclusive) of the region.
int right = objects[0].get_right();
Regions that have a right value equal to the image width (or bigger than the image width) are regions touching (or crossing) the right border. This feature is sometimes used to filter out objects touching the right border.
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
int right = b.get_right();

Since this is an integer coordinate, it is conceptually half a pixel right of the rightmost pixel.
The right value of the blob in picture blob.png is 89.
Top
This calculates the minimal y coordinate (inclusive) of the region.
int top = objects[0].get_top();
Regions that have a top value of 0 (or \<0) are regions touching (or crossing) the top border. This feature is sometimes used to filter out objects touching the top border.
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
int top = b.get_top();

Since this is an integer coordinate, it is conceptually in the middle of the topmost pixel.
The top value of the blob in picture blob.png is 11.
Bottom
This calculates the maximal y coordinate (exclusive) of the region.
int bottom = objects[0].get_bottom();
Regions that have a bottom value equal to the image height (or bigger than the image height) are regions touching (or crossing) the bottom border. This feature is sometimes used to filter out objects touching the bottom border.
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
int bottom = b.get_bottom();

Since this is an integer coordinate, it is conceptually in the middle of the topmost pixel.
The bottom value of the blob in picture blob.png is 70.
Width
This calculates the axis-parallel width of the region.
blob_features b = objects[0];
int width = b.get_width();
The width value of the blob in picture blob.png is 80.
Height
This calculates the axis-parallel height of the region.
blob_features b = objects[0];
int height = b.get_height();
The height value of the blob in picture blob.png is 59.
Aspect Ratio
This calculates the axis-parallel aspect ratio of the region. The aspect ratio is calculated according to the following formula:
$$r = \frac{w}{h}$$
where w is the width and h is the height.
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
double aspect_ratio = b. get_aspect_ratio ();
The aspect ratio value of the blob in picture blob.png is 1.35593.
Bounds
This calculates the bounds of the region.
Integer coordinates are in the middle of a pixel. Pixel boundaries are offset by half a pixel horizontally and vertically, and so are the region bounds.
box<double> bounds = *objects[0].get_bounds();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
box<double> bounds = *b.get_bounds();
The bounds encompass the whole region tightly, thus the bounds coordinates are returned in floating point values.
The bounds value of the blob in picture blob.png is a box with the top-left coordinate at (8.5, 10.5) and a size of (80, 59).
You may have noted the indirection in the bounds assignment above. This
is because the blob_features class calculates and caches the
box<double> on demand only. It therefore only allocates space when
needed and returns a shared_ptr<box<double>>, which is why you need
the indirection in order to get at the bounds value. All features that
occupy more space than a single value, are handled via a shared_ptr<>.
Perimeter
The perimeter of a region specifies the length of the object outline.
double perimeter = objects[0].get_perimeter();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
double perimeter = b.get_perimeter();

The perimeter of the blob in picture blob.png is 660.
Compactness
This calculates the compactness of the region.
blob_features b = objects[0];
double compactness = b.get_compactness();
The compactness c is calculated from the region area a and the region perimeter p according to this formula:
$$c = \frac {p^{2}} {4 \pi a}$$
The compactness value of the blob in picture blob.png is 41.5.
Convex Hull
This calculates a polyline that constitutes the convex hull of the region.
polyline<double> hull = objects[0].to_point_list().get_convex_hull();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
polyline<double> hull = *b.get_convex_hull();

The convex hull can be used to calculate further features, such as the area of the convex hull, the perimeter of the convex hull, as well as the minimum and maximum width of the convex hull. The minimum and the maximum width of the convex hull are calculated using a rotating caliper algorithm and are often called the Feret diameters.
Convex Area
This calculates the area enclosed by the convex hull.
double area = objects[0].to_point_list().get_convex_hull().get_area();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
double area = b.get_convex_area();
The convex area is always the same or bigger than the area of the original region. For the example image one can see right away that it is certainly bigger.
The convex area value of the blob in picture blob.png is 2325.5.
Perforation
This calculates the perforation of the region.
blob_features b = objects[0];
double perforation = b.get_perforation();
The perforation p is calculated from the region area a and the area of the holes ah according to this formula:
$$p = \frac { { a }_{ h } }{ a }$$
The perforation is zero for a region that has no holes, and it increases the more holes the region has. The perforation is scale invariant.
The perforation value of the blob in picture blob.png is 1.78.
Convexity
This calculates the convexity of the region.
blob_features b = objects[0];
double convexity = b.get_convexity();
The convexity c is calculated from the region area a and the convex area ac according to this formula:
$$c = \frac { a }{ { a }_{ c } }$$
The convexity is 1 for a region that already is convex. It is smaller than 1 for non-convex regions. The convexity is scale invariant.
The convexity value of the blob in picture blob.png is 0.36.
Convex Perimeter
This calculates the perimeter of the convex hull polygon.
double perimeter = objects[0].to_point_list().get_convex_hull().get_perimeter();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
double perimeter = b.get_convex_perimeter();
The convex perimeter value of the blob in picture blob.png is 205.14.
Minimum Feret Diameter
This calculates the minimum feret diameter of the convex hull polygon. The minimum feret diameter is calculated using a rotating calipers algorithm.
double min_feret = objects[0].to_point_list().get_convex_hull().get_minimum_width();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
double min_feret = b.get_minimum_feret();

The minimum feret diameter value of the blob in picture blob.png is 31.76.
Maximum Feret Diameter
This calculates the maximum feret diameter of the convex hull polygon. The maximum feret diameter is calculated using a rotating calipers algorithm.
double max_feret = objects[0].to_point_list().get_convex_hull().get_maximum_width();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
double max_feret = b.get_maximum_feret();

The maximum feret diameter value of the blob in picture blob.png is 82.71.
Minimum Bounding Circle
This calculates the smallest bounding circle of the region.
blob_features b = objects[0];
circle disc = *b.get_minimum_bounding_circle();

Inner Contour
This calculates a contour of the object that is a counter-clockwise chain code of object boundary pixels. The inner contour exclusively lies on object pixels and is an 8-connected contour.
chain_code contour = objects[0].get_inner_contour();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
chain_code contour = *b.get_inner_contour();

Inner Contour Perimeter
This calculates the object perimeter using the inner contour.
double perimeter = objects[0].get_inner_contour().get_contour_length();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
double perimeter = b.get_inner_contour_perimeter();
The inner contour is 8-connected. The contour length sums the contour segments for each of the chain code directions. Horizontal and vertical directions count as 1, diagonal directions count as $\sqrt{2}$.
Outer Contour
This calculates a contour of the object that is a clockwise chain code of background pixels just outside the object. The outer contour exclusively lies on background pixels and is a 4-connected contour.
chain_code contour = objects[0].get_outer_contour();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
chain_code contour = *b.get_outer_contour();

Outer Contour Perimeter
This calculates the object perimeter using the outer contour.
double perimeter = objects[0].get_outer_contour().get_contour_length();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
double perimeter = b.get_outer_contour_perimeter();
The outer contour is 4-connected. The contour length sums the contour segments for each of the chain code directions. Horizontal and vertical directions count as 1, diagonal directions are not used.
Region-based Moments
This calculates the region-based raw moments. There is a specific chapter about moments that you can consult, if you want to learn more about moments and how they are implemented. Here, in the context of blob analysis, they are documented only briefly.
moments raw = objects[0].get_raw_moments();
Another way to calculate this feature is with the blob_features class:
blob_features b = objects[0];
moments raw = *b.get_region_raw_moments ();
The region-based raw moments are calculated up to the third order, according to the following formula:
Mpq = ∑x∑yxpyq
The moments class has the properties m00, m10, m01, m20, m11, m02, m30, m21, m12 and m03 to read the respective moment.
Region-based Normalized Moments
This calculates the region-based normalized moments.
blob_features b = objects[0];
normalized_moments nm = *b.get_normalized_moments ();
They are calculated up to the third order, according to the following formula:
$${N}_{{pq}}={\frac{{M}_{{pq}}}{{M}_{{00}}}}$$
Normalized moments are invariant with respect to scaling, but are not invariant with respect to translation and rotation.
You can use the properties n10, n01, n20, n11, n02, n30, n21, n12 and n03 to read the respective normalized moments.
Region-based Centroid
This calculates the region-based object centroid. The centroid is a property of the normalized moments.
blob_features b = objects[0];
point<double> centroid = *b.get_region_centroid();
The centroid is the center of gravity and calculated according to the following formula:
$$\left( \begin{matrix} x \\ y \end{matrix} \right) =\left( \begin{matrix} \frac { { N }_{ 10 } }{ { N }_{ 00 } } \\ \frac { { N }_{ 01 } }{ { N }_{ 00 } } \end{matrix} \right)$$

The centroid value of the blob in picture blob.png is (47.02, 40.61).
Region-based Central Moments
This calculates the region-based central moments.
blob_features b = objects[0];
central_moments cm = *b.get_region_central_moments ();
They are calculated up to the third order according to the following formula:
$${ \mu }_{ pq }=\frac { 1 }{ { M }_{ 00 } } \sum _{ x }^{ }{ \sum _{ y }^{ }{ { (x-\overline { x } ) }^{ p }{ (y-\overline { y } ) }^{ q } } }$$
Central moments are invariant with respect to translation, but are not invariant with respect to rotation. You can use the properties mu20, mu11, mu02, mu30, mu21, mu12 and mu03 to read the respective central moments.
Region-based Equivalent Ellipse
This calculates the region_based equivalent ellipse of the object. The equivalent ellipse is built by combining properties from the normalized and the central moments.
blob_features b = objects[0];
ellipse equivalent_ellipse = b.get_region_equivalent_ellipse();

Region-based Scale Invariant Moments
This calculates the region-based scale-invariant moments.
blob_features b = objects[0];
scale_invariant_moments sim = *b.get_scale_invariant_moments();
They are calculated up to the third order according to the following formula:
$${\eta}_{{pq}}={\frac{{\mu}_{{pq}}}{{\mu}_{{00}}^{\frac{p+q}{2}+1}}}$$
Scale-invariant moments are invariant with respect to translation and scaling, but are not invariant with respect to rotation.
You can use the properties eta20, eta11, eta02, eta30, eta21, eta12 and eta03 to read the respective scale invariant moments.
Region-based Hu Moments
This calculates the region-based Hu moments. The formulas are described in the chapter about moments.
blob_features b = objects[0];
hu_moments hm = *b.get_hu_moments();
Hu's moments are invariant with respect to translation, scaling and rotation.
The formulas for Hu's moments are:
$$\begin{aligned} {\phi}_{{1}} & = & {{\eta}_{{20}}+{\eta}_{{02}}} \\ {\phi}_{{2}} & = & {({\eta}_{{20}}-{\eta}_{{02}})^2+4{\eta}_{{11}}^2} \\ {\phi}_{{3}} & = & {({\eta}_{{30}}-3{\eta}_{{12}})^2+(3{\eta}_{{21}}-{\eta}_{{03}})^2} \\ {\phi}_{{4}} & = & {({\eta}_{{30}}+{\eta}_{{12}})^2+({\eta}_{{21}}+{\eta}_{{03}})^2} \\ {\phi}_{{5}} & = & {({\eta}_{{30}}-3{\eta}_{{12}})({\eta}_{{30}}+{\eta}_{{12}})\left[({\eta}_{{30}}+{\eta}_{{12}})^2-3({\eta}_{{21}}+{\eta}_{{03}})^2\right]} \nonumber \\ & & {}{+(3{\eta}_{{21}}-{\eta}_{{03}})({\eta}_{{21}}+{\eta}_{{03}})\left[3({\eta}_{{30}}+{\eta}_{{12}})^2-({\eta}_{{21}}+{\eta}_{{03}})^2\right]} \\ {\phi}_{{6}} & = & {({\eta}_{{20}}-{\eta}_{{02}})\left[({\eta}_{{30}}+{\eta}_{{12}})^2-({\eta}_{{21}}+{\eta}_{{03}})^2\right]} \nonumber \\ & & {}{+4{\eta}_{{11}}({\eta}_{{30}}+{\eta}_{{12}})({\eta}_{{21}}+{\eta}_{{03}})} \\ {\phi}_{{7}} & = & {(3{\eta}_{{21}}-3{\eta}_{{03}})({\eta}_{{30}}+{\eta}_{{12}})\left[({\eta}_{{30}}+{\eta}_{{12}})^2-3({\eta}_{{21}}+{\eta}_{{03}})^2\right]} \nonumber \\ & & {}{-({\eta}_{{30}}-3{\eta}_{{12}})({\eta}_{{21}}+{\eta}_{{03}})\left[3({\eta}_{{30}}+{\eta}_{{12}})^2-({\eta}_{{21}}+{\eta}_{{03}})^2\right]}\end{aligned}$$
You can use the properties phi1, phi2, phi3, phi4, phi5, phi6 and phi7 to read the respective Hu moment.
Region-based Flusser Moments
This calculates the region-based Flusser moments. The formulas are described in the chapter about moments.
blob_features b = objects[0];
flusser_moments fm = *b.get_flusser_moments();
Flusser's moments are invariant with respect to affine transformations.
The formulas for Flusser's moments are:
$$\begin{aligned} {I}_{{1}} & = & {\frac{{\mu}_{{20}}{\mu}_{{02}}-{\mu}_{{11}}^2}{{\mu}_{{00}}^4}} \\ {I}_{{2}} & = & {\frac{{\mu}_{{30}}^2{\mu}_{{03}}^2-6{\mu}_{{30}}{\mu}_{{21}}{\mu}_{{12}}{\mu}_{{03}}+4{\mu}_{{30}}{\mu}_{{12}}^3+4{\mu}_{{21}}^3{\mu}_{{03}}-3{\mu}_{{21}}^2{\mu}_{{12}}^2}{{\mu}_{{00}}^10}} \\ {I}_{{3}} & = & {\frac{{\mu}_{{20}}({\mu}_{{21}}{\mu}_{{03}}-{\mu}_{{12}}^2)-{\mu}_{{11}}({\mu}_{{30}}{\mu}_{{03}}-{\mu}_{{21}}{\mu}_{{12}}))}{{\mu}_{{00}}^7}} \nonumber \\ & & {+\frac{{\mu}_{{02}}({\mu}_{{30}}{\mu}_{{12}}-{\mu}_{{21}}^2)}{{\mu}_{{00}}^7}} \\ {I}_{{4}} & = & {\frac{{\mu}_{{20}}^3{\mu}_{{03}}^2-6{\mu}_{{20}}^2{\mu}_{{11}}{\mu}_{{12}}({\mu}_{{03}}-6{\mu}_{{20}}^2{\mu}_{{02}}{\mu}_{{21}}){\mu}_{{03}}}{{\mu}_{{00}}^{11}}} \nonumber \\ & & {+\frac{9{\mu}_{{20}}^2{\mu}_{{02}}{\mu}_{{12}}^2+12{\mu}_{{20}}{\mu}_{{11}}^2{\mu}_{{21}}{\mu}_{{03}}+6{\mu}_{{20}}{\mu}_{{11}}{\mu}_{{02}}{\mu}_{{30}}{\mu}_{{03}}}{{\mu}_{{00}}^{11}}} \nonumber \\ & & {-\frac{18{\mu}_{{20}}{\mu}_{{11}}{\mu}_{{02}}{\mu}_{{21}}{\mu}_{{12}}+8{\mu}_{{11}}^3{\mu}_{{30}}{\mu}_{{03}}+6{\mu}_{{20}}{\mu}_{{02}}^2{\mu}_{{30}}{\mu}_{{12}}}{{\mu}_{{00}}^{11}}} \nonumber \\ & & {+\frac{9{\mu}_{{20}}{\mu}_{{02}}^2{\mu}_{{21}}^2+12{\mu}_{{11}}^2{\mu}_{{02}}{\mu}_{{30}}{\mu}_{{12}}-6{\mu}_{{11}}{\mu}_{{02}}^2{\mu}_{{30}}{\mu}_{{21}}}{{\mu}_{{00}}^{11}}} \nonumber \\ & & {+\frac{{\mu}_{{02}}^3{\mu}_{{30}}^2}{{\mu}_{{00}}^{11}}}\end{aligned}$$
You can use the properties i1, i2, i3, and i4 to read the respective flusser moments.
Holes
This calculates the holes of the region.
blob_features b = objects[0];
region_list rl = *b.get_holes();
The holes are returned as a region_list of connected components. Using this region_list, you can do another blob analysis on the holes, if necessary. If you need just the number of holes or the area of the holes, you can use the Number of Holes or Area of Holes features.
Number of Holes
This calculates the number of holes of the region.
blob_features b = objects[0];
int n = *b.get_number_of_holes();
The number of holes value of the blob in picture blob.png is 5.
Area of Holes
This calculates the total area of the holes of the region.
blob_features b = objects[0];
size_t area = *b.get_area_of_holes();
The area of holes value of the blob in picture blob.png is 244.
Fiber Length
This calculates an approximation of a fiber length. This measurement is only valid for elongated objects. The fiber length is approximated as half the perimeter.
blob_features b = objects[0];
double length = *b.get_fiber_length();
Fiber Width
This calculates an approximation of a fiber width. The fiber width is approximated as twice the maximum value of the distance transform.
blob_features b = objects[0];
double width = *b.get_fiber_width();
Bounding Rectangle
This calculates a bounding rectangle of the region.
blob_features b = objects[0];
rectangle r = *b.get_bounding_rectangle();

The rectangle has the same orientation as the equivalent ellipse.
Minimum Area Bounding Rectangle
This calculates a bounding rectangle of the region.
blob_features b = objects[0];
rectangle r = *b.get_minimum_area_bounding_rectangle();

The result is the rectangle with the smallest area bounding the region.
Minimum Perimeter Bounding Rectangle
This calculates a bounding rectangle of the region.
blob_features b = objects[0];
rectangle r = *b.get_minimum_perimeter_bounding_rectangle();
The result is the rectangle with the smallest perimeter bounding the region.

Pixel Based Features
In contrast to region-based features, pixel-based features use the pixel values in addition to the region definition. Pixel-based features are necessary since some features, such as the minimum pixel value, cannot be calculated given the region alone. However, the calculation of pixel-based features is slower than the calculation of region-based features.
Minimum Position
This calculates the minimum position value.
blob_features b(gray.get_view(), objects[0]);
point_3d<int> minimum = *b.get_minimum_position();
When calculating the minimum position for color images, the color is treated as a vector and the minimum is determined by comparing the Euclidean vector length.
The minimum position value of the blob in picture pair
blob.png/blobmono.png is (x = 38 y = 54 z = 0).
The minimum position value of the blob in picture pair
blob.png/blobcolor.png is (x = 25 y = 68 z = 0).
Minimum
This calculates the minimum value.
blob_features b(gray.get_view(), objects[0]); pixel_type minimum = b.get_minimum();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is unsigned char, for image<rgb<double>>
it is rgb<double>.
When calculating the minimum for color images, the color is treated as a vector and the minimum is determined by comparing the Euclidean vector length.
There is also the Channel Minimum, which does determine the minimum channel by channel for color images.
The minimum value of the blob in picture pair blob.png/blobmono.png is
29.
The minimum value of the blob in picture pair blob.png/blobcolor.png
is (red = 32 green = 59 blue = 37).
Maximum Position
This calculates the maximum position value.
blob_features b(gray.get_view(), objects[0]);
point_3d<int> maximum = *b.get_maximum_position();
When calculating the minimum position for color images, the color is treated as a vector and the minimum is determined by comparing the Euclidean vector length.
The maximum position value of the blob in picture pair
blob.png/blobmono.png is (x = 80 y = 25 z = 0).
The maximum position value of the blob in picture pair
blob.png/blobcolor.png is (x = 67 y = 15 z = 0).
Maximum
This calculates the maximum value.
blob_features b(gray.get_view(), objects[0]);
pixel_type maximum = b.get_maximum();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is unsigned char, for image<rgb<double>>
it is rgb<double>.
When calculating the maximum for color images, the color is treated as a vector and the maximum is determined by comparing the Euclidean vector length.
There is also the Channel Maximum, which does determine the maximum channel by channel for color images.
The maximum value of the blob in picture pair blob.png/blobmono.png is
207. The maximum value of the blob in picture pair
blob.png/blobcolor.png is (red = 240 green = 218 blue = 203).
Total
This calculates the total value.
blob_features b(gray.get_view(), objects[0]);
float_pixel_type total = b.get_total();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is double, for image<rgb<double>> it
isrgb<double>.
The total is the sum of all pixel values of the object:
T = ∑I
The total value of the blob in picture pair blob.png/blobmono.png is
91963.
The total value of the blob in picture pair blob.png/blobcolor.png is
(red = 107558 green = 107465 blue = 103216).
Mean
This calculates the mean value.
blob_features b(gray.get_view(), objects[0]);
float_pixel_type mean = b.get_mean();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is double, for image<rgb<double>> it
isrgb<double>.
The mean is calculated according to the following formula:
$$M = \frac { T }{ n }$$
where T is the total value and n is the number of pixels (i.e. the area) of the blob.
The mean value of the blob in picture pair blob.png/blobmono.png is
110.135. The mean value of the blob in picture
pair blob.png/blobcolor.png is (red = 128.812 green = 128.701 blue =
123.612).
Standard Deviation
This calculates the standard deviation value. Standard deviation is a measure of how wide the distribution of values is.
blob_features b(gray.get_view(), objects[0]);
float_pixel_type stddev = b.get_standard_deviation();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is double, for image<rgb<double>> it
isrgb<double>.
The standard deviation is calculated according to the following formula:
$$\sigma = \sqrt {\frac { 1 }{ n } \sum {}{(I-E)^2}}$$
The standard deviation value of the blob in picture pair
blob.png/blobmono.png is 49.447.
The standard deviation value of the blob in picture pair
blob.png/blobcolor.png is (red = 75.3174 green = 71.9041 blue =
42.301).
Skewness
This calculates the skewness value. Skewness can be understood as a measure of asymmetry in the distribution, i.e. how much it deviates from a gauss-shaped curve.
blob_features b(gray.get_view(), objects[0]);
float_pixel_type mean = b.get_mean();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is double, for image<rgb<double>> it
isrgb<double>.
The skewness is calculated according to the following formula:
$$\sigma = \sqrt[3]{\frac { 1 }{ n } \sum {}{(I-E)^3}}$$
The skewness value of the blob in picture pair blob.png/blobmono.png
is 30.6915.
The skewness value of the blob in picture pair blob.png/blobcolor.png
is (red = -20.3929 green = 21.2389 blue = 20.5604).
Channel Minimum
This calculates the channel-wise minimum value.
blob_features b(gray.get_view(), objects[0]);
pixel_type minimum = b.get_channel_minimum();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is unsigned char, for image<rgb<double>>
it is rgb<double>.
When calculating the channel minimum for color images, the color is treated as three scalars, and for each one a minimum value is determined.
There is also the Minimum, which does determine the minimum by comparing vector length for color images.
The channel minimum value of the blob in picture pair
blob.png/blobmono.png is 29.
The channel minimum value of the blob in picture pair
blob.png/blobcolor.png is (red = 32 green = 59 blue = 37).
Channel Maximum
This calculates the channel-wise maximum value.
blob_features b(gray.get_view(), objects[0]);
pixel_type maximum = b.get_channel_maximum();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is unsigned char, for image<rgb<double>>
it is rgb<double>.
When calculating the channel maximum for color images, the color is treated as three scalars, and for each one a maximum value is determined.
There is also the Maximum, which does determine the maximum by comparing vector length for color images.
The channel maximum value of the blob in picture pair
blob.png/blobmono.png is 207.
The channel maximum value of the blob in picture pair
blob.png/blobcolor.png is (red = 255 green = 219 blue = 220).
Contrast
This calculates the channel-wise contrast.
blob_features b(gray.get_view(), objects[0]);
float_pixel_type contrast = b.get_contrast();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is double, for image<rgb<double>> it
isrgb<double>.
The contrast is calculated according to the following formula:
$$c=\frac {max}{min + 1}$$
Weber Contrast
This calculates the channel-wise contrast acoording to Weber's formula.
blob_features b(gray.get_view(), objects[0]);
float_pixel_type contrast = b.get_weber_contrast();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is double, for image<rgb<double>> it
isrgb<double>.
The contrast is calculated according to the following formula:
$$c=\frac {max - min}{min + 1}$$
Michelson Contrast
This calculates the channel-wise contrast acoording to Michelson's formula.
blob_features b(gray.get_view(), objects[0]);
float_pixel_type contrast = b.get_mihcelson_contrast();
The resulting type depends on the image type, i.e. for
image<unsigned char> it is double, for image<rgb<double>> it
isrgb<double>.
The contrast is calculated according to the following formula:
$$c=\frac {max - min}{max + min + 1}$$
Horizontal Profile
This calculates the horizontal profile.
blob_features b(grey.get_view(), objects[0]);
profile<pixel_type> p = *b.get_horizontal_profile();
Vertical Profile
This calculates the vertical profile.
blob_features b(grey.get_view(), objects[0]);
profile<pixel_type> p = *b.get_vertical_profile();
Histogram
This calculates the histogram.
blob_features b(grey.get_view(), objects[0]);
histogram_type p = *b.get_histogram();
Pixel-based Moments
This calculates the pixel-based raw moments. There is a specific chapter about moments that you can consult, if you want to learn more about moments and how they are implemented. Here, in the context of blob analysis, they are documented only briefly.
blob_features b(grey.get_view(), objects[0]);
moments raw = *b.get_pixel_raw_moments();
The pixel-based raw moments are calculated up to the third order, according to the following formula:
Mpq = ∑x∑yxpyqIxy
Pixel based moments are similar to region-based moments, but they use pixel values in addition. The brighter a pixel is the more weight it has in the calculation of the moment.
If color images are used, they are converted to monochrome, before the respective pixel-based moment is calculated. The moments class has the properties m00, m10, m01, m20, m11, m02, m30, m21, m12 and m03 to read the respective moment.
Pixel-based Normalized Moments
This calculates the pixel-based normalized moments.
blob_features b(grey.get_view(), objects[0]);
normalized_moments nm = *b.get_pixel_normalized_moments();
They are calculated up to the third order, according to the following formula:
$${N}_{{pq}}={\frac{{M}_{{pq}}}{{M}_{{00}}}}$$
Pixel based moments are similar to region-based moments, but they use pixel values in addition. The brighter a pixel is the more weight it has in the calculation of the moment.
If color images are used, they are converted to monochrome, before the respective pixel-based moment is calculated. You can use the properties n10, n01, n20, n11, n02, n30, n21, n12 and n03 to read the respective normalized moments.
Pixel-based Centroid
This calculates the pixel-based object centroid. The centroid is a property of the normalized moments.
blob_features b(grey.get_view(), objects[0]);
point<double> centroid = b.get_pixel_centroid();
The centroid is the center of gravity and calculated according to the following formula:
$$\left( \begin{matrix} x \\ y \end{matrix} \right) =\left( \begin{matrix} \frac { { N }_{ 10 } }{ { N }_{ 00 } } \\ \frac { { N }_{ 01 } }{ { N }_{ 00 } } \end{matrix} \right)$$
![]()
Pixel based centroids are similar to region-based centroids, but they use pixel values in addition. The brighter a pixel is the more weight it has in the calculation of the moment.
If color images are used, they are converted to monochrome, before the respective pixel-based moment is calculated.
Pixel-based Central Moments
This calculates the pixel-based central moments.
blob_features b(grey.get_view(), objects[0]);
central_moments cm = *b.get_pixel_central_moments();
They are calculated up to the third order according to the following formula:
$${ \mu }_{ pq }=\frac { 1 }{ { M }_{ 00 } } \sum _{ x }^{ }{ \sum _{ y }^{ }{ { (x-\overline { x } ) }^{ p }{ (y-\overline { y } ) }^{ q }{ I }_{ xy } } }$$
Central moments are invariant with respect to translation, but are not invariant with respect to rotation. Pixel based moments are similar to region-based moments, but they use pixel values in addition. The brighter a pixel is the more weight it has in the calculation of the moment.
If color images are used, they are converted to monochrome, before the respective pixel-based moment is calculated. You can use the properties mu20, mu11, mu02, mu30, mu21, mu12 and mu03 to read the respective central moments.
Pixel-based Equivalent Ellipse
This calculates the pixel-based equivalent ellipse of the object. The equivalent ellipse is built by combining properties from the normalized and the central moments.
blob_features b(grey.get_view(), objects[0]);
ellipse equivalent_ellipse = b.get_pixel_equivalent_ellipse();
Pixel based equivalent ellipses are similar to region-based equivalent ellipses, but they use pixel values in addition. The brighter a pixel is the more weight it has in the calculation of the moment.
If color images are used, they are converted to monochrome, before the respective pixel-based moment is calculated.
Pixel-based Scale Invariant Moments
This calculates the pixel-based scale-invariant moments.
blob_features b(grey.get_view(), objects[0]);
scale_invariant_moments sim = *b.get_pixel_scale_invariant_moments();
They are calculated up to the third order, according to the following formula:
$${\eta}_{{pq}}={\frac{{\mu}_{{pq}}}{{\mu}_{{00}}^{\frac{p+q}{2}+1}}}$$
Scale-invariant moments are invariant with respect to translation and scaling, but are not invariant with respect to rotation.
Pixel based moments are similar to region-based moments, but they use pixel values in addition. The brighter a pixel is the more weight it has in the calculation of the moment.
If color images are used, they are converted to monochrome, before the respective pixel-based moment is calculated. You can use the properties eta20, eta11, eta02, eta30, eta21, eta12 and eta03 to read the respective scale invariant moments.
Pixel-based Hu Moments
This calculates the pixel-based Hu moments.
blob_features b(grey.get_view(), objects[0]);
hu_moments hm = *b.get_pixel_hu_moments();
The formulas for Hu's moments are:
$$\begin{aligned} {\phi}_{{1}} & = & {{\eta}_{{20}}+{\eta}_{{02}}} \\ {\phi}_{{2}} & = & {({\eta}_{{20}}-{\eta}_{{02}})^2+4{\eta}_{{11}}^2} \\ {\phi}_{{3}} & = & {({\eta}_{{30}}-3{\eta}_{{12}})^2+(3{\eta}_{{21}}-{\eta}_{{03}})^2} \\ {\phi}_{{4}} & = & {({\eta}_{{30}}+{\eta}_{{12}})^2+({\eta}_{{21}}+{\eta}_{{03}})^2} \\ {\phi}_{{5}} & = & {({\eta}_{{30}}-3{\eta}_{{12}})({\eta}_{{30}}+{\eta}_{{12}})\left[({\eta}_{{30}}+{\eta}_{{12}})^2-3({\eta}_{{21}}+{\eta}_{{03}})^2\right]} \nonumber \\ & & {}{+(3{\eta}_{{21}}-{\eta}_{{03}})({\eta}_{{21}}+{\eta}_{{03}})\left[3({\eta}_{{30}}+{\eta}_{{12}})^2-({\eta}_{{21}}+{\eta}_{{03}})^2\right]} \\ {\phi}_{{6}} & = & {({\eta}_{{20}}-{\eta}_{{02}})\left[({\eta}_{{30}}+{\eta}_{{12}})^2-({\eta}_{{21}}+{\eta}_{{03}})^2\right]} \nonumber \\ & & {}{+4{\eta}_{{11}}({\eta}_{{30}}+{\eta}_{{12}})({\eta}_{{21}}+{\eta}_{{03}})} \\ {\phi}_{{7}} & = & {(3{\eta}_{{21}}-3{\eta}_{{03}})({\eta}_{{30}}+{\eta}_{{12}})\left[({\eta}_{{30}}+{\eta}_{{12}})^2-3({\eta}_{{21}}+{\eta}_{{03}})^2\right]} \nonumber \\ & & {}{-({\eta}_{{30}}-3{\eta}_{{12}})({\eta}_{{21}}+{\eta}_{{03}})\left[3({\eta}_{{30}}+{\eta}_{{12}})^2-({\eta}_{{21}}+{\eta}_{{03}})^2\right]}\end{aligned}$$
Hu's moments are invariant with respect to translation, scaling and rotation.
Pixel based moments are similar to region-based moments, but they use pixel values in addition. The brighter a pixel is the more weight it has in the calculation of the moment.
If color images are used, they are converted to monochrome, before the respective pixel-based moment is calculated. You can use the properties phi1, phi2, phi3, phi4, phi5, phi6 and phi7 to read the respective Hu moment.
Pixel-based Flusser Moments
This calculates the pixel-based Flusser moments.
blob_features b(grey.get_view(), objects[0]);
flusser_moments fm = *b.get_pixel_flusser_moments();
The formulas for Flusser's moments are:
$$\begin{aligned} {I}_{{1}} & = & {\frac{{\mu}_{{20}}{\mu}_{{02}}-{\mu}_{{11}}^2}{{\mu}_{{00}}^4}} \\ {I}_{{2}} & = & {\frac{{\mu}_{{30}}^2{\mu}_{{03}}^2-6{\mu}_{{30}}{\mu}_{{21}}{\mu}_{{12}}{\mu}_{{03}}+4{\mu}_{{30}}{\mu}_{{12}}^3+4{\mu}_{{21}}^3{\mu}_{{03}}-3{\mu}_{{21}}^2{\mu}_{{12}}^2}{{\mu}_{{00}}^10}} \\ {I}_{{3}} & = & {\frac{{\mu}_{{20}}({\mu}_{{21}}{\mu}_{{03}}-{\mu}_{{12}}^2)-{\mu}_{{11}}({\mu}_{{30}}{\mu}_{{03}}-{\mu}_{{21}}{\mu}_{{12}}))}{{\mu}_{{00}}^7}} \nonumber \\ & & {+\frac{{\mu}_{{02}}({\mu}_{{30}}{\mu}_{{12}}-{\mu}_{{21}}^2)}{{\mu}_{{00}}^7}} \\ {I}_{{4}} & = & {\frac{{\mu}_{{20}}^3{\mu}_{{03}}^2-6{\mu}_{{20}}^2{\mu}_{{11}}{\mu}_{{12}}({\mu}_{{03}}-6{\mu}_{{20}}^2{\mu}_{{02}}{\mu}_{{21}}){\mu}_{{03}}}{{\mu}_{{00}}^{11}}} \nonumber \\ & & {+\frac{9{\mu}_{{20}}^2{\mu}_{{02}}{\mu}_{{12}}^2+12{\mu}_{{20}}{\mu}_{{11}}^2{\mu}_{{21}}{\mu}_{{03}}+6{\mu}_{{20}}{\mu}_{{11}}{\mu}_{{02}}{\mu}_{{30}}{\mu}_{{03}}}{{\mu}_{{00}}^{11}}} \nonumber \\ & & {-\frac{18{\mu}_{{20}}{\mu}_{{11}}{\mu}_{{02}}{\mu}_{{21}}{\mu}_{{12}}+8{\mu}_{{11}}^3{\mu}_{{30}}{\mu}_{{03}}+6{\mu}_{{20}}{\mu}_{{02}}^2{\mu}_{{30}}{\mu}_{{12}}}{{\mu}_{{00}}^{11}}} \nonumber \\ & & {+\frac{9{\mu}_{{20}}{\mu}_{{02}}^2{\mu}_{{21}}^2+12{\mu}_{{11}}^2{\mu}_{{02}}{\mu}_{{30}}{\mu}_{{12}}-6{\mu}_{{11}}{\mu}_{{02}}^2{\mu}_{{30}}{\mu}_{{21}}}{{\mu}_{{00}}^{11}}} \nonumber \\ & & {+\frac{{\mu}_{{02}}^3{\mu}_{{30}}^2}{{\mu}_{{00}}^{11}}}\end{aligned}$$
Flusser's moments are invariant with respect to affine transformations.
Pixel based moments are similar to region-based moments, but they use pixel values in addition. The brighter a pixel is the more weight it has in the calculation of the moment.
If color images are used, they are converted to monochrome, before the respective pixel-based moment is calculated. You can use the properties i1, i2, i3, and i4 to read the respective usser moments.
Object Filtering
Filtering is the process of removing objects that satisfy a certain condition. Examples of filtering are removal of small objects caused by noise, or removal of objects touching the image border, because these objects would be partial anyway and their features would be wrong.
Here is an example that removes objects with an area smaller than 5 pixels:
rl = rl.filter([] (region & r) -> bool { return r.get_area() < 5; });
Here is another example that removes objects which are touching the left border:
rl = rl.filter([] (region & r) -> bool { return r.get_left() <= 0; });
By specifying a lambda, you can easily create various filter criteria.
Calculation Hierarchy
The order in which the features were presented to you so far may have looked arbitrary to you. However, the order was guided by the hierarchy used to calculate the features.
Feature calculation starts with the region, and many features can be easily calculated using the region (e.g. area, left, etc.). However, calculation of other features is more complicated, and they are calculated indirectly. First the region is converted into a different representation, and then this other representation is used to calculate the feature. For example, the convex hull of the region is needed before the convex area, convex perimeter and minimum and maximum feret diameters can be calculated. Sometimes, this needs more than one step, such as with the moments (see the chapter about moments, to see how they are related to each other), which are needed to calculate the center of gravity or the equivalent ellipse parameters, such as orientation or eccentricity.

Convenience Classes
The blob_features and blob_features_list classes are convenience
classes that allow you to calculate features without having to know
exactly how they are calculated internally. The blob_features_list
class provides parallelization on the blob level, i.e. features for
multiple blobs can be calculated in parallel. The blob_features class
also caches features that have been already calculated, in order to
avoid duplicate calculation.
However, it still helps to know what exactly is calculated and how, in order to understand the algorithms runtime behavior.
Benchmarks
We have provided a sample program called time_blob_analysis which can be used to time the calculation of the various features. The times are calculated for each feature in isolation, i.e. they do not reflect the time savings you would gain, if some feature is already partly calculated (i.e. if you calculate the convex perimeter, and have previously calculated the convex hull, this will save considerable time, since the shared portions of the calculation are not done twice).
This is the picture used in the benchmark program:

Here are the results of the time_blob_analysis program from my machine (Lenovo Laptop with Intel Core i7-2820QM CPU running at 2.3 GHz):
Blob Analysis Benchmark
Image: grains.tif
Size: 640 x 480
Number of blobs: 93
Mean blob area: 786.849
| Operation | msec |
| Segmentation | 0.92367 |
| Connected components analysis | 8.54171 |
Region-based blob features:
| Operation | msec |
| Area | 0.000192107 |
| Left | 0.000307371 |
| Right | 0.000201712 |
| Top | 0.000172896 |
| Bottom | 0.000302569 |
| Width | 0.000518689 |
| Height | 0.00028816 |
| Aspect Ratio | 0.000662769 |
| Bounds | 0.000739612 |
| Perimeter | 0.0963032 |
| Compactness | 0.0724195 |
| Convex hull | 0.197909 |
| Convex area | 0.171965 |
| Perforation | 0.0116224 |
| Convexity | 0.216019 |
| Convex perimeter | 0.223185 |
| Minimum feret diameter | 0.181483 |
| Maximum feret diameter | 0.154262 |
| Minimum bounding circle | 0.228378 |
| Inner contour | 0.00650762 |
| Inner contour perimeter | 0.00738651 |
| Outer contour | 0.00396221 |
| Outer contour perimeter | 0.003943 |
| Region-based raw moments | 0.000763625 |
| Region-based normalized moments | 0.000619545 |
| Region-based centroid | 0.00068198 |
| Region-based central moments | 0.000653164 |
| Region-based equivalent ellipse | 0.000869284 |
| Region-based scale-invariant moments | 0.000893297 |
| Region-based hu moments | 0.000802047 |
| Region-based flusser moments | 0.000662769 |
| Holes | 0.0103689 |
| Number of Holes | 0.00924991 |
| Area of Holes | 0.00936517 |
| Fiber Length | 0.0801851 |
| Fiber Width | 0.00629148 |
| Bounding rectangle | 0.162821 |
| Minimum area bounding rectangle | 0.178055 |
| Minimum perimeter bounding rectangle | 0.169674 |
(Times are in msec per blob on average.)
Pixel-based blob features:
| Operation | msec |
| Minimum position | 0.00191627 |
| Minimum | 0.0016137 |
| Maximum position | 0.00167613 |
| Maximum | 0.00163771 |
| Total | 0.00242055 |
| Mean | 0.00160409 |
| Standard deviation | 0.00217561 |
| Skewness | 0.00225726 |
| Channel minimum | 0.00174817 |
| Channel maximum | 0.00164251 |
| Horizontal profile | 0.00903383 |
| Vertical profile | 0.00735289 |
| Histogram | 0.00690625 |
| Pixel-based raw moments | 0.0784997 |
| Pixel-based normalized moments | 0.0706569 |
| Pixel-based centroid | 0.0821401 |
| Pixel-based central moments | 0.0826492 |
| Pixel-based equivalent ellipse | 0.0829854 |
| Pixel-based scale-invariant moments | 0.0812612 |
| Pixel-based hu moments | 0.0729622 |
| Pixel-based flusser moments | 0.0816263 |




