← Francesco Vigni

Fetal ultrasound · orientation

Estimating fetal cardiac orientation does not need a trained model.

How tilted the heart sits in the chest is a quantity clinicians measure on the standard four-chamber scan, and an unusual tilt is one of the signals that prompts a closer look. This estimates it two ways and compares them. If something already outlines the heart, the tilt follows from basic geometry — two orders of magnitude more accurately, and an order of magnitude more cheaply, than the model trained to do the same job. The useful part is knowing when that shortcut breaks.

Six fetal four-chamber ultrasound frames with annotated and predicted heart axes overlaid, labelled best, median and worst
Best, median and worst test cases — never only the flattering ones.

The pipeline

A YOLOv5s detector fine-tuned on 200 images finds the cardiac and thoracic regions: mAP@50 0.995 on the held-out split, 29.6 ms per image. Two numbers matter more than the mAP — on a different hospital's data it still fires on 93% of thorax images at 0.75 confidence, and the mAP itself is table stakes for one organ, one view, centred and always present. Anything below about 0.98 would signal a labelling problem, not a modelling one.

Then: take the highest-confidence cardiac box, expand it by 35%, compose any rotation and the crop into one affine matrix, and apply that same matrix to the image and to the landmarks so they cannot drift apart. Warp to 192×192, regress four points, reconstruct the angle geometrically, emit abstention flags. Both axes vote — the major endpoints give the axis directly, the minor endpoints give it rotated by 90°, which is a negation in doubled-angle space, so the two average as unit vectors.

Three routes, measured against each other

routemedian
error
tail
second-order moments — needs a mask, no training0.28°0% beyond 10°
minimum-area rectangle — needs a mask4.95°44% beyond 10°
trained landmark model — needs only a box7.04°p90 12.92°

The minimum-area rectangle is bimodal on elliptical shapes, which is why its median looks respectable and nearly half its errors are large. And the 0.28° is a floor, not a result: those masks are rasterised from the same ellipse annotations the angle is scored against.

How much you should trust the learned route

median absolute error7.04°
95% CI on the median4.84–9.26°
Bland–Altman bias−0.55°
95% limits of agreement±18°
ICC(2,1)0.980

Essentially unbiased, and ±18° against a clinical normal band roughly 40° wide. A working method with an honest error bar — not an instrument.

Bland-Altman plot and error distribution for the learned orientation route

Why landmarks rather than a scalar angle

The alternative was implemented and measured. A second head predicts the doubled angle directly:

headmedianp90
landmarks → geometric reconstruction7.04°12.92°
direct doubled-angle head5.64°11.43°

The direct head is better, so landmarks are not justified by accuracy. They are justified by an output a reviewer can reject point by point, an oriented box and aspect ratio for free, and two votes whose disagreement is a signal. With one caveat, reported rather than buried: the two heads' errors correlate at r = +0.79 — they share a backbone and fail together, which makes head disagreement a weak abstention signal.

Two architecture choices came from measured failures, not from taste. Heatmap regression plateaued at 28°, because an ellipse axis endpoint has no distinctive local appearance — it is defined by a global property of the shape. Global average pooling plateaued at 21°, because it discards exactly the spatial layout that encodes the angle. A 3×3 pooled grid is what fixed it.

Direction is deliberately not predicted. Apex-left against apex-right is levocardia against dextrocardia — a diagnosis that needs the spine or the stomach bubble, not something to infer from a cropped heart.

What the angle is worth

Against axis-aligned boxes, the oriented box reaches a median rotated IoU of 0.83 versus 0.51. Collapsing the annotation to axis-aligned costs ×1.97 the box area — and the annotations cluster at 45° and 135°, which is where a fetal heart sits in a correct four-chamber view. The near-worst case is the ordinary case.

Rotated IoU and box-area cost of dropping the orientation, and what the orientation head recovers

Where the shortcut breaks

Not where the quality score says it should. A mask scoring Dice 0.87 can produce a 46° error, while one at 0.77 produces 0.22°. What matters is how the segmentation fails, not how well it scores: symmetric erosion barely moves the axis, while a one-sided truncation of a chamber rotates it hard. Any gate built on Dice alone will pass the cases that hurt.

On a second hospital's data the p90 of the orientation error triples. That number, not the median on the training centre, is the one that describes the model.

Error distribution on external data compared with the in-distribution test split

Validated mostly without labels

Rotate the input and the axis must rotate with it. Change the brightness and it must not move. Detect, crop to the predicted oriented box, and detect again — the original detection must survive its own geometry. These tests need no ground truth, so they transfer to any dataset, and they caught a real defect: two pipeline stages augmenting over inconsistent rotation ranges, which took re-detection from 52% to 100% once fixed. No accuracy number was ever going to surface that.

What this does not show

The clinical cardiac axis, which needs a spine landmark this dataset does not carry. ±18° limits of agreement are not clinically useful. Segmentation failures were simulated, not sampled from a real segmenter. 50 held-out images. Not a medical device, and no clinical claim.

Reproduce it

Public CC-BY-4.0 data (FOCUS and FETAL_PLANES_DB), released weights, 63 tests in CI on Python 3.11–3.13, one command per figure in this page.

Full background hello@francescovigni.com GitHub