fix(recognition): calibrate the accept lines against unrelated shelves
Every threshold was fitted on image6, where each crop is a facing of a product the shelf holds, so the set could not price a false accept. Measured on 4580 crops from 64 unrelated Wikimedia shelf photos at the shipped configuration: LOCAL_ACCEPT 2.0 -> 4.0 false accepts 60 (1.31%) -> 3 (0.07%) TEXT_MIN_SHARED 2 -> 4 the two-bigram reads that named sku_l12 via おい/いし On image6 that is 44 shown / 42 correct at full resolution - 95.5% precision, 65.6% coverage - the highest-coverage cell of the joint sweep that passes both G2 (>= 95%) and G3 (<= 1%). At live resolution 56% end-to-end at 97%. The text lane's evidence floor gates its answer only: zeroing the row's score would reorder the ranking and make the margin gate compare a different pair than the one it was measured on. code/sweep_accept_lines.py sweeps both axes jointly through the shipped DecisionPolicy; the earlier table swept one axis while pinning the other, so its baseline rows were not the old line.
This commit is contained in:
parent
4ce41ecb17
commit
5094b5f6ca
12 changed files with 815 additions and 195 deletions
|
|
@ -18,6 +18,7 @@ import cv2 # noqa: E402
|
|||
import numpy as np # noqa: E402
|
||||
|
||||
from eval_live import ( # noqa: E402
|
||||
IDENTITY_BACKENDS,
|
||||
EvalInputError,
|
||||
identity_level,
|
||||
labelled_top1,
|
||||
|
|
@ -296,5 +297,42 @@ class IdentityContractTests(unittest.TestCase):
|
|||
{"identity_backend": "matcher"},
|
||||
])
|
||||
|
||||
def test_van_is_accepted_by_the_cli_and_by_a_recording_that_names_it(self):
|
||||
self.assertIn("van", IDENTITY_BACKENDS)
|
||||
self.assertEqual(resolve_identity("van", None), "van")
|
||||
self.assertEqual(recorded_identity([{"identity_backend": "van"}]), "van")
|
||||
root = tempfile.mkdtemp()
|
||||
self.addCleanup(shutil.rmtree, root, ignore_errors=True)
|
||||
stock = os.path.join(root, "stock")
|
||||
os.makedirs(stock)
|
||||
recording = os.path.join(root, "session")
|
||||
os.makedirs(recording)
|
||||
write_jpeg(os.path.join(recording, "000000.jpg"), np.zeros((8, 8, 3), dtype=np.uint8))
|
||||
line = {"frame": 1, "path": "000000.jpg", "tracks": [], "identity_backend": "van"}
|
||||
with open(os.path.join(recording, "index.jsonl"), "w", encoding="utf-8") as handle:
|
||||
handle.write(json.dumps(line) + "\n")
|
||||
for extra in ([], ["--identity", "van"]):
|
||||
report_path = os.path.join(root, "eval_live.json")
|
||||
completed = subprocess.run(
|
||||
[
|
||||
sys.executable,
|
||||
os.path.join(current_dir, "eval_live.py"),
|
||||
recording,
|
||||
"--stock-dir",
|
||||
stock,
|
||||
"--json",
|
||||
report_path,
|
||||
*extra,
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
self.assertEqual(completed.returncode, 0, completed.stdout + completed.stderr)
|
||||
with open(report_path, "r", encoding="utf-8") as handle:
|
||||
report = json.load(handle)
|
||||
self.assertEqual(report["identity"]["backend"], "van")
|
||||
self.assertEqual(report["fingerprints"]["model"]["identity"], "van")
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue