apis-mellifera-wing-landmarks-19-v1
Honey bee wing landmarks, 19 points, input/output format v1.
A heatmap model that finds the 19 standard landmarks (vein junctions) on a honey bee (Apis mellifera) worker forewing image. The points feed geometric morphometrics: wing indices (cubital index, discoidal shift, Hantel index), Procrustes shape analysis and lineage / subspecies classification.
The model powers Apiala, a wing morphometrics app for beekeepers (web PWA and desktop). It runs entirely on the user's device with ONNX Runtime (WASM in the browser), so wing images are never uploaded. Try it at apiala.com.
A wing from the test split (colony never seen in training): model predictions (red dots, numbered) against the expert landmarks (green rings). Mean error on this wing: 0.99 px, typical for the test set (mean 0.94 px).
| Model | apis-mellifera-wing-landmarks-19-v1 (v1 = input/output format below; a breaking change gets a new -v2 repo) |
| Release | 2026-10-24-effb0 (git tag v2026-10-24-effb0 in this repo) |
| Architecture | EfficientNet-B0 backbone (timm, ImageNet-pretrained) + FPN head → 19 heatmaps at stride 4, soft-argmax for sub-pixel coordinates |
| Input | image: float32 [1, 1, 256, 768], greyscale in [0, 1], letterboxed (see below) |
| Outputs | points: float32 [1, 19, 2] (x, y) in input-canvas pixels, origin top-left, y down. confidence: float32 [1, 19] peak heatmap probability |
| Format | ONNX, opset 17, fp32, 15.2 MB (landmarks.onnx, sha256 1d0113bf92fa525c20cd222066203908debfb319ca4db61c32a09275b9536fe0) |
| Licence | Apache-2.0 |
Files
| File | Content |
|---|---|
landmarks.onnx |
The model |
landmarks.json |
Metadata read by the app: version, backbone, input size, landmark count, sha256, size |
eval-test.json |
Full test-set report: overall and per-landmark errors, confidence calibration |
args.json |
Training arguments |
LICENSE |
Apache License 2.0 |
example.png |
Example prediction on a test-split wing (shown above) |
How to use
Preprocessing (must match exactly)
- Convert the image to greyscale (8-bit, mode
L). - Orient the wing base on the right, tip on the left (the training images' orientation). The model was trained with mirroring as augmentation, so it tolerates flipped wings, but the landmark numbering follows the standard orientation.
- Letterbox into a 768 × 256 canvas:
scale = min(768 / w, 256 / h), resize to(round(w·scale), round(h·scale))with bilinear resampling, place it at the top-left corner, and fill the rest with the (rounded) mean of the image's 1-pixel border. - Divide by 255 and add batch and channel axes →
[1, 1, 256, 768].
Map the outputs back to the original image by dividing points by scale.
Python
import numpy as np
import onnxruntime as ort
from PIL import Image
W, H = 768, 256
def letterbox(img: Image.Image) -> tuple[np.ndarray, float]:
a = np.asarray(img.convert("L"))
h, w = a.shape
scale = min(W / w, H / h)
nw, nh = max(1, round(w * scale)), max(1, round(h * scale))
border = np.concatenate([a[0], a[-1], a[:, 0], a[:, -1]]).mean()
canvas = np.full((H, W), round(border), dtype=np.uint8)
canvas[:nh, :nw] = np.asarray(img.convert("L").resize((nw, nh), Image.Resampling.BILINEAR))
return canvas, scale
sess = ort.InferenceSession("landmarks.onnx", providers=["CPUExecutionProvider"])
canvas, scale = letterbox(Image.open("wing.png"))
x = (canvas.astype(np.float32) / 255)[None, None]
points, confidence = sess.run(["points", "confidence"], {"image": x})
landmarks = points[0] / scale # (19, 2) in original image pixels, y down
Browser
Apiala runs the same model with onnxruntime-web (WASM backend) in a Web Worker. Its TypeScript
letterbox is a bit-exact port of Pillow's bilinear resampling, so browser and Python inputs are
identical.
Landmarks
The 19-point scheme of the training dataset (Oleksa et al. 2023), images shown base-right:
- 1–2: close pair at the proximal cubital vein junction
- 3–6, 8–13: junctions of the submarginal, discoidal and cubital cells
- 7, 14: anterior margin (radial / marginal cell)
- 15–18: distal / basal region towards the wing base
- 19: most apical point used (near the wing tip)
Training data
Oleksa A. et al. (2022). Collection of wing images for conservation of honey bees (Apis mellifera) biodiversity in Europe. Zenodo, doi:10.5281/zenodo.7244070, released into the public domain.
- 26,481 worker forewing images from 1,725 colonies in 13 European countries (AT, ES, GR, HR, HU, MD, ME, PL, PT, RO, RS, SI, TR), with expert landmarks.
- Greyscale PNG scans, about 900 × 320 px, tightly cropped single wings, mostly 2,400 dpi.
- Raw coordinates are y-up (TPS convention) and were converted to
y = image_height − y. - Split by colony, stratified by country: 80 / 10 / 10 (seed 0). No colony appears in more than one split.
Training procedure
- Input: letterboxed 768 × 256 canvas (as above), cached as uint8.
- Targets: 19 Gaussian heatmaps (σ = 1 cell at stride 4).
- Loss: KL divergence to the Gaussian target + L1 on the soft-argmax coordinates.
- GPU augmentation: rotation ±15°, scale 0.8–1.12, shift, horizontal / vertical mirroring, brightness / contrast / gamma, blur, noise.
- Optimiser: AdamW, lr 4e-3, weight decay 1e-4, linear warm-up (≤ 500 steps) then cosine decay, batch 128, bf16 mixed precision, 30 epochs, one NVIDIA RTX 5090. The checkpoint with the lowest validation error was kept (epoch 30, validation mean error 0.96 px).
- Export: ONNX opset 17 with soft-argmax inside the graph. Maximum difference against PyTorch on validation wings: 0.0003 px.
Evaluation
Test split: 2,704 wings from 172 colonies never seen during training. Error is the Euclidean distance between the predicted and the expert landmark, in original-image pixels (at 2,400 dpi, 1 px ≈ 10.6 µm).
| Mean | Median | 95th pct. | Max | |
|---|---|---|---|---|
| Error (px) | 0.94 | 0.74 | 2.25 | 237.2 |
| Error (µm)¹ | 10.9 | 7.1 | 21.1 | 2,510 |
¹ Only wings whose scan resolution is recorded in the dataset.
Per landmark (px):
| Landmark | Mean | Median | 95th pct. | Max |
|---|---|---|---|---|
| 1 | 0.78 | 0.63 | 1.92 | 9.9 |
| 2 | 0.82 | 0.64 | 1.98 | 11.9 |
| 3 | 0.87 | 0.69 | 2.07 | 36.8 |
| 4 | 1.05 | 0.85 | 2.49 | 15.7 |
| 5 | 0.77 | 0.63 | 1.84 | 10.4 |
| 6 | 0.99 | 0.79 | 2.48 | 20.7 |
| 7 | 1.03 | 0.76 | 2.84 | 21.7 |
| 8 | 0.84 | 0.67 | 1.99 | 14.9 |
| 9 | 0.88 | 0.70 | 2.12 | 11.5 |
| 10 | 0.82 | 0.67 | 1.91 | 13.1 |
| 11 | 0.75 | 0.63 | 1.67 | 9.5 |
| 12 | 0.84 | 0.72 | 1.89 | 15.2 |
| 13 | 1.05 | 0.85 | 2.52 | 9.7 |
| 14 | 1.39 | 1.06 | 3.23 | 116.3 |
| 15 | 0.92 | 0.76 | 2.18 | 9.0 |
| 16 | 0.96 | 0.79 | 2.16 | 12.6 |
| 17 | 0.85 | 0.72 | 1.93 | 7.6 |
| 18 | 1.13 | 0.93 | 2.53 | 18.9 |
| 19 | 1.14 | 0.77 | 2.21 | 237.2 |
Not evaluated yet: error relative to inter-observer error, and whether wing indices and lineage classification computed from predicted landmarks agree with those from expert landmarks.
Limitations
- Image domain. Trained only on clean, cropped, greyscale lab scans of single wings. Phone or microscope-camera photos, colour images, wings with debris, torn or folded wings and uncropped images are out of distribution and will give larger errors.
- Geography. European colonies only (lineages C and M dominate; lineage O has 49 colonies, A 188). Bees from other regions have not been tested.
- Worker forewings only. Not trained on drones, queens or hind wings.
- Rare large errors. Most points are within ~2 px, but single points can be far off (landmarks 14 and 19 are the most affected). Always show the points to the user for review before computing indices.
- Confidence is a weak error signal. Flagging the 10% least confident points catches only
about 14% of errors above 5 px. Do not rely on
confidencealone to skip manual review. - Not a diagnostic or regulatory tool. Classification of subspecies from wing shape is probabilistic and depends on the reference data used downstream, not on this model alone.
License
The model weights and this card are released under the
Apache License 2.0 (full text in LICENSE).
Copyright 2026 Rafal Woloszyn.
The training data (Oleksa et al., Zenodo 7244070) is in the public domain. The backbone was initialised from ImageNet-pretrained timm EfficientNet-B0 weights (Apache-2.0).
Citation
If you use this model, please cite the training dataset and paper:
@article{oleksa2023wings,
title = {Honey bee (Apis mellifera) wing images: a tool for identification and conservation},
author = {Oleksa, Andrzej and others},
journal = {GigaScience},
volume = {12},
pages = {giad019},
year = {2023},
doi = {10.1093/gigascience/giad019}
}
@dataset{oleksa2022zenodo,
title = {Collection of wing images for conservation of honey bees (Apis mellifera) biodiversity in Europe},
author = {Oleksa, Andrzej and others},
publisher = {Zenodo},
year = {2022},
doi = {10.5281/zenodo.7244070}
}