Part B · Concepts
How Lite Classify works
Lite Classify reads a drone image the way a person does. It splits the scene into objects, describes each object with up to 24 measurements and a learned description of its appearance, proposes groups of look-alike objects for you to name, and learns from your examples which descriptions belong to which class.
5.1Objects, not pixels
Object-based image analysis classifies groups of similar neighbouring pixels instead of single pixels. A group carries far more evidence than a pixel: its average colour, how varied it is inside, its texture, its shape, its height and how it compares with its neighbours. It also removes the scattered single-pixel speckle that pixel-by-pixel maps suffer from.



At drone resolution a tree crown or roof spans hundreds of pixels, so objects match real things on the ground. Resolution can also be too fine. Below roughly 1–5 cm per pixel the segmenter starts outlining individual leaves and roof sheets, and objects stop meaning anything. About 5–10 cm per pixel suits field-, bed- and crown-scale work. The worked example is captured at 2.16 cm and segmented at 5 cm.
RGB only. Consumer drone cameras record red, green and blue, with no near-infrared. That rules out NDVI, so Lite Classify leans on visible-light vegetation indices, texture, height and learned appearance instead.
5.2Segmentation with SLIC
SLIC (Simple Linear Iterative Clustering) is k-means clustering on five numbers per pixel: three colour values in CIELAB space (L*, a*, b*) and the pixel's x and y. Seeds start on a regular grid. Each pixel then joins the nearest seed, where "near" mixes colour and distance:
D = √( dcolour² + (dspace / S)² · m² )
S is the seed spacing and m is compactness. CIELAB is used because distances in it track how different two colours look to a person. After about ten rounds of moving seeds and reassigning pixels, a clean-up pass makes every segment a single connected piece.
Number of segments: the scale of the map
This one setting decides how big objects are, and it is the most important choice in OBIA. Too many, and crowns and roofs are cut into fragments (more labelling, but edges are kept). Too few, and objects straddle two cover types, which no classifier can fix. The worked example asked for segments over ha and got , about m² each: part of a bed, part of a crown or a roof. That is small on purpose: crop beds, ditches and paths are only a few objects wide.



The same patch of greenhouses and small plots, segmented on its own at each scene-wide density.
Compactness and sigma
Compactness trades colour against regularity: low values let segments follow colour edges closely; high values make them blocky and even. Sigma blurs the image slightly before clustering so that fine texture and sensor noise do not seed spurious segments.
Large images: tiles, and GPU vs CPU
When one run would not fit in memory, Lite Classify segments the image in tiles with an overlap margin. Colour is scaled over the whole scene first and every tile aims for the same segment size, so tiles match. Each overlap pixel goes to the segment whose centre owns it, and leftover slivers merge into the neighbour they share most border with, so no object is cut or duplicated at a tile seam. Images that fit keep the single-run path.
The CPU engine is scikit-image's SLIC. The GPU engine is a PyTorch version of the same clustering. They scale compactness differently, so the same value gives similar but not identical segments, and the GPU's parallel updates make it not bit-for-bit repeatable (about 98% of pixels agree between runs). Pick one engine for a project and keep it; the realised segment count, not the requested one, is what to report.
5.3The object fingerprint
Once segmented, every object is summarised by a fixed list of numbers. These numbers, not the image, are what the classifier learns from. Nineteen come from the RGB image alone; a DSM adds five more. Optionally, 20 appearance components from DINOv2 join them (5.4): the worked example's classifier used all .
All 24 features
| Group | Feature | What it measures | Helps separate |
|---|---|---|---|
| Colour | r_mean g_mean b_mean | Average of each band | Overall colour; dark shade and gaps |
r_std g_std b_std | Spread of each band inside the object | Ragged crown vs. lawn or roof | |
brightness_mean | Average of (R+G+B)/3 | Sunlit vs. shaded surfaces | |
| Vegetation index | exg_mean | Excess Green, 2g − r − b | Plants vs. soil, roads, roofs |
vari_mean | (G − R) / (G + R − B) | Green cover, damped for light | |
ngrdi_mean | (G − R) / (G + R) | Greenness, NDVI stand-in | |
| Texture (GLCM) | contrast | Grey-level difference between neighbours | Canopy vs. smooth roof |
homogeneity | Closeness of neighbouring grey levels | Uniform surfaces | |
energy | Orderliness (angular second moment) | Repetitive surfaces | |
entropy | Disorder of the texture | Complex canopy | |
| Shape | area perimeter | Size of the outline, m² and m | Object size |
circularity | 4πA / P²; 1 is a disc | Compact vs. long objects | |
convexity | Area / convex-hull area | Regular vs. ragged outlines | |
| Context | brightness_rel_neighbors | Own brightness minus touching objects' mean | Locally dark patches, gaps |
| Height (DSM) | dsm_mean dsm_std | Mean height and its spread | Tall vs. low; rough canopy |
slope_mean | Mean slope in degrees | Tilted roofs and crown sides vs. flat ground | |
dsm_rel_neighbors | Own mean height minus touching objects' mean | Raised objects (crowns, roofs) vs. sunken (gaps, roads) | |
hag_mean | Mean height above a ground surface estimated from the DSM | Tall cover vs. low cover, on any slope | |
| Appearance (optional) | deep_5m_pc1…10 deep_10m_pc1…10 | Principal components of the DINOv2 description of 5 m and 10 m patches | Canopy types of similar colour and height; stand pattern |
The three vegetation indices use chromatic coordinates, each band divided by R + G + B, so that a shaded leaf and a sunlit leaf score alike. Random Forest needs no rescaling, so features go in as measured.
Measuring finer than you segment
Coarsening the image keeps objects crown-sized, but it also throws away the fine detail texture is computed from. Lite Classify separates the two: segments are drawn on the working grid, and colour and texture are read from the original file at the finer resolution you set in Colour/texture at. In the worked example, outlines come from the 5 cm grid and every object's colour and texture from the native 2.16 cm pixels, about five times as many pixels per object. Height features always use the DSM on the working grid.
Feature explorer
Pick a feature to see its value for every object in one patch of the worked example: crop beds, grass strips, bare ground, the road, greenhouse roofs and trees.
Colour ramps are stretched to the 2nd–98th percentile of objects in this patch. The neighbour features use a blue–red ramp centred on zero.
Texture, step by step
Texture comes from a grey-level co-occurrence matrix (GLCM). The object is turned to grey, reduced to 15 grey levels, and every pair of touching pixels is tallied by its two levels, in four directions. A smooth surface puts all its pairs on the diagonal (same level next to same level). A busy one scatters them.
A tree object

Co-occurrence: spread wide
A roof object

Co-occurrence: tightly grouped
A painted or weathered roof can come close to a crown in mean colour. Texture helps separate them: these are typical objects of each kind, and the crown's contrast is several times the roof's. Objects smaller than 16 pixels get neutral texture values.
Exactly how Lite Classify computes texture
Luminance is 0.299R + 0.587G + 0.114B. Grey levels 1–15 hold the object's pixels; level 0 marks pixels outside the object and is dropped, then the matrix is renormalised so only pairs inside the object count. Pairs are one pixel apart at 0°, 45°, 90° and 135°, counted symmetrically. Contrast, homogeneity and energy are averaged over the four directions. Entropy is computed in bits and summed over the four directions, so its values run about four times a single-direction entropy; the classifier is unaffected by that scale.
Context and height
Two features compare each object with the objects it touches, using a region adjacency graph (a list of which objects share a border). An object darker and lower than everything around it, such as a ditch or a pond edge, stands out wherever it sits on a slope.
A DSM is the height of the top surface, not the ground, so absolute height mixes terrain with the objects on it. Height above ground removes the terrain. Lite Classify estimates a ground surface from the DSM itself: it takes the lowest value in each ~1 m block, then a morphological opening over 40 m (a moving minimum, then a moving maximum) that removes anything narrower than 40 m, such as crowns and buildings, and smooths the result. Each object's height above that surface is hag_mean. Under closed canopy wider than 40 m the ground estimate rides up on the canopy and heights are underestimated, the usual limit of ground estimation from a DSM alone.



