Objects, Holes and their Features

Objects and holes are both represented by the class ECodedElement .NET Python, so they are managed in the same way and share the same functions. Use IsObject .NET Python or IsHole .NET Python to determine the type of the coded element.

Holes Construction

A hole is a set of connected pixels that is entirely surrounded by a parent object. A hole has no child. Objects inside a hole are considered to be separate objects.

To get the holes of a specific object, use GetHoles .NET Python.

With an object selection, you can also add the holes of all the objects of a coded image using EObjectSelection::AddHoles .NET Python and add the holes of all the objects of the selection using EObjectSelection::AddHolesOfSelectedObjects .NET Python.

Raw image Raw image
Encoding the white layer (3 objects and 3 holes) Encoding the white layer (3 objects and 3 holes)
Encoding the black layer (4 objects and 3 holes) Encoding the black layer (4 objects and 3 holes)

See also

See the code snippets showing how to extract the holes from the objects.

Features

EasyObject can compute various features for each object and use these features for filtering or sorting.

There are two main categories of features:

  • Cacheable features that will be computed only once on the first invocation. These features corresponds to methods prefixed with Get in C++ or properties in C# and Python.

  • Non-cacheable features that will be reevaluated at every invocation. These features corresponds to method prefixed with Compute.

    • Note that these features usually requires an additional parameter or are slower to compute.

Most features will be expressed in the frame of reference used when encoding the image. However, some features are computed at the pixel level. In the tables below, the frame of reference is indicated in the corresponding column:

  • Frame means that the result is expressed with regard to the frame that was used when encoding the image.

  • Pixel means that local pixel coordinates are used, irrespective of the frame.

Gravity Center

Feature

Method

Data type

Frame of reference

Gravity center
(X and Y)

GetGravityCenter .NET Python
GetGravityCenterX .NET Python
GetGravityCenterY .NET Python

EPoint .NET Python
Float

frame

Weighted gravity center
(X and Y)

ComputeWeightedGravityCenter .NET Python

EPoint .NET Python

frame

../../../_images/feature_gravity_center.webp

Gravity center

The gravity center is the average of the coordinates, expressed in a frame of reference, of all the pixel of the blob:

\[ G = \frac{1}{N} \sum_{i=1}^N p_i \]

The weighted gravity center requires an input image and is the average of the coordinates, expressed in a frame of reference, of all the pixel of the blob, weighted by the corresponding pixel value of the given image:

\[ G_w = \frac{\sum_{i=1}^N I(p_i) p_i}{\sum_{i=1}^N I(p_i)} \]

Size and Extent

A Feret box is a rectangle with the minimum surface rotated at a specified angle that contains all the pixels center points of an object.

  • Bounding box is the Feret box at 0°.

  • Minimum enclosing rectangle is the Feret box with the minimum surface across all the possible angles.

  • Width of a Feret box rectangle is the length of the rectangle side that exhibits the smallest angle with the X-axis. This is NOT necessarily the smallest side!

  • The height of a Feret box rectangle is the length of the other side of the rectangle.

  • Use ComputeFeretBox .NET Python to compute a Feret box with an arbitrary angle.

    • The angle is measured clockwise from the X axis to the width side of the rectangle as shown in the image below:

      ../../../_images/EasyObject_FeretAngle.svg

      Feret box angle.

Miscellaneous

Feature

Method

Data type

Frame of reference

Starting point of the object contour
(X and Y)

GetContour .NET Python
GetContourX .NET Python
GetContourY .NET Python

EPoint .NET Python
int

pixel

Path of the object contour

GetContourPath .NET Python

EPathVector .NET Python

pixel

Pixel gray-level value
(min and max)

ComputePixelMax .NET Python
ComputePixelMin .NET Python

EBW8 .NET Python

n.a.

Note

The object perimeter in pixels can be measured indirectly by tracing the object contour with contouring methods and counting the pixels.

Moments and Ellipse of Inertia

../../../_images/feature_ellipse_of_inertia.webp

Ellipse of inertia

Feature

Method

Data type

Frame of reference

Eccentricity of the ellipse of inertia

GetEccentricity .NET Python

float

frame

Moments

GetCentralMoment .NET Python
GetMoment .NET Python
GetNormalizedCentralMoment .NET Python

float

frame

Ellipse
(angle, height, width)

GetEllipseAngle .NET Python
GetEllipseHeight .NET Python
GetEllipseWidth .NET Python

float

frame

Centered moments of inertia
(Sigma: X, XX, XY, Y, YY)

GetSigmaX .NET Python
GetSigmaXX .NET Python
GetSigmaXY .NET Python
GetSigmaY .NET Python
GetSigmaYY .NET Python

float

frame

Given \(N\) is the number of pixels of the blob, \(x_i\) and \(y_i\) the x and y coordinates of the \(i\)-th pixel of the blob, expressed in the frame of reference used to encode the image, the raw moment .NET Python of order \((p, q)\) is:

