Lite Classify · free and open source (GPL-3.0) · Windows 10/11 (64-bit) · NVIDIA GPU optional

Source on GitHub · Inquiries: ldbarua@gmail.com · or DM on Facebook

Download
Lite Classify Manual

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.

Crop beds and grass at 5 cm
Pixels 5 cm each. A single pixel says little.
Same view with yellow segment outlines
Segments Groups that share colour and position.
Same view with each segment filled with its mean colour
Objects Each now has one colour, one texture, one shape.

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.

Segments at a 30,000 target
30,000 ~ m² objects. Plots and the ground beside them begin to share objects.
Segments at a 67,536 target
67,536 (used here) ~ m² objects. Greenhouse edges and small plots separate.
Segments at a 150,000 target
150,000 ~ m² objects. Greenhouses split into many small pieces.

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

GroupFeatureWhat it measuresHelps separate
Colourr_mean g_mean b_meanAverage of each bandOverall colour; dark shade and gaps
r_std g_std b_stdSpread of each band inside the objectRagged crown vs. lawn or roof
brightness_meanAverage of (R+G+B)/3Sunlit vs. shaded surfaces
Vegetation indexexg_meanExcess Green, 2g − r − bPlants 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)contrastGrey-level difference between neighboursCanopy vs. smooth roof
homogeneityCloseness of neighbouring grey levelsUniform surfaces
energyOrderliness (angular second moment)Repetitive surfaces
entropyDisorder of the textureComplex canopy
Shapearea perimeterSize of the outline, m² and mObject size
circularity4πA / P²; 1 is a discCompact vs. long objects
convexityArea / convex-hull areaRegular vs. ragged outlines
Contextbrightness_rel_neighborsOwn brightness minus touching objects' meanLocally dark patches, gaps
Height (DSM)dsm_mean dsm_stdMean height and its spreadTall vs. low; rough canopy
slope_meanMean slope in degreesTilted roofs and crown sides vs. flat ground
dsm_rel_neighborsOwn mean height minus touching objects' meanRaised objects (crowns, roofs) vs. sunken (gaps, roads)
hag_meanMean height above a ground surface estimated from the DSMTall cover vs. low cover, on any slope
Appearance (optional)deep_5m_pc1…10 deep_10m_pc1…10Principal components of the DINOv2 description of 5 m and 10 m patchesCanopy 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

A tree segment outlined in magenta, at 5 cm
Outlined object, on the 5 cm working grid

Co-occurrence: spread wide

A roof object

A greenhouse roof segment outlined in magenta, at 5 cm
Outlined object, on the 5 cm working grid

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.

DSM heights over the patch
DSM – m. Terrain and objects mixed together.
Slope over the patch
Slope 0–60°. Crown sides and roof edges light up.
Height above ground per object
Height above ground Roofs and trees stand out; fields, the road and bare ground sit near zero.

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.

1 · Two patches Square crops centredon each object: 5 m: the object10 m: its setting resized to 224 × 224 px 2 · Cut into tiles The patch becomes a16 × 16 grid of 14 pxtiles ("tokens"). each tile → 384numbers the only convolution 3 · Transformer 12 blocks of self-attention:every tile looks at everyother tile and updates itsdescription from what itsees. Context is built in. ViT-S/14 · 22 M weights,frozen, runs offline 4 · One vector A summary token gives384 numbers per patch:objects that look alikeget similar numbers. 2 patches × 384per object, cached indeep_features.npz Discover (Tab 2) PCA to 32 per patch,clustered into groups Classifier (Tab 3) PCA to 10 per patch:+20 features, optional
How an object gets its appearance description. Lite Classify computes it once per segmentation and keeps it in the workspace.

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.

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.

  1. 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.
  2. 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.
  3. 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.
  4. 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.
The survey coloured by Discover group
The groups, scene-wide requested, after splitting; were named.
Group colours over the feature-explorer patch
Close-up The same patch as the feature explorer. Groups follow cover type and pattern, not just colour.
Eight tiles from a group named Crop 1

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

Eight tiles from a group named Crop 2

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

Eight tiles from a group named Building

A group named Building: roofs and sheds.

Eight tiles from a group named Mud

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.

Many trees, each trained on a random resample, vote on every object Training objects your labelled examples,each a row of 44 numbers … 2,038 rows in the example Tree 1ExG > 0.08?HAG > 2 m? Tree 2deep 10 mPC1 > 0.4? … Tree 100each sees arandom subset One object's votes 64 28 7 1 illustrative counts Crop 1 majority wins the questions inside each tree are learned from the data; those shown are examples

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 pairwise JM table and the closest pairs for the worked example's nine classes
The worked example's separability. The pairwise table and the closest pairs on 44 features. The closest are Bare vs. Road and Bare vs. Grass (about 1.8), then Crop 2 vs. Grass (1.98); the rest round to 2.00.

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.

Classification from a first model trained on 5 objects per class
The same area classified by the final model
First model · objectsFinal model · objects

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
RoundTraining 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.

Orthomosaic, object map and refined map of a row field side by side
A row field. Orthomosaic, the object map, and the refined map. The green rows, too narrow for the objects, appear only after refinement, and they come out wider than they are on the ground.

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.

Classification with no sieve
Classification after a 4,000-pixel sieve
No sieveSieve 4,000 px (10 m²)
Sieve (px)Area at 5 cm (m²)Map pixels changedOverall 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):

MeasureQuestion it answersFrom the matrix
Overall accuracyWhat share of the map is right?Diagonal total ÷ all
User's accuracyIf the map says Grass, how often is it really Grass? (reliability for a map user; 1 − commission error)Diagonal ÷ row total
Producer's accuracyOf 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?

DesignHow points are placedGood forWatch out
Simple randomAnywhere on the image, independent of the mapA map-wide figure straight from the countsRare classes get too few points for a usable per-class score
Stratified by map classA minimum number of points in each map class (the strata), the rest by area shareUsable per-class figures for small classesCounts 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.