5.4Appearance with DINOv2 and DINOv3
The 24 features describe each object on its own, and at this scale an object is about the size of part of a crop bed. Some cover types are defined by their surroundings and pattern instead: two crops can be equally green and equally low, but one grows in regular rows and the other does not, and a grass strip looks like a crop leaf in close-up. To capture that, Lite Classify adds a learned description of what each object and its neighbourhood look like.
DINOv2 (Meta AI, 2023) is a vision transformer trained on 142 million images without labels, by learning to give matching descriptions to different crops of the same picture. Lite Classify uses its small version, ViT-S/14, as a frozen feature extractor: it never trains it, fine-tunes it, or uses it to classify.
- Two patch sizes, on purpose. The 5 m patch describes the object and its edge; the 10 m patch describes the stand pattern around it. Both are cut from the orthomosaic on the working grid, centred on the object.
- Why a transformer and not hand-made texture. GLCM texture counts neighbouring pixel pairs inside one object. Self-attention relates every part of the patch to every other part, so it captures arrangement: rows, spacing, crown shape, how an object sits among its neighbours.
- Why it needs no labels. Because DINOv2 learned from unlabelled images, its descriptions are general: they transfer to aerial scenes it never saw, without retraining. Your labels are only needed later, by the Random Forest.
- Where it pays off. In the worked example, the two crops are told apart mainly by pattern, which is what these appearance components carry; the separability check shows which features lead each pair (5.7).
Is it a CNN? No. A convolutional neural network (CNN) builds its picture from many layers of small sliding filters. DINOv2 ViT-S/14 is a vision transformer: its one convolution layer only cuts the patch into 14 × 14 px tiles (about 1% of its weights), and everything after that is attention. "Deep learning features" is accurate; "CNN" is not.
Cost, offline use, and limits
Computing the descriptions is a one-off cost per segmentation, roughly half a minute per 7,000 objects on a consumer GPU (slower on CPU). The 85 MB weights ship with the program, so it runs without internet. DINOv2 sees only RGB; it does not know about height, which the DSM features cover. Patches at the image edge are partly empty; Discover can leave those segments out. The weights and model code are Meta's, released under the Apache License 2.0.
DINOv3, the optional backbone
DINOv3 (Meta AI, 2025) is the next generation of the same idea, trained on about 1.7 billion images. Lite Classify can use its small model, ViT-S+/16, in place of DINOv2 for both Discover and the classifier. Everything in the diagram above stays the same except step 2: the 224 px patch is cut into 16 px tiles (a 14 × 14 grid), and the summary is still 384 numbers per patch.
- What changes in practice. DINOv3 was trained to keep its tile descriptions sharp and stable over long training, which tends to give cleaner groups of look-alike objects. On the worked example, its groups of crops, beds and grass followed the field layout more closely than DINOv2's.
- Why it is optional. DINOv3 is released under Meta's own DINOv3 licence, not Apache 2.0, so Lite Classify never bundles or downloads it. You request the weights from Meta and point the app at the file (Part C, 8.1). The app checks that it is the ViT-S+/16 file and that its checksum matches its name.
- One backbone per workspace. The cached appearance descriptions record which backbone made them. Switching backbones means computing them again; Find Groups asks before it does, and the classifier's appearance features follow the workspace's backbone.
5.5Discovering classes
A supervised map assumes you already know which classes the scene contains and can recognise each one. That is often where mapping goes wrong: the obvious list (trees, grass, bare, buildings) is easy to label but coarse, and the categories that matter may not be visible at a glance. Discover Classes turns this around: the machine proposes groups of look-alike objects, and you supply the names.
- Describe. Each object gets its DINOv2 appearance (32 components per patch size) and its standardised classifier features. Each block is scaled to equal total weight, so the many appearance numbers do not drown out colour, texture and height.
- Over-cluster. k-means splits the objects into more groups than you expect classes. Too fine is cheap to fix (merge two groups in one click); a group that mixes two cover types has to be split, which is harder. Segments at the image edge can be left out.
- Curate. You review each group's tiles and act on it: name it (which creates a class), merge it, split it by appearance, height or brightness, move single tiles, or ignore it.
- Hand over. The typical segments of the named groups become training samples in Tab 3. The Random Forest then generalises from them; groups never become the map directly, because one mis-grouped object would go straight into the map with nothing to correct it.



A group named Crop 1: one crop's regular rows.

A group named Crop 2: taller, broad-leaved plants in a looser pattern.

A group named Building: roofs and sheds.

