Skip to content

📦 WP-067 — release: v0.4.0 consolidated note and examples

Engineering log · Phase 10 — Consolidation

🔗 Depends on WP-066 · Needed by WP-113, WP-113b

⬅️ WP-110 · Roadmap · WP-111 ➡️

WP-067 — the drawing library that could not be installed

The example was going to use supervision, which draws boxes, masks and rotated boxes and is Apache-2.0 at its own metadata. It is not installed here, and the reason is WP-109: it hard-requires av>=14.2, whose wheel ships libx264 — GPL-2.0 — while declaring BSD-3-Clause and shipping a licence document that mentions no GPL anywhere. Neither existing licence check saw it (D16). So the example is drawn with matplotlib, which the repository already carries for the training figures (R29), and the refusal is the more durable artifact of the two: the example is a hundred lines anyone could rewrite, and the check that refuses the dependency now runs on every commit.

A dev dependency must not become a runtime one by being convenient. matplotlib is in the dev group and nothing under src/lucid_yolo/ imports it at any level, so a wheel a consumer installs pulls no plotting stack. That is why this is scripts/draw_predictions.py beside plot_training.py rather than a lucid_yolo.draw module, and it is also why the deliverable is a script rather than the notebook the row originally named: a notebook is not reachable by make gate, and an example nothing runs is an example that rots.

The drawing functions take an already-computed prediction and an image array rather than a checkpoint. That is what makes the geometry assertable at all — D14 ships no trained weights, so there is no checkpoint to draw from in a test, and a drawing function that insisted on doing its own inference could only have been tested through one.

The oriented case is the one with a wrong answer that looks right. An A45 row's first four columns are [cx, cy, w, h], which read as an xyxy box without complaint: a [:, :4] slice draws a plausible upright rectangle that is not the object the model reported, at the wrong place and the wrong size, and nothing in the figure says so. The corners come from rboxes_to_polygons, the same function the oriented report and the tile writer state an object with, so a drawn ring and a written ring are the same four points. The test asserts both halves — that the four vertices match the rotated corners, and that the ring is not axis-aligned — because the envelope of a rotated box contains all four of its corners too and would satisfy the first assertion alone.

Two smaller decisions worth the sentence each. Colour is a pure function of the class index, not a palette walked in encounter order, so two figures of the same scene are comparable by eye and a class missing from one image does not shift the colours around it. And masks are drawn one overlay per instance rather than one composited layer, because the question a segmentation figure is read to answer is which instance covers a pixel, and a single layer can only answer that some instance does — boxes and masks are filtered by one row mask computed once, since two filters are how a mask ends up drawn on its neighbour with the counts still agreeing.

What the tests cannot see is whether the figure reads. Artist assertions pin geometry, colour and count; legibility — where the label sits, whether the mask alpha leaves the object visible — was checked by rendering three previews and looking at them. That is stated rather than hidden, because the gate does not cover it and the next person changing the layout should know which half of this is machine-checked.