@camstack/addon-pipeline 1.2.294 → 1.2.295
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_MODELS.md +233 -0
- package/dist/audio-analyzer/index.js +2 -2
- package/dist/audio-analyzer/index.mjs +2 -2
- package/dist/{default-detection-model-0dPKRKUD.mjs → default-detection-model-CAUBVbgK.mjs} +107 -54
- package/dist/{default-detection-model-D24AJOTn.js → default-detection-model-wNEISVA9.js} +107 -54
- package/dist/detection-pipeline/index.js +284 -457
- package/dist/detection-pipeline/index.mjs +284 -457
- package/dist/{dist-CJR259Xf.js → dist-BsVcf5wO.js} +1310 -832
- package/dist/{dist-RXbmRAwP.mjs → dist-CuxSNLKW.mjs} +1305 -833
- package/dist/motion-wasm/index.js +1 -1
- package/dist/motion-wasm/index.mjs +1 -1
- package/dist/{node-atmRSHPk.mjs → node-Cqb1QiXk.mjs} +1 -1
- package/dist/{node-DWg9zbY1.js → node-UFk6I2f6.js} +1 -1
- package/dist/pipeline-runner/index.js +189 -70
- package/dist/pipeline-runner/index.mjs +189 -70
- package/dist/{process-memory-BJUXvTjd.js → process-memory-CJV29sPf.js} +1 -1
- package/dist/{process-memory-BgFOHFnx.mjs → process-memory-D0Nvs9rr.mjs} +1 -1
- package/dist/recorder/index.js +12 -2
- package/dist/recorder/index.mjs +12 -2
- package/dist/{segment-demux-js-C_fPJub3.js → segment-demux-js-DGwmf5hu.js} +1 -1
- package/dist/{segment-demux-js-G7wFpHzn.mjs → segment-demux-js-DIDWw1iE.mjs} +1 -1
- package/dist/stream-broker/_stub.js +2 -2
- package/dist/stream-broker/{_virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-6IyM-BIn.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_stream_broker_widgets-B7nBFqva.mjs} +2 -2
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-CCIyBvRa.mjs +26 -0
- package/dist/stream-broker/{_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DoyA71_q.mjs → _virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DeD_UFdb.mjs} +1 -1
- package/dist/stream-broker/demux-worker-child.js +1 -1
- package/dist/stream-broker/demux-worker-child.mjs +1 -1
- package/dist/stream-broker/{hostInit-BBYHWS3M.mjs → hostInit-BKlb3qac.mjs} +2 -2
- package/dist/stream-broker/index.js +3 -3
- package/dist/stream-broker/index.mjs +3 -3
- package/dist/stream-broker/remoteEntry.js +1 -1
- package/package.json +3 -2
- package/python/postprocessors/__init__.py +2 -0
- package/python/postprocessors/ssd.py +73 -17
- package/python/postprocessors/test_ssd.py +205 -0
- package/python/postprocessors/test_yunet.py +292 -0
- package/python/postprocessors/testdata/ssdlite_mobiledet_outputs.json +1 -0
- package/python/postprocessors/yunet.py +275 -0
- package/dist/stream-broker/_virtual_mf___mfe_internal__addon_stream_broker_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-6IHzlLJ_.mjs +0 -26
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"""Pins the SSD decoder on REAL SSDLite MobileDet output tensors.
|
|
2
|
+
|
|
3
|
+
`ssdlite-mobiledet-coco-edgetpu` joins the two Coral detectors that already use
|
|
4
|
+
`postprocessor: 'ssd'`. Its graph ends in the same `TFLite_Detection_PostProcess`
|
|
5
|
+
op, but nothing had checked that the decoder reads MobileDet's outputs the way
|
|
6
|
+
the model writes them. Each class below pins one thing that could silently turn
|
|
7
|
+
a working model into wrong labels or empty frames:
|
|
8
|
+
|
|
9
|
+
- the output ORDER (boxes, classes, scores, count on positional keys "0".."3");
|
|
10
|
+
- the class-index OFFSET (91 score columns, background dropped by the op, so
|
|
11
|
+
the emitted index is 0-based and 0 is person);
|
|
12
|
+
- the COUNT clamp (MobileDet emits N=100 rows, not 20 like SSD MobileNet V2);
|
|
13
|
+
- the letterbox inversion, against boxes an unrelated detector (DETR) drew on
|
|
14
|
+
the same COCO frame;
|
|
15
|
+
- the score CEILING of this quantised graph (about 0.771), which decides which
|
|
16
|
+
confidence thresholds can ever pass.
|
|
17
|
+
|
|
18
|
+
The fixture (`testdata/ssdlite_mobiledet_outputs.json`) holds the model's raw
|
|
19
|
+
outputs on two COCO val2017 frames; its `_provenance` says how they were made.
|
|
20
|
+
|
|
21
|
+
`unittest.TestCase` with no numpy: `scripts/test-python-pool.sh` runs these on
|
|
22
|
+
CI's bare interpreter, where numpy is absent, and `ssd.py` decodes plain lists
|
|
23
|
+
for exactly that reason. The one case that needs numpy (ndarray inputs decode
|
|
24
|
+
the same as lists) is skipped, by name, without it.
|
|
25
|
+
"""
|
|
26
|
+
import json
|
|
27
|
+
import os
|
|
28
|
+
import unittest
|
|
29
|
+
|
|
30
|
+
try: # real numpy when the sandbox has it
|
|
31
|
+
import numpy as _numpy_probe
|
|
32
|
+
except ImportError:
|
|
33
|
+
_numpy_probe = None
|
|
34
|
+
|
|
35
|
+
# `ndarray` is real-numpy-only: a stub another test module installed would import.
|
|
36
|
+
_HAS_REAL_NUMPY = _numpy_probe is not None and hasattr(_numpy_probe, "ndarray")
|
|
37
|
+
|
|
38
|
+
from ssd import COCO_90, label_for_class, postprocess_ssd # noqa: E402
|
|
39
|
+
|
|
40
|
+
_FIXTURE = os.path.join(os.path.dirname(os.path.abspath(__file__)), "testdata",
|
|
41
|
+
"ssdlite_mobiledet_outputs.json")
|
|
42
|
+
with open(_FIXTURE, encoding="utf-8") as _fh:
|
|
43
|
+
_FRAMES = json.load(_fh)["frames"]
|
|
44
|
+
|
|
45
|
+
CATS = _FRAMES["coco_val2017_000000039769_two_cats"]
|
|
46
|
+
STREET = _FRAMES["coco_val2017_000000252219_street"]
|
|
47
|
+
|
|
48
|
+
# The catalog entry's input side; the pool sets `inputSize` from the graph.
|
|
49
|
+
INPUT_SIZE = 320
|
|
50
|
+
# The score column of this graph is LOGISTIC over a uint8 logit quantised at
|
|
51
|
+
# scale 0.046695, zero point 229, so the largest logit it can carry is
|
|
52
|
+
# (255 - 229) * 0.046695 = 1.2141 and sigmoid(1.2141) = 0.77102.
|
|
53
|
+
SCORE_CEILING = 0.77102
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _decode(frame: dict, confidence: float = 0.5, outputs: "dict | None" = None) -> list:
|
|
57
|
+
width, height = frame["orig"]
|
|
58
|
+
result = postprocess_ssd(
|
|
59
|
+
outputs if outputs is not None else frame["outputs"],
|
|
60
|
+
{"confidence": confidence, "inputSize": INPUT_SIZE},
|
|
61
|
+
width, height, frame["scale"], tuple(frame["pad"]),
|
|
62
|
+
)
|
|
63
|
+
return result["detections"]
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _iou(a: list, b: list) -> float:
|
|
67
|
+
ix = max(0.0, min(a[2], b[2]) - max(a[0], b[0]))
|
|
68
|
+
iy = max(0.0, min(a[3], b[3]) - max(a[1], b[1]))
|
|
69
|
+
inter = ix * iy
|
|
70
|
+
union = (a[2] - a[0]) * (a[3] - a[1]) + (b[2] - b[0]) * (b[3] - b[1]) - inter
|
|
71
|
+
return inter / union if union > 0 else 0.0
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class FixtureShapeTest(unittest.TestCase):
|
|
75
|
+
"""The fixture is what the MobileDet graph emits: [1,100,4] [1,100] [1,100] [1]."""
|
|
76
|
+
|
|
77
|
+
def test_output_shapes(self) -> None:
|
|
78
|
+
for frame in (CATS, STREET):
|
|
79
|
+
out = frame["outputs"]
|
|
80
|
+
self.assertEqual(len(out["0"]), 1)
|
|
81
|
+
self.assertEqual(len(out["0"][0]), 100)
|
|
82
|
+
self.assertTrue(all(len(row) == 4 for row in out["0"][0]))
|
|
83
|
+
self.assertEqual(len(out["1"][0]), 100)
|
|
84
|
+
self.assertEqual(len(out["2"][0]), 100)
|
|
85
|
+
self.assertEqual(out["3"], [100.0])
|
|
86
|
+
|
|
87
|
+
def test_scores_are_sorted_descending(self) -> None:
|
|
88
|
+
# TFLite_Detection_PostProcess ranks by score; a reordered export would not.
|
|
89
|
+
scores = STREET["outputs"]["2"][0]
|
|
90
|
+
self.assertEqual(scores, sorted(scores, reverse=True))
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class OutputOrderTest(unittest.TestCase):
|
|
94
|
+
"""Positional "1" is CLASSES and "2" is SCORES. Swapped, the labels are nonsense."""
|
|
95
|
+
|
|
96
|
+
def test_cats_decode_as_cats(self) -> None:
|
|
97
|
+
labels = [d["class"] for d in _decode(CATS)]
|
|
98
|
+
self.assertEqual(labels.count("cat"), 2, labels)
|
|
99
|
+
|
|
100
|
+
def test_street_decodes_three_people(self) -> None:
|
|
101
|
+
people = [d for d in _decode(STREET) if d["class"] == "person"]
|
|
102
|
+
self.assertEqual(len(people), 3)
|
|
103
|
+
# Left, middle and right of the frame.
|
|
104
|
+
centres = sorted((d["bbox"][0] + d["bbox"][2]) / 2 for d in people)
|
|
105
|
+
self.assertLess(centres[0], 200)
|
|
106
|
+
self.assertTrue(250 < centres[1] < 450, centres)
|
|
107
|
+
self.assertGreater(centres[2], 500)
|
|
108
|
+
|
|
109
|
+
def test_every_score_is_a_probability(self) -> None:
|
|
110
|
+
for frame in (CATS, STREET):
|
|
111
|
+
self.assertTrue(all(0.0 <= s <= 1.0 for s in frame["outputs"]["2"][0]))
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
class ClassOffsetTest(unittest.TestCase):
|
|
115
|
+
"""Emitted class index = COCO-90 line number of `coco_labels.txt`, 0 = person."""
|
|
116
|
+
|
|
117
|
+
def test_raw_indices_behind_the_labels(self) -> None:
|
|
118
|
+
classes = STREET["outputs"]["1"][0]
|
|
119
|
+
scores = STREET["outputs"]["2"][0]
|
|
120
|
+
top = [int(c) for c, s in zip(classes, scores) if s >= 0.7]
|
|
121
|
+
self.assertEqual(set(top), {0}) # the three people
|
|
122
|
+
cat_classes = {int(c) for c, s in zip(CATS["outputs"]["1"][0], CATS["outputs"]["2"][0]) if s >= 0.7}
|
|
123
|
+
self.assertEqual(cat_classes, {16})
|
|
124
|
+
|
|
125
|
+
def test_label_map(self) -> None:
|
|
126
|
+
self.assertEqual(len(COCO_90), 90)
|
|
127
|
+
self.assertEqual(label_for_class(0), "person")
|
|
128
|
+
self.assertEqual(label_for_class(2), "car")
|
|
129
|
+
self.assertEqual(label_for_class(16), "cat")
|
|
130
|
+
self.assertEqual(label_for_class(17), "dog")
|
|
131
|
+
self.assertEqual(label_for_class(89), "toothbrush")
|
|
132
|
+
self.assertEqual(label_for_class(11), "n/a")
|
|
133
|
+
self.assertEqual(label_for_class(90), "90")
|
|
134
|
+
|
|
135
|
+
def test_gap_classes_are_dropped(self) -> None:
|
|
136
|
+
out = {k: v for k, v in STREET["outputs"].items()}
|
|
137
|
+
out["1"] = [[11.0] + list(STREET["outputs"]["1"][0][1:])] # "n/a" on the top row
|
|
138
|
+
labels = [d["class"] for d in _decode(STREET, outputs=out)]
|
|
139
|
+
self.assertNotIn("n/a", labels)
|
|
140
|
+
self.assertEqual(labels.count("person"), 2)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
class CountClampTest(unittest.TestCase):
|
|
144
|
+
"""All 100 rows are read when count says 100, and only `count` rows otherwise."""
|
|
145
|
+
|
|
146
|
+
def test_low_threshold_reads_past_row_20(self) -> None:
|
|
147
|
+
# SSD MobileNet V2 stops at 20 rows; MobileDet's detections go on to row 100.
|
|
148
|
+
dets = _decode(STREET, confidence=0.01)
|
|
149
|
+
self.assertGreater(len(dets), 20)
|
|
150
|
+
|
|
151
|
+
def test_count_limits_the_rows(self) -> None:
|
|
152
|
+
out = dict(STREET["outputs"])
|
|
153
|
+
out["3"] = [2.0]
|
|
154
|
+
self.assertEqual(len(_decode(STREET, confidence=0.01, outputs=out)), 2)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class LetterboxGeometryTest(unittest.TestCase):
|
|
158
|
+
"""Boxes land in ORIGINAL-frame pixels, where another detector puts the same cats."""
|
|
159
|
+
|
|
160
|
+
# DETR ResNet-50 on this exact COCO frame (the facebook/detr-resnet-50 model
|
|
161
|
+
# card example): an independent reference for where the two cats are.
|
|
162
|
+
DETR_CATS = ([13.24, 52.05, 314.02, 470.93], [345.4, 23.85, 640.37, 368.72])
|
|
163
|
+
|
|
164
|
+
def test_cats_match_the_reference_boxes(self) -> None:
|
|
165
|
+
cats = [d["bbox"] for d in _decode(CATS) if d["class"] == "cat"]
|
|
166
|
+
for ref in self.DETR_CATS:
|
|
167
|
+
best = max(_iou(ref, box) for box in cats)
|
|
168
|
+
self.assertGreater(best, 0.85, (ref, cats))
|
|
169
|
+
|
|
170
|
+
def test_boxes_stay_inside_the_frame(self) -> None:
|
|
171
|
+
for frame in (CATS, STREET):
|
|
172
|
+
width, height = frame["orig"]
|
|
173
|
+
for d in _decode(frame, confidence=0.01):
|
|
174
|
+
x1, y1, x2, y2 = d["bbox"]
|
|
175
|
+
self.assertTrue(0 <= x1 < x2 <= width and 0 <= y1 < y2 <= height, d)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class ScoreCeilingTest(unittest.TestCase):
|
|
179
|
+
"""This graph cannot score above ~0.771, so a stricter threshold returns nothing."""
|
|
180
|
+
|
|
181
|
+
def test_no_score_exceeds_the_ceiling(self) -> None:
|
|
182
|
+
for frame in (CATS, STREET):
|
|
183
|
+
self.assertLessEqual(max(frame["outputs"]["2"][0]), SCORE_CEILING)
|
|
184
|
+
|
|
185
|
+
def test_the_ceiling_is_reached(self) -> None:
|
|
186
|
+
self.assertAlmostEqual(max(CATS["outputs"]["2"][0]), 0.76953125)
|
|
187
|
+
|
|
188
|
+
def test_threshold_above_the_ceiling_finds_nothing(self) -> None:
|
|
189
|
+
self.assertEqual(_decode(STREET, confidence=0.78), [])
|
|
190
|
+
self.assertEqual(len([d for d in _decode(STREET, confidence=0.65) if d["class"] == "person"]), 3)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
class NumpyInputTest(unittest.TestCase):
|
|
194
|
+
"""The pool hands ndarrays; they must decode exactly like the lists above."""
|
|
195
|
+
|
|
196
|
+
@unittest.skipUnless(_HAS_REAL_NUMPY, "needs real numpy (not on CI's bare interpreter)")
|
|
197
|
+
def test_ndarrays_decode_like_lists(self) -> None:
|
|
198
|
+
np = _numpy_probe
|
|
199
|
+
for frame in (CATS, STREET):
|
|
200
|
+
arrays = {k: np.asarray(v, dtype=np.float32) for k, v in frame["outputs"].items()}
|
|
201
|
+
self.assertEqual(_decode(frame, confidence=0.3, outputs=arrays), _decode(frame, confidence=0.3))
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
if __name__ == "__main__":
|
|
205
|
+
unittest.main()
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
"""Pins the YuNet decoder: prior layout, box/landmark decode, landmark order.
|
|
2
|
+
|
|
3
|
+
YuNet out of the box found 0 faces on 413 person crops through the SCRFD
|
|
4
|
+
decoder (2026-09-26 model-replacement spike, §2.2): one prior per cell instead
|
|
5
|
+
of two, centre+exp(size) boxes instead of anchor distances, and a score split
|
|
6
|
+
across `cls_*` and `obj_*`. Each class below pins one of those.
|
|
7
|
+
|
|
8
|
+
`unittest.TestCase`, not pytest-style: `scripts/test-python-pool.sh` runs the
|
|
9
|
+
`unittest.TestCase` modules on CI's bare interpreter — the self-hosted runner
|
|
10
|
+
has NO numpy. So everything that decides is plain Python and tested here
|
|
11
|
+
without it: prior layout, decode, landmark order, the score, NMS, the top-K cap,
|
|
12
|
+
and the output gate (`check_outputs` runs before `postprocess_yunet` touches
|
|
13
|
+
numpy, so its refusals are exercised through `postprocess_yunet` itself).
|
|
14
|
+
|
|
15
|
+
What genuinely needs real numpy, and is SKIPPED (named) without it: the
|
|
16
|
+
vectorised pre-filter (`np.maximum(cls, obj) >= conf`), and the decode of a
|
|
17
|
+
live prior through `postprocess_yunet` end to end (flatten/reshape of the
|
|
18
|
+
tensors, the cap applied inside it). Those run wherever numpy is installed —
|
|
19
|
+
every pool host — and in the spike harness.
|
|
20
|
+
"""
|
|
21
|
+
import math
|
|
22
|
+
import sys
|
|
23
|
+
import types
|
|
24
|
+
import unittest
|
|
25
|
+
|
|
26
|
+
try: # real numpy when the sandbox has it
|
|
27
|
+
import numpy as _numpy_probe # noqa: F401
|
|
28
|
+
except ImportError:
|
|
29
|
+
_numpy_probe = None
|
|
30
|
+
|
|
31
|
+
# `ndarray` is real-numpy-only: a stub another module installed would import.
|
|
32
|
+
_HAS_REAL_NUMPY = _numpy_probe is not None and hasattr(_numpy_probe, "ndarray")
|
|
33
|
+
|
|
34
|
+
# Without numpy, `yunet.py`'s `import numpy` is satisfied by an EMPTY stub for
|
|
35
|
+
# the duration of the import only, and the stub is removed again at once: a
|
|
36
|
+
# stub left in `sys.modules` would be picked up by the next test module in the
|
|
37
|
+
# same `python3 -m unittest` process (test_scrfd needs `np.ceil` from its OWN
|
|
38
|
+
# stub), making the result depend on module order. `yunet` keeps its own
|
|
39
|
+
# reference; nothing it runs here touches it.
|
|
40
|
+
if _numpy_probe is None:
|
|
41
|
+
sys.modules["numpy"] = types.ModuleType("numpy")
|
|
42
|
+
try:
|
|
43
|
+
import yunet # noqa: F401
|
|
44
|
+
finally:
|
|
45
|
+
del sys.modules["numpy"]
|
|
46
|
+
|
|
47
|
+
from yunet import ( # noqa: E402
|
|
48
|
+
NUM_LANDMARKS,
|
|
49
|
+
STRIDES,
|
|
50
|
+
TOP_K,
|
|
51
|
+
cap_top_k,
|
|
52
|
+
check_outputs,
|
|
53
|
+
decode_prior,
|
|
54
|
+
grid_cols,
|
|
55
|
+
missing_outputs,
|
|
56
|
+
nms,
|
|
57
|
+
postprocess_yunet,
|
|
58
|
+
prior_cell,
|
|
59
|
+
score_of,
|
|
60
|
+
to_source,
|
|
61
|
+
value_count,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class PriorLayoutTest(unittest.TestCase):
|
|
66
|
+
"""One prior per cell, row-major — NOT SCRFD's two anchors per cell."""
|
|
67
|
+
|
|
68
|
+
def test_grid_is_one_prior_per_cell_at_640(self):
|
|
69
|
+
self.assertEqual([grid_cols(s, 640) for s in STRIDES], [80, 40, 20])
|
|
70
|
+
# 6400 + 1600 + 400. SCRFD's layout would be twice this (16800).
|
|
71
|
+
self.assertEqual(sum(grid_cols(s, 640) ** 2 for s in STRIDES), 8400)
|
|
72
|
+
|
|
73
|
+
def test_index_is_row_major(self):
|
|
74
|
+
cols = grid_cols(8, 640)
|
|
75
|
+
self.assertEqual(prior_cell(0, cols), (0, 0))
|
|
76
|
+
self.assertEqual(prior_cell(1, cols), (0, 1)) # SCRFD: index 1 is still cell (0,0)
|
|
77
|
+
self.assertEqual(prior_cell(cols + 2, cols), (1, 2))
|
|
78
|
+
self.assertEqual(prior_cell(cols * cols - 1, cols), (cols - 1, cols - 1))
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class DecodeTest(unittest.TestCase):
|
|
82
|
+
def test_box_is_centre_plus_exp_size_from_the_cell_corner(self):
|
|
83
|
+
# cell (row 1, col 2) at stride 8; centre offset (0.5, 0.5) → centre
|
|
84
|
+
# ((2+.5)*8, (1+.5)*8) = (20, 12); log size 0 → 8×8.
|
|
85
|
+
box, _ = decode_prior(8, 1, 2, [0.5, 0.5, 0.0, 0.0], [0.0] * 10)
|
|
86
|
+
self.assertEqual(box, (16.0, 8.0, 24.0, 16.0))
|
|
87
|
+
|
|
88
|
+
def test_size_is_exponential(self):
|
|
89
|
+
box, _ = decode_prior(16, 0, 0, [0.0, 0.0, math.log(3.0), math.log(2.0)], [0.0] * 10)
|
|
90
|
+
x1, y1, x2, y2 = box
|
|
91
|
+
self.assertAlmostEqual(x2 - x1, 48.0, places=4) # 3 * 16
|
|
92
|
+
self.assertAlmostEqual(y2 - y1, 32.0, places=4) # 2 * 16
|
|
93
|
+
|
|
94
|
+
def test_landmarks_are_cell_relative_in_stride_units(self):
|
|
95
|
+
kps = [0.25, 0.5, 0.75, 0.5, 0.5, 1.0, 0.25, 1.5, 0.75, 1.5]
|
|
96
|
+
_, points = decode_prior(32, 3, 4, [0.0, 0.0, 0.0, 0.0], kps)
|
|
97
|
+
self.assertEqual(len(points), NUM_LANDMARKS)
|
|
98
|
+
self.assertEqual(points[0], ((4 + 0.25) * 32, (3 + 0.5) * 32))
|
|
99
|
+
self.assertEqual(points[2], ((4 + 0.5) * 32, (3 + 1.0) * 32))
|
|
100
|
+
|
|
101
|
+
def test_score_is_geometric_mean_of_clamped_cls_and_obj(self):
|
|
102
|
+
self.assertAlmostEqual(score_of(0.81, 1.0), 0.9)
|
|
103
|
+
self.assertAlmostEqual(score_of(0.64, 0.25), 0.4)
|
|
104
|
+
self.assertEqual(score_of(1.3, 1.0), 1.0)
|
|
105
|
+
self.assertEqual(score_of(-0.2, 1.0), 0.0)
|
|
106
|
+
|
|
107
|
+
def test_to_source_undoes_the_letterbox(self):
|
|
108
|
+
# 320×160 crop letterboxed into 640: scale 2, pad (0, 160).
|
|
109
|
+
self.assertEqual(to_source(100.0, 260.0, 2.0, (0, 160)), (50.0, 50.0))
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class LandmarkOrderTest(unittest.TestCase):
|
|
113
|
+
"""YuNet emits the SUBJECT's right eye first = image-LEFT eye, which is
|
|
114
|
+
the order `face-align.ts` maps onto ARCFACE_TEMPLATE_112. The decoder must
|
|
115
|
+
pass the five points through in model order — a sort or a swap here
|
|
116
|
+
mirrors every aligned face."""
|
|
117
|
+
|
|
118
|
+
def test_points_keep_model_order(self):
|
|
119
|
+
# A frontal face: image-left eye, image-right eye, nose, mouth L, mouth R.
|
|
120
|
+
kps = [0.2, 0.3, 0.8, 0.3, 0.5, 0.55, 0.3, 0.8, 0.7, 0.8]
|
|
121
|
+
_, points = decode_prior(8, 0, 0, [0.5, 0.5, 0.0, 0.0], kps)
|
|
122
|
+
xs = [p[0] for p in points]
|
|
123
|
+
self.assertLess(xs[0], xs[1]) # eye 0 is image-left
|
|
124
|
+
self.assertLess(xs[3], xs[4]) # mouth 3 is image-left
|
|
125
|
+
self.assertEqual([round(x, 3) for x in xs], [1.6, 6.4, 4.0, 2.4, 5.6])
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class MissingOutputsTest(unittest.TestCase):
|
|
129
|
+
"""Name-only matching: a model without YuNet's twelve named tensors is
|
|
130
|
+
refused, not decoded as "no faces"."""
|
|
131
|
+
|
|
132
|
+
def test_all_twelve_present(self):
|
|
133
|
+
names = [f"{k}_{s}" for k in ("cls", "obj", "bbox", "kps") for s in STRIDES]
|
|
134
|
+
self.assertEqual(missing_outputs(names), [])
|
|
135
|
+
|
|
136
|
+
def test_names_what_is_missing(self):
|
|
137
|
+
names = [f"{k}_{s}" for k in ("cls", "bbox", "kps") for s in STRIDES]
|
|
138
|
+
self.assertEqual(missing_outputs(names), ["obj_8", "obj_16", "obj_32"])
|
|
139
|
+
|
|
140
|
+
def test_scrfd_style_outputs_are_refused(self):
|
|
141
|
+
names = [f"{k}_{s}" for k in ("score", "bbox", "kps") for s in STRIDES]
|
|
142
|
+
self.assertIn("cls_8", missing_outputs(names))
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _list_outputs(input_size=640, drop=()):
|
|
146
|
+
"""Correctly-SHAPED outputs as nested lists — no numpy needed."""
|
|
147
|
+
out = {}
|
|
148
|
+
for s in STRIDES:
|
|
149
|
+
n = grid_cols(s, input_size) ** 2
|
|
150
|
+
for kind, width in (("cls", 1), ("obj", 1), ("bbox", 4), ("kps", 10)):
|
|
151
|
+
if f"{kind}_{s}" not in drop:
|
|
152
|
+
out[f"{kind}_{s}"] = [[[0.0] * width for _ in range(n)]]
|
|
153
|
+
return out
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
class OutputGateTest(unittest.TestCase):
|
|
157
|
+
"""`check_outputs` runs before any numpy call, so these go through
|
|
158
|
+
`postprocess_yunet` itself on the bare interpreter."""
|
|
159
|
+
|
|
160
|
+
def test_missing_output_raises_instead_of_reporting_no_faces(self):
|
|
161
|
+
raw = _list_outputs(drop=("obj_32",))
|
|
162
|
+
with self.assertRaises(ValueError) as ctx:
|
|
163
|
+
postprocess_yunet(raw, {"confidence": 0.5}, 640, 640, 1.0, (0, 0))
|
|
164
|
+
self.assertIn("obj_32", str(ctx.exception))
|
|
165
|
+
|
|
166
|
+
def test_wrong_input_size_raises(self):
|
|
167
|
+
raw = _list_outputs(input_size=320)
|
|
168
|
+
with self.assertRaises(ValueError) as ctx:
|
|
169
|
+
postprocess_yunet(raw, {"confidence": 0.5, "inputSize": 640}, 640, 640, 1.0, (0, 0))
|
|
170
|
+
self.assertIn("does not match the model", str(ctx.exception))
|
|
171
|
+
|
|
172
|
+
def test_correct_outputs_pass_the_gate(self):
|
|
173
|
+
check_outputs(_list_outputs(), 640) # no raise
|
|
174
|
+
|
|
175
|
+
def test_value_count_of_nested_lists(self):
|
|
176
|
+
self.assertEqual(value_count([[[0.0] * 4 for _ in range(3)]]), 12)
|
|
177
|
+
self.assertEqual(value_count(7.0), 1)
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
class TopKCapTest(unittest.TestCase):
|
|
181
|
+
"""The pure-Python NMS is O(n·kept): 5000 disjoint candidates took 2.8 s.
|
|
182
|
+
At most TOP_K, the best by score, may reach it."""
|
|
183
|
+
|
|
184
|
+
def _cands(self, n):
|
|
185
|
+
return [{"score": (i % 997) / 997.0, "_xyxy": (i, 0, i + 1, 1)} for i in range(n)]
|
|
186
|
+
|
|
187
|
+
def test_under_the_cap_is_untouched(self):
|
|
188
|
+
cands = self._cands(10)
|
|
189
|
+
kept, dropped = cap_top_k(cands)
|
|
190
|
+
self.assertIs(kept, cands)
|
|
191
|
+
self.assertEqual(dropped, 0)
|
|
192
|
+
|
|
193
|
+
def test_over_the_cap_keeps_the_best_k(self):
|
|
194
|
+
cands = self._cands(TOP_K + 250)
|
|
195
|
+
kept, dropped = cap_top_k(cands)
|
|
196
|
+
self.assertEqual(len(kept), TOP_K)
|
|
197
|
+
self.assertEqual(dropped, 250)
|
|
198
|
+
worst_kept = min(c["score"] for c in kept)
|
|
199
|
+
best_dropped = max(c["score"] for c in cands if c not in kept)
|
|
200
|
+
self.assertGreaterEqual(worst_kept, best_dropped)
|
|
201
|
+
|
|
202
|
+
def test_cap_is_well_below_upstream_and_above_real_frames(self):
|
|
203
|
+
# upstream 5000 (C++ NMS); measured max 110 candidates/frame at 0.1.
|
|
204
|
+
self.assertLessEqual(TOP_K, 5000)
|
|
205
|
+
self.assertGreaterEqual(TOP_K, 110 * 5)
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class NmsTest(unittest.TestCase):
|
|
209
|
+
def test_keeps_best_of_overlapping_and_disjoint(self):
|
|
210
|
+
cands = [
|
|
211
|
+
{"score": 0.6, "_xyxy": (0, 0, 10, 10)},
|
|
212
|
+
{"score": 0.9, "_xyxy": (1, 1, 11, 11)},
|
|
213
|
+
{"score": 0.7, "_xyxy": (50, 50, 60, 60)},
|
|
214
|
+
]
|
|
215
|
+
kept = nms(cands, 0.45)
|
|
216
|
+
self.assertEqual([k["score"] for k in kept], [0.9, 0.7])
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def _outputs(np, input_size=640, live=None):
|
|
220
|
+
"""Raw YuNet-shaped outputs, all priors dead except `live`:
|
|
221
|
+
{stride: (index, cls, obj, bbox4, kps10)}."""
|
|
222
|
+
out = {}
|
|
223
|
+
for s in STRIDES:
|
|
224
|
+
n = grid_cols(s, input_size) ** 2
|
|
225
|
+
out[f"cls_{s}"] = np.zeros((1, n, 1), np.float32)
|
|
226
|
+
out[f"obj_{s}"] = np.zeros((1, n, 1), np.float32)
|
|
227
|
+
out[f"bbox_{s}"] = np.zeros((1, n, 4), np.float32)
|
|
228
|
+
out[f"kps_{s}"] = np.zeros((1, n, 10), np.float32)
|
|
229
|
+
for s, (index, cls, obj, bbox, kps) in (live or {}).items():
|
|
230
|
+
out[f"cls_{s}"][0, index, 0] = cls
|
|
231
|
+
out[f"obj_{s}"][0, index, 0] = obj
|
|
232
|
+
out[f"bbox_{s}"][0, index] = bbox
|
|
233
|
+
out[f"kps_{s}"][0, index] = kps
|
|
234
|
+
return out
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
@unittest.skipUnless(_HAS_REAL_NUMPY, "postprocess_yunet round trip needs real ndarray ops")
|
|
238
|
+
class PostprocessYunetRoundTripTest(unittest.TestCase):
|
|
239
|
+
def setUp(self):
|
|
240
|
+
import numpy as np
|
|
241
|
+
|
|
242
|
+
self.np = np
|
|
243
|
+
|
|
244
|
+
def test_one_live_prior_decodes_to_source_pixels(self):
|
|
245
|
+
cols = grid_cols(16, 640)
|
|
246
|
+
index = 10 * cols + 20 # row 10, col 20
|
|
247
|
+
kps = [0.2, 0.3, 0.8, 0.3, 0.5, 0.55, 0.3, 0.8, 0.7, 0.8]
|
|
248
|
+
raw = _outputs(self.np, live={16: (index, 0.81, 1.0, [0.5, 0.5, math.log(4), math.log(4)], kps)})
|
|
249
|
+
# 1280×640 frame letterboxed into 640: scale 0.5, pad (0, 160).
|
|
250
|
+
out = postprocess_yunet(raw, {"confidence": 0.5, "inputSize": 640}, 1280, 640, 0.5, (0, 160))
|
|
251
|
+
dets = out["detections"]
|
|
252
|
+
self.assertEqual(len(dets), 1)
|
|
253
|
+
d = dets[0]
|
|
254
|
+
self.assertEqual(d["class"], "face")
|
|
255
|
+
self.assertAlmostEqual(d["score"], 0.9, places=3)
|
|
256
|
+
# network centre (328, 168), size 64 → [296,136,360,200] → source /0.5, y-160.
|
|
257
|
+
self.assertEqual(d["bbox"], [592.0, 0.0, 720.0, 80.0])
|
|
258
|
+
self.assertEqual(len(d["landmarks"]), NUM_LANDMARKS)
|
|
259
|
+
self.assertEqual(d["landmarks"][0], {"x": round((20.2 * 16) / 0.5, 1), "y": round((10.3 * 16 - 160) / 0.5, 1)})
|
|
260
|
+
self.assertLess(d["landmarks"][0]["x"], d["landmarks"][1]["x"])
|
|
261
|
+
|
|
262
|
+
def test_score_uses_both_tensors(self):
|
|
263
|
+
cols = grid_cols(8, 640)
|
|
264
|
+
# cls alone high, obj low → sqrt(0.9*0.1)=0.3 < 0.5: dropped.
|
|
265
|
+
raw = _outputs(self.np, live={8: (cols + 1, 0.9, 0.1, [0.5, 0.5, 1.0, 1.0], [0.0] * 10)})
|
|
266
|
+
out = postprocess_yunet(raw, {"confidence": 0.5}, 640, 640, 1.0, (0, 0))
|
|
267
|
+
self.assertEqual(out["detections"], [])
|
|
268
|
+
|
|
269
|
+
def test_prior_with_low_cls_but_high_obj_still_passes(self):
|
|
270
|
+
# sqrt(0.45 * 0.95) = 0.654 >= 0.5 although cls alone is under it: a
|
|
271
|
+
# prefilter on ONE tensor would drop a real face here.
|
|
272
|
+
cols = grid_cols(32, 640)
|
|
273
|
+
raw = _outputs(self.np, live={32: (cols + 3, 0.45, 0.95, [0.5, 0.5, 0.0, 0.0], [0.0] * 10)})
|
|
274
|
+
out = postprocess_yunet(raw, {"confidence": 0.5}, 640, 640, 1.0, (0, 0))
|
|
275
|
+
self.assertEqual(len(out["detections"]), 1)
|
|
276
|
+
self.assertAlmostEqual(out["detections"][0]["score"], 0.6538, places=3)
|
|
277
|
+
|
|
278
|
+
def test_cap_applies_inside_postprocess(self):
|
|
279
|
+
# TOP_K + 50 disjoint live priors on the stride-8 grid: all pass the
|
|
280
|
+
# score gate, none overlap, so only the cap can remove any.
|
|
281
|
+
n = grid_cols(8, 640) ** 2
|
|
282
|
+
raw = _outputs(self.np)
|
|
283
|
+
live = list(range(0, n, 2))[: TOP_K + 50]
|
|
284
|
+
raw["cls_8"][0, live, 0] = 0.9
|
|
285
|
+
raw["obj_8"][0, live, 0] = 0.9
|
|
286
|
+
raw["bbox_8"][0, live] = [0.5, 0.5, -1.0, -1.0] # ~3 px boxes, disjoint
|
|
287
|
+
out = postprocess_yunet(raw, {"confidence": 0.5}, 640, 640, 1.0, (0, 0))
|
|
288
|
+
self.assertEqual(len(out["detections"]), TOP_K)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
if __name__ == "__main__":
|
|
292
|
+
unittest.main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"_provenance":"Raw output tensors of google-coral/test_data ssdlite_mobiledet_coco_qat_postprocess.tflite (sha256 32c486140391eb4dc43fca7113ad392be632dc5366687f2731f73d740678693f; the CPU build of the same QAT graph as ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite, whose four outputs have the identical names, shapes and dtypes), captured 2026-09-26 on ai-edge-litert 2.1.3 through inference_pool.py's edgetpu load/preprocess/predict path with a CPU interpreter, letterbox 320. Frames are COCO val2017 images; only the model's numeric outputs are stored here, never the pixels.","frames":{"coco_val2017_000000039769_two_cats":{"orig":[640,480],"scale":0.5,"pad":[0,40],"outputs":{"0":[[[0.15955263376235962,0.534464955329895,0.713003933429718,0.9716978073120117],[0.2043571174144745,0.02350570261478424,0.8648291826248169,0.5011452436447144],[0.10257476568222046,0.014032959938049316,0.9505413174629211,0.996590256690979],[0.22124464809894562,0.04488908499479294,0.3162550926208496,0.29261064529418945],[0.03658798336982727,0.012482762336730957,0.40508130192756653,0.987517237663269],[0.1555221676826477,0.6529091000556946,0.8028101325035095,1.006462574005127],[0.24686561524868011,0.5220372080802917,0.4193393588066101,0.5692116618156433],[0.2072891891002655,0.1583276093006134,0.3572945296764374,0.4583382308483124],[0.23659078776836395,0.5290685892105103,0.42224830389022827,0.5870484113693237],[0.5743775367736816,0.23019926249980927,0.6594175100326538,0.34779107570648193],[0.3052724301815033,0.24310186505317688,0.9099631309509277,0.9973288774490356],[0.11994627118110657,0.3792511224746704,0.5946398973464966,0.9894982576370239],[0.2084560990333557,0.2897113263607025,0.3498774766921997,0.4769533574581146],[0.048862308263778687,-0.024405688047409058,0.8030894994735718,0.6076090335845947],[0.47406071424484253,0.039728641510009766,0.8791598677635193,0.9857875108718872],[0.20506274700164795,0.006122678518295288,0.3345203399658203,0.26888036727905273],[0.21482816338539124,0.2670758366584778,0.4976709187030792,0.48709094524383545],[0.17930985987186432,0.5188078880310059,0.6031879782676697,0.87400221824646],[0.5569137930870056,0.8219212889671326,0.6033983826637268,0.91482013463974],[0.5594297051429749,0.06481415033340454,0.6947370171546936,0.3435206711292267],[0.2410658895969391,0.526638925075531,0.3487098515033722,0.5821121335029602],[0.24299399554729462,0.8754947781562805,0.3305767774581909,0.9966028332710266],[0.09360367059707642,-0.027666032314300537,0.4855625033378601,0.7005844712257385],[0.21883206069469452,0.37879708409309387,0.3296947479248047,0.46383705735206604],[0.2706087529659271,0.8736841082572937,0.34845462441444397,0.9984135031700134],[0.23773013055324554,0.5050985217094421,0.5164366364479065,0.5824022889137268],[0.8736730217933655,0.004488527774810791,1.0054889917373657,0.9902228713035583],[0.23501813411712646,0.1322900503873825,0.3002501130104065,0.2705683708190918],[0.2720530033111572,0.9462981820106506,0.35584938526153564,0.9963359236717224],[0.247519388794899,0.944722592830658,0.3231050968170166,0.9993845820426941],[0.38305434584617615,0.378726065158844,0.47873106598854065,0.49631792306900024],[0.5535222291946411,0.7801342010498047,0.7023705244064331,0.8831243515014648],[0.7894991040229797,0.03270852565765381,0.9892374873161316,0.9928076267242432],[0.20900268852710724,0.05372738838195801,0.29099857807159424,0.3962726294994354],[0.2068709284067154,0.006370965391397476,0.3372364044189453,0.0244777649641037],[0.23342448472976685,-0.01042163372039795,0.3790746331214905,0.2895890474319458],[0.22075217962265015,0.22743815183639526,0.8087112307548523,0.824122965335846],[0.5976130962371826,0.05392265319824219,0.9607176780700684,0.9731613397598267],[0.11443797498941422,0.7428056597709656,0.24389559030532837,0.9905272126197815],[0.22740966081619263,0.4848347008228302,0.4475909471511841,0.5901657938957214],[0.21618488430976868,0.5098341703414917,0.44631537795066833,0.6151652336120605],[0.8084112405776978,0.0015302002429962158,0.9273114204406738,0.9038747549057007],[-0.003454655408859253,0.01914122700691223,0.29720693826675415,0.9142001867294312],[0.23717385530471802,0.4077231287956238,0.6862777471542358,1.043309211730957],[0.40243661403656006,0.4213453233242035,0.46671468019485474,0.49919119477272034],[0.038508474826812744,0.13357895612716675,0.5688574910163879,0.814859926700592],[0.2079186886548996,0.4072537422180176,0.25239354372024536,0.45305848121643066],[0.18039143085479736,0.7189949750900269,0.346691370010376,1.0018376111984253],[0.17740964889526367,0.8574067950248718,0.3975909352302551,0.9967599511146545],[0.30818599462509155,0.000822313129901886,0.6126490831375122,0.1720949113368988],[0.06299805641174316,0.032074540853500366,0.2399788498878479,0.8108158111572266],[0.13213692605495453,0.5332436561584473,0.41890597343444824,0.9667563438415527],[0.3001849353313446,0.8360094428062439,0.5748157501220703,1.0098237991333008],[0.46447721123695374,0.7584561109542847,0.6980230808258057,0.8998774290084839],[0.22825893759727478,0.5397037863731384,0.7288434505462646,0.8317379355430603],[0.21569259464740753,0.8997492790222168,0.2564050257205963,0.9679288864135742],[0.25803816318511963,0.4330609440803528,0.3111131191253662,0.4992610216140747],[0.22732794284820557,0.3999912738800049,0.4643397331237793,0.5687592029571533],[0.23802617192268372,0.5667713284492493,0.42239078879356384,0.8623947501182556],[0.34699746966362,0.2612840533256531,0.488418847322464,0.5053830146789551],[0.5587438941001892,0.22770456969738007,0.6354513764381409,0.34881260991096497],[0.5473014116287231,0.6006264090538025,0.6144839525222778,0.6729443669319153],[0.5691072940826416,0.5631829500198364,0.6691073179244995,0.6897634267807007],[0.197118878364563,0.5749090313911438,0.5393403768539429,1.0084216594696045],[0.2407025694847107,0.4220343232154846,0.41971439123153687,0.648799479007721],[0.43011459708213806,0.42714160680770874,0.49631467461586,0.4729463458061218],[0.5331307053565979,0.7939615845680237,0.61097651720047,0.8855019211769104],[0.2184237539768219,0.7220790386199951,0.6754136085510254,1.0115272998809814],[0.23764437437057495,0.8479610085487366,0.8712865710258484,0.9984578490257263],[0.12035168707370758,0.8447889089584351,0.35048216581344604,0.9947942495346069],[0.21286840736865997,0.9534194469451904,0.26364877820014954,0.9906877279281616],[0.23123027384281158,0.04802142083644867,0.31140387058258057,0.12702254951000214],[0.5154188871383667,0.7573367357254028,0.6169029474258423,0.8059217929840088],[0.697390079498291,0.05803816393017769,0.8673416376113892,0.11111311614513397],[0.22868293523788452,0.3173567056655884,0.32868295907974243,0.45768725872039795],[0.24360230565071106,0.01714465767145157,0.5480654239654541,0.2307719588279724],[0.2897666394710541,0.5481002926826477,0.4560665786266327,0.839400589466095],[0.37094348669052124,0.7636645436286926,0.6415581107139587,0.9050858616828918],[0.46699267625808716,0.5482616424560547,0.6871740221977234,0.7246556282043457],[0.27251920104026794,0.03307163715362549,0.827480673789978,0.32943978905677795],[0.03661632537841797,0.2884189486503601,0.7459261417388916,1.0189385414123535],[0.05953405797481537,0.8303914070129395,0.2862992286682129,0.9966913461685181],[0.17441785335540771,0.2090485841035843,0.27974894642829895,0.5367846488952637],[0.18664157390594482,0.5720193386077881,0.35294151306152344,0.919648289680481],[0.19373293220996857,-0.003133825957775116,0.531268835067749,0.1656341254711151],[0.27887362241744995,0.9335945248603821,0.658628523349762,0.9955716729164124],[0.32571566104888916,0.0015931539237499237,0.6534517407417297,0.07340744137763977],[0.4985097050666809,0.058443158864974976,0.6723241209983826,0.32905781269073486],[0.5864514112472534,0.15539874136447906,0.6753339767456055,0.29165494441986084],[0.5612818598747253,0.6305587291717529,0.6754595637321472,0.719441294670105],[0.513027012348175,0.5583153367042542,0.7057222723960876,0.8958513140678406],[0.004697104915976524,-0.005696093663573265,0.040883369743824005,0.03212530165910721],[0.20103901624679565,0.33512550592422485,0.35104435682296753,0.5940406918525696],[0.20186400413513184,0.4540380537509918,0.37313663959503174,0.716795802116394],[0.22820225358009338,0.3030018210411072,0.40721407532691956,0.5136640667915344],[0.43144962191581726,0.2230268269777298,0.6185503005981445,0.4936414361000061],[0.48286062479019165,0.7618263959884644,0.6039686799049377,0.8043785095214844],[0.5385960936546326,0.6290205121040344,0.6187697052955627,0.7091941237449646],[0.4680514335632324,0.7121118903160095,0.7194494009017944,0.871222198009491],[0.6098172664642334,-0.0005137994885444641,0.7401827573776245,0.04462110251188278]]],"1":[[16.0,16.0,64.0,74.0,62.0,16.0,74.0,16.0,43.0,73.0,64.0,16.0,16.0,62.0,64.0,83.0,16.0,16.0,84.0,16.0,74.0,74.0,62.0,16.0,74.0,74.0,64.0,83.0,74.0,74.0,74.0,84.0,64.0,74.0,83.0,83.0,16.0,64.0,0.0,74.0,74.0,64.0,62.0,16.0,74.0,62.0,74.0,31.0,74.0,83.0,62.0,16.0,0.0,58.0,16.0,74.0,74.0,16.0,16.0,16.0,73.0,76.0,76.0,16.0,74.0,74.0,84.0,16.0,64.0,0.0,74.0,83.0,84.0,74.0,16.0,83.0,16.0,83.0,39.0,16.0,62.0,0.0,16.0,16.0,83.0,0.0,83.0,16.0,74.0,84.0,30.0,0.0,16.0,74.0,16.0,73.0,76.0,84.0,31.0,83.0]],"2":[[0.76953125,0.76953125,0.5234375,0.39453125,0.30078125,0.24609375,0.23828125,0.19140625,0.18359375,0.17578125,0.1640625,0.15234375,0.14453125,0.14453125,0.140625,0.1328125,0.1328125,0.125,0.11328125,0.11328125,0.109375,0.109375,0.109375,0.10546875,0.10546875,0.10546875,0.10546875,0.1015625,0.1015625,0.09765625,0.09765625,0.09765625,0.09765625,0.08984375,0.08984375,0.08984375,0.0859375,0.0859375,0.08203125,0.08203125,0.08203125,0.08203125,0.08203125,0.08203125,0.078125,0.078125,0.07421875,0.07421875,0.07421875,0.07421875,0.07421875,0.07421875,0.0703125,0.0703125,0.0703125,0.06640625,0.06640625,0.06640625,0.06640625,0.06640625,0.06640625,0.06640625,0.06640625,0.06640625,0.0625,0.0625,0.0625,0.0625,0.0625,0.05859375,0.05859375,0.05859375,0.05859375,0.05859375,0.0546875,0.0546875,0.0546875,0.0546875,0.0546875,0.0546875,0.0546875,0.05078125,0.05078125,0.05078125,0.05078125,0.05078125,0.05078125,0.05078125,0.05078125,0.05078125,0.05078125,0.046875,0.046875,0.046875,0.046875,0.046875,0.046875,0.046875,0.046875,0.046875]],"3":[100.0]}},"coco_val2017_000000252219_street":{"orig":[640,428],"scale":0.5,"pad":[0,53],"outputs":{"0":[[[0.4162486791610718,0.024550773203372955,0.7795857191085815,0.1983652412891388],[0.4350929260253906,0.5026833415031433,0.7440744638442993,0.6160659193992615],[0.4274504780769348,0.8110100030899048,0.760050356388092,0.9848244190216064],[0.5311018228530884,0.3237488269805908,0.7480632066726685,0.5054173469543457],[0.6483170986175537,0.6389470100402832,0.7928438186645508,0.7346237897872925],[0.5338170528411865,0.3173767626285553,0.6368073225021362,0.3987402021884918],[0.4912804067134857,0.9553788900375366,0.6911295056343079,1.0005137920379639],[0.30877313017845154,0.8685252070426941,0.41176334023475647,1.0109384059906006],[0.28655675053596497,0.8688049912452698,0.5342783331871033,1.0041122436523438],[0.5341765880584717,0.30358779430389404,0.6143501996994019,0.3802952766418457],[0.24573861062526703,0.535965085029602,0.3307785391807556,0.599303126335144],[0.4633682072162628,0.9736822247505188,0.6661832332611084,0.9969421029090881],[0.5260692834854126,0.38162389397621155,0.6489746570587158,0.48016151785850525],[0.7162842154502869,0.5424903035163879,0.7484474778175354,0.6030901074409485],[0.3242916762828827,0.9250457882881165,0.40213754773139954,0.9984369874000549],[0.5646662712097168,0.32681071758270264,0.6617629528045654,0.4069843292236328],[0.43745797872543335,0.8556292653083801,0.506649374961853,0.8928975462913513],[0.5453707575798035,0.9623616933822632,0.6898974776268005,0.9964772462844849],[0.3656116724014282,0.9378393292427063,0.6885550022125244,0.9913268685340881],[0.6316292881965637,0.35618144273757935,0.7316293120384216,0.47908681631088257],[0.299285888671875,0.9094834923744202,0.39638257026672363,1.0051602125167847],[0.5499159693717957,0.13722729682922363,0.5882986187934875,0.20540684461593628],[0.5260947346687317,0.3105463683605194,0.6739063858985901,0.4977883994579315],[0.5227016806602478,0.9099226593971252,0.6287714838981628,0.9592286944389343],[0.5940675735473633,0.3829779624938965,0.6574056148529053,0.46554887294769287],[0.4623275697231293,0.8369593620300293,0.4979846775531769,0.8631285429000854],[0.5491682291030884,0.47726282477378845,0.62587571144104,0.5139861106872559],[0.2056179791688919,0.4550957679748535,0.2488015741109848,0.5022701621055603],[0.21111512184143066,0.5228007435798645,0.24625077843666077,0.552243173122406],[0.5356869101524353,0.49689340591430664,0.6069472432136536,0.5310089588165283],[0.5498236417770386,0.4632295072078705,0.7031227350234985,0.511814534664154],[0.46009230613708496,0.7904802560806274,0.7690738439559937,0.9199378490447998],[0.5481249690055847,0.4862275719642639,0.7283921837806702,0.5313624739646912],[0.5189509391784668,0.02130730450153351,0.7701113224029541,0.44223350286483765],[0.6050348877906799,0.9128004312515259,0.6596968770027161,0.966663122177124],[0.4300398528575897,0.8400573134422302,0.4641554057598114,0.8629769682884216],[0.3168220520019531,0.9083377122879028,0.6748456954956055,0.9979112148284912],[0.5227682590484619,0.8477926850318909,0.6257585287094116,0.913992702960968],[0.7170714735984802,0.3222942352294922,0.7432406544685364,0.360115647315979],[0.49940651655197144,0.5581434369087219,0.5609056353569031,0.6006955504417419],[0.48628464341163635,0.40381699800491333,0.730383574962616,0.5295159816741943],[0.5414602756500244,0.5834677815437317,0.6011738777160645,0.6092543005943298],[0.7611274719238281,0.0054911356419324875,0.8006578683853149,0.03861616551876068],[0.5396264791488647,0.10698680579662323,0.760373592376709,0.5930132269859314],[0.17262639105319977,0.8333241939544678,0.4315415620803833,1.0020921230316162],[0.48002371191978455,0.8558622598648071,0.5729225873947144,0.9073963165283203],[0.5417873859405518,0.05324568599462509,0.6141053438186646,0.11295924335718155],[0.5150630474090576,0.8205909729003906,0.6275711059570312,0.8500334024429321],[0.5987178683280945,0.4551270604133606,0.7453894019126892,0.5037120580673218],[0.23898977041244507,0.5919873118400574,0.33752739429473877,0.6653785109519958],[0.2905657887458801,0.5573469996452332,0.3343902826309204,0.6073847413063049],[0.41652873158454895,0.8505421876907349,0.4688275158405304,0.8861992359161377],[0.4871012568473816,0.10838092118501663,0.5746840834617615,0.1622435450553894],[0.5822117328643799,0.850226879119873,0.6545296907424927,0.914504885673523],[0.6951959729194641,0.34702178835868835,0.737125813961029,0.4853001534938812],[0.5352706909179688,0.10564260184764862,0.6014707088470459,0.17087455093860626],[0.6321781277656555,0.9626111388206482,0.6927779316902161,0.9962278008460999],[0.7240806818008423,0.4945259094238281,0.7494900226593018,0.5657862424850464],[0.7278625965118408,0.6477597951889038,0.7912006378173828,0.699293851852417],[0.44048047065734863,0.9741995334625244,0.5787588357925415,0.9905321598052979],[0.5262652635574341,0.526103138923645,0.5561445951461792,0.550413966178894],[0.5032247304916382,0.8301358819007874,0.5570874214172363,0.8566934466362],[0.5438975691795349,0.31178784370422363,0.688424289226532,0.37798792123794556],[0.741370677947998,0.0036882534623146057,0.7968438863754272,0.1787216067314148],[0.26776328682899475,0.8388197422027588,0.4030705988407135,1.0153470039367676],[0.4859636723995209,0.8949870467185974,0.5802412629127502,0.956486165523529],[0.6024523973464966,0.49162277579307556,0.7387086153030396,0.5348063707351685],[0.5774096250534058,0.6351754665374756,0.797590970993042,0.762739896774292],[0.2301507294178009,0.5263333320617676,0.3286883533000946,0.5708081722259521],[0.2292805016040802,0.6279017925262451,0.3369244635105133,0.6867420673370361],[0.5606799125671387,0.027291707694530487,0.5996322631835938,0.05806448310613632],[0.5880016088485718,0.5785675644874573,0.6782033443450928,0.6112081408500671],[0.718255341053009,0.01484508067369461,0.7508959174156189,0.13957443833351135],[0.7315396666526794,0.8035227060317993,0.7597091794013977,0.837638258934021],[0.2944031357765198,0.809653639793396,0.453513503074646,0.9861807823181152],[0.6220482587814331,0.33179566264152527,0.7205859422683716,0.4476678669452667],[0.42942866683006287,0.7300208806991577,0.7904558181762695,1.0069555044174194],[0.44813793897628784,0.14109531044960022,0.46520859003067017,0.15604627132415771],[0.5543093681335449,0.5982905626296997,0.6266273260116577,0.6222459077835083],[0.4242232143878937,0.5523462295532227,0.7424439191818237,0.6393190622329712],[0.5669523477554321,0.5963963866233826,0.6992526054382324,0.6285596489906311],[0.21041908860206604,0.4460771381855011,0.34374770522117615,0.683089017868042],[0.5402801036834717,0.27855896949768066,0.7388873100280762,0.4006084203720093],[0.5964339971542358,0.8200300335884094,0.6535660028457642,0.8447017073631287],[0.2541125416755676,0.4373975098133087,0.3120924234390259,0.5199684500694275],[0.5770773887634277,0.04363440349698067,0.6699762344360352,0.12993639707565308],[0.7549723386764526,0.26059067249298096,0.7994471788406372,0.3144533038139343],[0.39701393246650696,0.9599695801734924,0.46035197377204895,0.9885571599006653],[0.5154039859771729,0.14906154572963715,0.5684789419174194,0.20535801351070404],[0.5914602875709534,0.08590969443321228,0.6511738896369934,0.16261713206768036],[0.6257311701774597,0.5529274940490723,0.7242688536643982,0.602965235710144],[0.7689149975776672,0.748873770236969,0.7928703427314758,0.7981798052787781],[0.212331622838974,0.4396534562110901,0.24356108903884888,0.46190768480300903],[0.5010358691215515,0.03401685133576393,0.5607494711875916,0.046919818967580795],[0.5261155366897583,0.33853837847709656,0.5592405796051025,0.390837162733078],[0.43047335743904114,0.00413740798830986,0.7486940622329712,0.07919672131538391],[0.5710752606391907,0.0036823004484176636,0.6921833157539368,0.06252261996269226],[0.6423197388648987,0.6038827300071716,0.8014300465583801,0.7752847075462341],[0.5016130208969116,0.3145033121109009,0.7622942924499512,0.5751845240592957],[0.497750461101532,0.720516562461853,0.561088502407074,0.7368491888046265]]],"1":[[0.0,0.0,0.0,61.0,32.0,26.0,0.0,27.0,27.0,26.0,0.0,0.0,26.0,40.0,27.0,26.0,0.0,30.0,0.0,61.0,27.0,30.0,26.0,30.0,26.0,0.0,26.0,0.0,0.0,30.0,61.0,0.0,61.0,14.0,30.0,0.0,0.0,30.0,36.0,30.0,0.0,30.0,40.0,14.0,27.0,26.0,30.0,30.0,61.0,71.0,0.0,0.0,26.0,30.0,61.0,30.0,32.0,40.0,40.0,0.0,30.0,30.0,26.0,40.0,27.0,30.0,61.0,32.0,0.0,61.0,0.0,61.0,40.0,36.0,27.0,61.0,0.0,76.0,30.0,0.0,61.0,71.0,0.0,30.0,83.0,30.0,36.0,27.0,42.0,30.0,40.0,40.0,0.0,0.0,26.0,0.0,14.0,32.0,14.0,0.0]],"2":[[0.76953125,0.76953125,0.76953125,0.55859375,0.46484375,0.453125,0.453125,0.39453125,0.375,0.36328125,0.3515625,0.34375,0.33203125,0.33203125,0.3203125,0.30078125,0.28125,0.28125,0.2734375,0.2734375,0.24609375,0.24609375,0.24609375,0.24609375,0.24609375,0.23828125,0.23828125,0.23046875,0.23046875,0.22265625,0.22265625,0.22265625,0.21484375,0.21484375,0.20703125,0.19921875,0.19921875,0.19921875,0.19921875,0.19140625,0.19140625,0.19140625,0.19140625,0.19140625,0.18359375,0.18359375,0.18359375,0.18359375,0.18359375,0.17578125,0.17578125,0.17578125,0.17578125,0.17578125,0.16796875,0.1640625,0.1640625,0.1640625,0.1640625,0.15625,0.15625,0.15625,0.15625,0.15625,0.15234375,0.15234375,0.15234375,0.15234375,0.14453125,0.14453125,0.14453125,0.14453125,0.14453125,0.14453125,0.140625,0.140625,0.140625,0.1328125,0.1328125,0.1328125,0.1328125,0.12890625,0.12890625,0.12890625,0.125,0.125,0.125,0.1171875,0.1171875,0.1171875,0.1171875,0.1171875,0.11328125,0.11328125,0.11328125,0.11328125,0.11328125,0.11328125,0.11328125,0.109375]],"3":[100.0]}}}}
|