A group named Mud: dark patches in and around the shallow pond.
In the worked example, the groups split the fields further than a list made in advance would have: dense rows and sparse, broad-leaved plants became Crop 1 and Crop 2, and the dark patches in the shallow pond became Mud, distinct from open water and from dry bare soil.
5.6Random Forest
You label a modest number of example objects per class. Lite Classify trains a Random Forest of 100 decision trees on their feature lists and asks it to label every object in the scene.
Why this and not hand-written rules such as "brightness below 50 means gap"? Rules are clear but brittle: a change in light breaks them, and they do not scale to 44 features and nine classes. A Random Forest learns the combinations for you. Training each tree on a random resample of your examples, with a random subset of features at each split, keeps it from memorising noise. It tolerates correlated features, needs no scaling, works with a few hundred examples, and retrains in seconds. The vote shares also tell Lite Classify which objects the model is least sure about, which is how What to Label Next picks its suggestions.
5.7Class separability
Before you invest in labelling and checking, Check Class Separability reports whether your training samples can support the class list. For every pair of classes it computes the Jeffries–Matusita (JM) distance from the labelled objects: 0 means the two are identical in feature space, 2 means completely distinct (1.9 or more good, 1.7–1.9 fair, below 1.7 poor). The score is cross-validated: each pair is separated along the best direction found on part of its samples and scored on the rest. With dozens of features and a few hundred samples, the classic full-dimensional JM (used up to v1.1) reaches 2 for almost any pair, even a class split against itself, so it cannot point out a weak pair; the cross-validated score can, and errs on the cautious side. It also ranks, for each pair, which single features separate it best, and says so in a sentence.
The signature plot for each pair shows the class means feature by feature, most telling on the left. Pick a pair:
Grass vs. Bare is led by greenness (ExG), the material difference the classic features are built to carry and the same difference the greenness refinement uses pixel by pixel (5.9), with appearance components close behind. Crop 1 vs. Crop 2 is led by appearance components alone, which is a pattern difference. That split between material and pattern is the clearest single argument for the appearance features.
Read the ranking alongside the number. The cross-validated score no longer saturates at 2.00 the way the v1.1 score did, but it is still estimated from your training samples, not from the map. The order of the closest pairs and the per-feature ranking are the most useful part. A class with few samples (here Water, Tree and Mud, 48 each) gives a noisier score.
5.8Why retraining matters
The first model rarely gets every class right. It mislabels objects unlike anything in your first examples. Every classification run shows you where those errors are, and retraining fixes them: add the misclassified objects as samples under their correct class, train again, classify again.

Drag across the image. A first model on five objects per class scatters Water and Building across the road and the fields; the final model clears most of that.
Simulated from the worked example · not a recorded history
The workspace keeps only its final training set, not the order it was built in. To show how accuracy grows round by round, we replayed the retraining loop from those real labels. Round 1 trains on randomly chosen objects per class. Each later round adds up to objects per class that the current model gets wrong, drawn from the workspace's own labelled objects, which is what you do after inspecting a run. Every round is scored as area-weighted overall accuracy on the stratified reference points. The replay was repeated from random starts.
Overall accuracy by retraining round
Mean of replays (line) and their range (bars). Area-weighted, on the stratified reference sample.
Show as table
| Round | Training objects (mean) | Overall accuracy (mean) | Range |
|---|
The first rounds matter most. Accuracy climbs from on objects to by round 3, then levels off near . Later rounds still add samples, but each fixes less.
Targeted samples beat sheer numbers. The replays come within about a point of the full -object model () with only about objects, chosen because the model got them wrong.
Start-up luck fades. In round 1 the replays range from to , depending on which five objects per class happened to be picked. By the last rounds they sit within a few points of each other.
Producer's accuracy per class, first model and final model
Area-weighted share of each class's reference area the map finds. Round 1 is the mean of the replays.
Classes that cover many looks gain the most: five objects cannot cover every stage of a crop, or every kind of bare ground. In this replay Road, Bare and Grass gain the most, from a producer's accuracy of about 75 to 80% in the first round to over 90% with all the samples. Classes narrower than the segments go the other way: more samples cannot fix a grass strip thinner than an object; the greenness refinement (5.9) or a finer working grid can.
The rule that follows: after each run, do not just fix the most visible blotch. Pan the whole scene, list the kinds of mistakes, and add a few samples of each kind from several places. Then measure with the Accuracy tab rather than by eye.
5.9Greenness refinement
An object-based map is only as fine as its objects. In row crops, a strip of grass between two bare beds can be a few tens of centimetres wide, narrower than any object, so it is absorbed into the bare object around it and the map shows bare soil where a reference point finds grass. Making the objects smaller only helps up to a point, and costs time and memory on large images.
The greenness refinement keeps the objects and adds one step after classification. The objects decide what kind of land an area is; for two classes you choose (typically grass and bare soil), each pixel then decides which of the two it is by its greenness. Every other class stays exactly as the objects decided.
- The measure. Greenness is the excess green index, ExG = 2g − r − b on colours scaled to sum to 1, the same index as the
exg_meanfeature. It is averaged over a small square window (3 × 3 pixels by default) so single pixels do not flicker. - The cutoff. Set from your own training samples: the ExG value that best separates the samples of the two classes. In the worked example it is . Dying grass keeps a faint green tinge that ExG picks up even where the colour looks like soil.
- Two modes. In both, pixels of the other class that read green become the green class one by one, which is what brings out thin strips. They differ in the other direction. Every pixel, both ways turns every grass pixel below the cutoff to bare, giving the sharpest edges but punching holes in patchy grass. Keep green segments whole (the default) turns a grass object to bare only as a whole, when under a quarter of its pixels read green, so patchy or dying grass stays solid.
On the worked example, the refinement raised overall accuracy at the reference points from to . Two cautions. The map is no longer purely object-based for those two classes. And because greenness is averaged over a window, strips come out somewhat wider than they are, so treat the green class's area with care in row crops.
5.10Generalisation
Even a good map has isolated objects labelled differently from everything around them. The sieve removes connected patches of one class smaller than a pixel threshold and hands them to the surrounding class. This sets a minimum mapping unit without blurring real boundaries, because it only ever moves whole small patches.

