Repository navigation
Release v1.8.0 - Orientation Error, the IoU Ladder, and a Signed Morphological Kernel
Release v1.8.0 - Orientation Error, the IoU Ladder, and a Signed Morphological Kernel
A feature release, driven by a 28-hour ensemble sweep whose nine model configurations landed within 0.0060 mean IoU of each other, against a resolution floor of 0.0015. Two things came out of that: a score that saturates cannot rank models, and a morphology axis swept in one direction only cannot answer what it was asked. Both are addressed here. Conversion output is unchanged for any configuration that was expressible before, so existing annotations and benchmark results stay valid.
✨ Features
-
The evaluator reports what the mean cannot show. Beside average IoU,
hbb2obb-evaland every grid point ofhbb2obb-optimizenow record the median IoU, the orientation error of every matched pair (median, mean, std, p90) and the share of pairs at or above IoU 0.5, 0.75, 0.85 and 0.9, overall and per class. Orientation is taken from a box's longer side and wraps at 180 degrees, since a box turned end for end is the same box, so the largest possible error is a right angle rather than a half turn. On the bundled sample a mean IoU of 0.8964 hides a median orientation error of 1.04 degrees with a p90 of 4.40, and a motorcycle class at 9.95 degrees against 1.00 for cars.These are reported, never optimized. The grid search still ranks by mean IoU, so a sweep stays directly comparable with one measured before this release.
-
The morphological kernel is one signed axis. The magnitude of
--opening_kernel_percentagesets the kernel size and the sign now picks the operation: positive opens as before, negative closes, zero is off in the middle. Opening can only remove pixels; closing can only add them. That asymmetry matters because the converter keeps the largest contour only, so a vehicle split in two by windscreen glare, a roof-colour break or an occluding pole loses the smaller piece permanently. Closing runs before that choice is made and is the only step in the pipeline that can undo it. The mirror risk, reaching across a narrow gap to a neighbouring object, is bounded by the clip to the expanded HBB. -
Plots can draw a metric other than the one being ranked.
--plot_metric/-pmtakesavg_iou(default),median_iou,median_angle_error,p90_angle_error,iou_at_75oriou_at_90, and works under--refresh, so an existing sweep is redrawn against any of them without running SAM again. A metric carries whether higher is better, so the Pareto front oncomparison.pngflips for an error, and a run plot stars the grid point that metric prefers, which is worth seeing precisely when it is not the one that won.
🛡️ Robustness
- Results measured before these metrics existed record none of them, and both readers degrade rather than fail:
summary.mdleaves those columns empty, a run folder with nothing to draw is reported and skipped while the rest of the benchmark renders, and the summary says why its figure is missing. - An unknown
--plot_metricis rejected before any sweep starts, so a typo cannot surface hours into a long run with the grid already measured.
ℹ️ Notes
avg_iouremains the default plot metric and its render is unchanged: the 18 plots shipped indata/benchmark_results/still reproduce byte for byte, which the test suite pins.- Nothing about the conversion changed for a non-negative kernel, so existing annotations need no regeneration. The bundled
data/benchmark_results/predates these metrics and records none of them; it is a fixture and is deliberately not re-run. - Precision, recall and F1 carry no information on a reference set where each oriented box has exactly one horizontal box of the same class by construction: every grid point matches all of them. The new scores exist for exactly that case.
- Test suite grew from 318 to 328.
📦 Installation
pip install --upgrade hbb2obbFull Changelog: v1.7.0...v1.8.0