""" Opt-in integration test against the real model and the real catalog. Skipped unless DORAYAKI_REAL_MODEL=1, because it loads the YOLO weights and classifies a full shelf. It defends the end-to-end claim: the server detects the whole shelf, accepts a meaningful share of the products, keeps a label stable while the camera pans, and never names a SKU for a weak match. cd recognization/code DORAYAKI_REAL_MODEL=1 YOLO_OFFLINE=1 ../.venv/bin/python -m unittest test_real_model -v """ from __future__ import annotations import math import os import sys import unittest current_dir = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(current_dir) if os.path.exists(os.path.join(project_root, "stock")): os.chdir(project_root) if current_dir not in sys.path: sys.path.insert(0, current_dir) import cv2 # noqa: E402 from engine import EngineSettings, build_default_engine # noqa: E402 from live import LiveSession, LiveSettings # noqa: E402 ENABLED = os.environ.get("DORAYAKI_REAL_MODEL") == "1" # Measured baseline on image.jpg (2026-09-24): 170 detections, 105 recognized. BASELINE_DETECTIONS = 170 BASELINE_RECOGNIZED = 105 @unittest.skipUnless(ENABLED, "set DORAYAKI_REAL_MODEL=1 to run against the real model") class RealModelTests(unittest.TestCase): @classmethod def setUpClass(cls): cls.engine = build_default_engine(EngineSettings(device="cpu")) cls.engine.warm_up() @classmethod def tearDownClass(cls): cls.engine.shutdown() def test_recognize_whole_shelf(self): with open("image.jpg", "rb") as handle: payload = handle.read() image = self.engine.decode_image(payload) result = self.engine.recognize(image, classify=True) summary = result["summary"] self.assertGreaterEqual( summary["in_view"], int(BASELINE_DETECTIONS * 0.95), "detection must not regress below the measured baseline", ) self.assertGreaterEqual( summary["recognized"], int(BASELINE_RECOGNIZED * 0.9), "recognition must not regress below the measured baseline", ) # every named SKU must exist in the catalog catalog = {product["sku_id"] for product in self.engine.catalog()} for detection in result["detections"]: identity = detection["identity"] if identity["state"] == "recognized": self.assertIn(identity["sku_id"], catalog) else: self.assertIsNone(identity["sku_id"], "only an accepted match may name a SKU") def test_pan_keeps_labels_stable_and_advances_them(self): image = cv2.imread("image.jpg") height, width = image.shape[:2] frame_w, frame_h = 1280, 720 session = LiveSession("real", self.engine, settings=LiveSettings(method="hybrid")) session.refresh_catalog() labels: dict = {} relabels: dict = {} restarts: dict = {} unexplained = [] recognized_frames = 0 frames = 16 for index in range(frames): phase = index / (frames - 1) x = int((width - frame_w) * (0.5 - 0.5 * math.cos(2 * math.pi * phase))) y = max(0, (height - frame_h) // 2) window = image[y:y + frame_h, x:x + frame_w] ok, buffer = cv2.imencode(".jpg", window, [cv2.IMWRITE_JPEG_QUALITY, 75]) session.submit_frame(index, buffer.tobytes()) pending = session.take_pending(timeout=5.0) self.assertIsNotNone(pending) result = session.process_frame(*pending) import time time.sleep(0.4) # let classification land, as a live client's next frame would if result["summary"]["recognized"]: recognized_frames += 1 for track in result["tracks"]: identity = track["identity"] if identity["state"] != "recognized": continue track_id = track["track_id"] sku = identity["sku_id"] if restarts.get(track_id, 0) < track["restarts"]: labels.pop(track_id, None) if track_id in labels and labels[track_id] != sku: if track["relabels"] <= relabels.get(track_id, 0): unexplained.append((track_id, labels[track_id], sku)) labels[track_id] = sku relabels[track_id] = track["relabels"] restarts[track_id] = track["restarts"] self.assertGreater(recognized_frames, frames // 2, "labels should appear on most frames") self.assertGreater(len(labels), 0, "the pan should label products") self.assertEqual(unexplained, [], "a label must never change without re-verification") if __name__ == "__main__": unittest.main()