| Sieve (px) | Area at 5 cm (m²) | Map pixels changed | Overall accuracy (area-weighted) |
|---|
Objects in the worked example average about m² ( pixels), so a 4,000 px (10 m²) sieve leaves most of the map alone. It does erase the thin grass strips the greenness refinement brings out, which is why the example is assessed with no sieve. Set the sieve for how the map will be used, not to raise the score; a sieve tuned against the reference points is no longer an independent check.
5.11Accuracy assessment
A map is only as useful as your knowledge of how wrong it is. Lite Classify follows standard practice for thematic maps (Congalton and Green; Olofsson et al. 2014):
- A probability sample. Points are placed at random, by a design you choose, so every part of the map has a known chance of being checked. Training objects are kept out.
- Blind labelling. You label each point on the raw image, with the classification hidden, so the model's answer cannot sway you.
- An error matrix. Rows are what the map says; columns are what the reference says. The diagonal holds agreements.
| Measure | Question it answers | From the matrix |
|---|---|---|
| Overall accuracy | What share of the map is right? | Diagonal total ÷ all |
| User's accuracy | If the map says Grass, how often is it really Grass? (reliability for a map user; 1 − commission error) | Diagonal ÷ row total |
| Producer's accuracy | Of the real Grass, how much did the map find? (completeness; 1 − omission error) | Diagonal ÷ column total |
Kappa is left out on purpose; current guidance favours these three measures.
Simple random or stratified?
| Design | How points are placed | Good for | Watch out |
|---|---|---|---|
| Simple random | Anywhere on the image, independent of the map | A map-wide figure straight from the counts | Rare classes get too few points for a usable per-class score |
| Stratified by map class | A minimum number of points in each map class (the strata), the rest by area share | Usable per-class figures for small classes | Counts over-weight small classes; use the area-weighted estimates |
Under a stratified design, small classes are sampled at much higher rates than large ones, so a share of points is not a share of the map. Lite Classify therefore also weights each stratum by its mapped area and reports area-weighted overall, user's and producer's accuracy, the estimated area of each class, and 95% confidence intervals (Olofsson et al. 2014). The strata are the map classes at the time the points were drawn; if you later merge or rename classes, the estimates still use the original strata (Stehman 2014). In the worked example the points were drawn at 50 per class with no sieve, seed , on an earlier version of the map. The samples were refined afterwards, and the estimates keep those original strata as their weights. 229 of the 450 randomly drawn points were moved a median of 1.7 m by the interpreter, without reference to the classified map, to a spot with a clearer view of the land cover.
The worked example's points give from raw counts and ± area-weighted. The two differ because the design gave every class the same number of points, while the area-weighted figure counts each class by the area it covers. The full matrix is in Part C, 11.5.
Reference data is not ground truth. Points you label by eye from the orthomosaic are high-confidence reference data. Only points checked on the ground are ground truth. Where interpretation is hard, as for dry grass versus bare soil, the interpreter's errors resemble the model's. Lite Classify's report records the source of every point and says so in its footnote.