\[ M_{pq} = \sum_{i=1}^N x_i^p y_i^q. \]

The central moment .NET Python of order \((p, q)\) is:

\[ \mu_{pq} = \sum_{i=1}^N (x_i - \bar{x})^p (y_i - \bar{y})^q. \]

where \(\bar{x}\) and \(\bar{y}\) are the averages of all the \(x_i\) and \(y_i\).

The normalized central moment .NET Python of order \((p, q)\) is:

\[ \eta_{pq} = \frac{\mu_{pq}}{\mu_{00}^{1+\frac{p+q}{2}}}. \]

The centered moments of inertia \(\sigma_x\), \(\sigma_y\), and \(\sigma_{xy}\) are defined as:

\[ \sigma_x = \frac{\mu_{02}}{N} = \frac{1}{N} \sum_{i=1}^N (y_i - \bar{y})^2 \]
\[ \sigma_y = \frac{\mu_{20}}{N} = \frac{1}{N} \sum_{i=1}^N (x_i - \bar{x})^2\]
\[ \sigma_{xy} = \frac{\mu_{11}}{N} = \frac{1}{N} \sum_{i=1}^N (x_i - \bar{x}) (y_i - \bar{y}) \]

They can be grouped into the tensor of inertia:

\[\begin{split} \left( \begin{array}{cc} \sigma_x & \sigma_{xy} \\ \sigma_{xy} & \sigma_y \end{array}\right). \end{split}\]

\(\sigma_{xx}\) and \(\sigma_{yy}\) are the largest and smallest eigenvalues of this matrix and are also called the first and second centered principal axis of inertia:

\[ \sigma_{xx} = \frac{\sigma_x + \sigma_y}{2} + \frac{\sqrt{4\sigma_{xy}^2 + (\sigma_x - \sigma_y)^2}}{2} \]
\[ \sigma_{yy} = \frac{\sigma_x + \sigma_y}{2} - \frac{\sqrt{4\sigma_{xy}^2 + (\sigma_x - \sigma_y)^2}}{2}. \]

The width (\(w\)), height (\(h\)), and angle (\(\theta\)) of the ellipse of inertia are:

\[ w = 4 \sqrt{\sigma_{xx}} \]
\[ h = 4 \sqrt{\sigma_{yy}} \]
\[ \theta = \frac{1}{2}\arctan\left( \frac{2 \sigma_{xy}}{\sigma_x - \sigma_y} \right).\]

The eccentricity, or object elongation, is:

\[ \sqrt{1 - \frac{\sigma_{yy}}{\sigma_{xx}}}. \]

Note

The moments of inertia \(\sigma_x\), \(\sigma_y\), and \(\sigma_{xy}\) are also commonly noted as \(I_x\), \(I_y\), and \(I_{xy}\).

The moments of inertia around the X or Y axis are also the variance of the Y and X coordinates of the blobs respectively.

Convex Hull

The convex hull .NET Python hull of a shape is the convex polygon of minimum area that completely surrounds an object. The convex hull can be used to characterize the object footprint, as well as to observe concavities.

Given that the number of vertices of the convex hull is variable, they are stored in a EPathVector .NET Python container.

The convex hull is computed in pixel coordinates.

../../../_images/feature_convex_hull.webp

Convex hull.

Graphic Representation

The objects can be drawn onto the source image by means of ECodedImage2::Draw .NET Python. The following features also have a graphical representation that can be drawn by the means of ECodedImage2::DrawFeature .NET Python.

Drawable features and their default appearance.

Objects

Graphic

Bounding box

../../../_images/90005.jpg

Contour

../../../_images/90006.jpg

Convex hull

../../../_images/90007.jpg

Ellipse

../../../_images/90008.jpg

Feret box

../../../_images/90009.jpg

Feret box with an angle of 22°

../../../_images/90010.jpg

Feret box with an angle of 45°

../../../_images/90011.jpg

Feret box with an angle of 68°

../../../_images/90012.jpg

Gravity center

../../../_images/90013.jpg

Minimum enclosing rectangle

../../../_images/90014.jpg

Weighted gravity center

../../../_images/90015.jpg

Runs

For the sake of computational efficiency, the objects are described as lists of runs. A run is a sequence of adjacent pixels that share homogeneous properties (such as being above a given threshold). These runs are merged in objects by the image encoder.

../../../_images/runs.webp

A single object (in yellow) with eight highlighted runs (in red).

EasyObject can work at object level, and at run level which allows faster processing in critical cases. This is useful to compute custom features on objects then list all runs belonging to a given object. Use ECodedElement::GetRunsIterator .NET Python to get an EObjectRunsIterator .NET Python iterator object.

See also

See the code snippets showing how to loop over the runs of an object.