fix(axelera): emit normalized box coordinates (0..1)

Frigate detect() interprets detector boxes as fractions of the region and
discards any box resolving outside the frame. The plugin returned pixel
coordinates, so every detection was silently filtered out and no events
were ever created despite a working inference chain. Normalize by model
width/height (same contract as memryx/onnx). Live: 0 events -> 27 events
in ~70 s after the fix.
This commit is contained in:
patrykorwat 2026-08-18 06:48:23 +00:00
parent f17b5e95e3
commit 10b4394879
2 changed files with 17 additions and 5 deletions

View File

@ -177,7 +177,12 @@ class _AxeleraInference:
yield frame
def _detection_rows(self, frame_result) -> list:
"""Convert a stream result into (class_id, score, ymin, xmin, ymax, xmax) rows."""
"""Convert a stream result into (class_id, score, ymin, xmin, ymax, xmax) rows.
Box coordinates are NORMALIZED [0..1]: Frigate's detect() multiplies
them by the region size, pixel boxes are discarded as outside the frame
(zero events despite working detections).
"""
dets = getattr(frame_result, "detections", None) or []
rows = []
for det in dets:
@ -202,7 +207,14 @@ class _AxeleraInference:
continue
x0, y0, x1, y1 = box
rows.append(
(class_id, score, y0, x0, min(y1, self._height), min(x1, self._width))
(
class_id,
score,
y0 / self._height,
x0 / self._width,
min(y1, self._height) / self._height,
min(x1, self._width) / self._width,
)
)
rows.sort(key=lambda r: r[1], reverse=True)
return rows[:MAX_ROWS]

View File

@ -227,8 +227,8 @@ class TestAxeleraInference(unittest.TestCase):
ids = sorted(int(r[0]) for r in out if r[1] > 0)
self.assertEqual(ids, [0, 7]) # unknown_label dropped
rows = {int(r[0]): r for r in out if r[1] > 0}
# rows are [class_id, score, ymin, xmin, ymax, xmax] in pixels
self.assertEqual(tuple(rows[7][2:6]), (20.0, 10.0, 40.0, 30.0))
# rows are [class_id, score, ymin, xmin, ymax, xmax] NORMALIZED (0..1)
self.assertEqual(tuple(rows[7][2:6]), (0.0625, 0.03125, 0.125, 0.09375))
self.assertEqual(rows[0][1], 0.55)
finally:
engine.stop()
@ -291,7 +291,7 @@ class TestAxeleraInference(unittest.TestCase):
truck = [r for r in out if int(r[0]) == 7 and r[1] > 0]
self.assertTrue(truck, "expected truck row")
self.assertAlmostEqual(float(truck[0][1]), 0.8, places=2)
self.assertEqual(tuple(truck[0][2:6]), (20.0, 10.0, 40.0, 30.0))
self.assertEqual(tuple(truck[0][2:6]), (0.0625, 0.03125, 0.125, 0.09375))
finally:
engine.stop()