Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Understand how one semantic class becomes many individually identifiable objects

1. Motivation

Every function you use later in this lesson, training, inference, evaluation, works on the assumption that “field number 7” is meaningfully different from “field number 12,” even though both are simply “field” as a class. Understanding this distinction now makes the rest of the lesson, especially reading raw prediction output, far less confusing.


2. Core idea

A semantic segmentation label answers “what class is this pixel,” using one value per class. An instance segmentation label answers “what class, and which specific object,” using one value per object. Two adjacent fields of the same crop still get two different values, because the label encodes object identity, not just class membership.

Take the field-parcel example directly: a semantic segmentation model applied to a farming region might produce one large connected region labeled “field.” From that output alone, you cannot tell whether it contains 5 parcels or 50, and you cannot compute the area of any individual one. An instance segmentation model instead produces a separate mask per parcel, each with its own instance identifier and confidence score, which is what makes counting, per-parcel measurement, and tracking possible.


3. How instance identity is represented

A. Class labels and instance IDs

Consider three neighboring fields.

A semantic class raster might contain:

0 0 0 0 0 0
0 1 1 1 1 0
0 1 1 1 1 0
0 0 0 0 0 0

where:

0 = background
1 = field

This tells us which pixels are fields, but not how many fields exist.

An instance raster could instead contain:

0 0 0 0 0 0 0
0 1 1 2 2 3 0
0 1 1 2 2 3 0
0 1 1 2 2 3 0
0 0 0 0 0 0 0

Now:

0 = background
1 = field instance 1
2 = field instance 2
3 = field instance 3

The values 1, 2 and 3 are not different land-cover classes. They are unique object identifiers.

This distinction is central to instance-segmentation training data.


B. What one prediction contains

A typical predicted instance contains several related outputs:

instance
├── class label
├── confidence score
├── bounding box
└── pixel-level mask
ComponentFormat / ExampleRole in Downstream Analytics
Class LabelCategory ID / Name
field = 1
Assigns the semantic category to the detected object.
Instance IDNominal Integer
ID: 27
Distinguishes individual entities without imposing rank (e.g., ID 27 is not “greater than” ID 3).
Confidence ScoreProbability Float
0.94 (94%)
Quantifies model certainty; acts as a filter threshold to discard weak candidate predictions.
Bounding BoxCoordinates
[xmin, ymin, xmax, ymax]
Defines the coarse bounding envelope enclosing the object.
Pixel MaskBinary Matrix
1 = object, 0 = background
Provides exact feature geometry for area, perimeter, and shape calculations.

C. One class, many masks

The agricultural example illustrates an important point.

Suppose an image contains 35 fields.

You do not need:

35 semantic classes

You need:

1 semantic class: field
35 separate instances

This is why the practical training workflow later uses:

num_classes=2

for:

0 = background
1 = field

even though an image may contain many individual parcels.

Object identity comes from the masks, not from adding more semantic classes.


D. Why object identity matters

Once each object remains separate, you can perform object-level operations.

For example:

instance mask
     ↓
polygon
     ↓
one row in a GeoDataFrame
     ↓
area / perimeter / shape / attributes

This creates a familiar spatial data model:

instance_idclassconfidencegeometry
1field0.94Polygon
2field0.88Polygon
3field0.81Polygon

The prediction has become a set of spatial features rather than only a raster class map.


E. Common instance errors

Instance segmentation introduces several error types beyond incorrect class labels.

Error TypeStatistical ClassReference vs. PredictionPractical GeoAI Impact
Missed InstanceFalse NegativeRef: 1 2 3
Pred: 1 2 -
Undercounts objects (e.g., missing isolated tree crowns).
Spurious InstanceFalse PositiveRef: 1 - -
Pred: 1 2 -
Overcounts objects by detecting ghosts or background noise.
Merged InstancesStructural ErrorRef: 1 2
Pred: 1 1 1
Combines adjacent entities (e.g., merging two farm parcels).
Split InstanceStructural ErrorRef: 1 1 1
Pred: 1 2 3
Artificially inflates object counts (e.g., splitting one building into three).
Poor BoundaryGeometric ErrorRef: [ 1 ]
Pred: [ 1 1 1 1 ]
Skews area/perimeter metrics while keeping counts correct.

F. Mask overlap

Intersection over Union (IoU) evaluates the geometric overlap between a predicted mask (AA) and a reference mask (BB):

IoU(A,B)=∣A∩B∣∣A∪B∣=TPTP+FP+FN=Area of OverlapArea of Union\text{IoU}(A, B) = \frac{\vert{}A \cap B\vert{}}{\vert{}A \cup B\vert{}} = \frac{\text{TP}}{\text{TP} + \text{FP} + \text{FN}} = \frac{\text{Area of Overlap}}{\text{Area of Union}}

For instance segmentation, the overlap is calculated using the mask pixels, rather than only the rectangular bounding boxes.

Higher mask IoU indicates stronger spatial agreement.

This becomes useful when calculating instance-level metrics such as Average Precision (AP).


4. Python reactivation

An instance-label raster loaded as a NumPy array behaves exactly like the class-label arrays from L07: numpy.unique(array) lists the distinct values present, only now those values represent individual object IDs rather than class indices. Subtracting one for the background value—len(numpy.unique(array)) - 1—is a quick way to count how many distinct objects a mask contains.

Suppose instance_mask is an array where zero is background and positive integers are individual object IDs:

You can filter for non-background IDs to get exact object numbers and identifiers:

Or calculate the total count directly using the shortcut formula:

While this is not how a neural network generates predictions, it demonstrates why an instance-labelled raster is useful: every object retains a distinct identity and can be selected independently.


5. Common pitfalls


6. Mini task

You load an instance-label raster and find numpy.unique(array) returns [0, 1, 2, 3, 4, 5]. A colleague says “so the model found 6 fields.” Are they right? Explain.

Sample solution

Not quite. Assuming 0 is reserved for background, as is the convention in this lesson, the array actually contains 5 distinct field instances (values 1 through 5), not 6. It is a common off-by-one mistake to count the background value as an object; always confirm which value represents background before counting instances.


7. Key takeaways