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
|
|
@ -5,8 +5,11 @@ that share nothing with the LOPIA catalog. Every accept here is a false accept
|
|||
by construction, which is what makes the set useful: the image6 shelf can only
|
||||
measure false accepts on the products it happens to contain.
|
||||
|
||||
The stored eval.json predates the open-set gate, so it is re-run rather than
|
||||
trusted.
|
||||
Measured the way the server measures: a 1280-long-side frame detected at
|
||||
`LiveSettings.conf`. The sources are 4032-4512 px photos, and detecting them at
|
||||
full resolution and at the default `detect_conf` instead measures a
|
||||
configuration the phone never runs, which is how a threshold change reads as a
|
||||
pass on evidence the product does not produce.
|
||||
|
||||
.venv/bin/python code/eval_distractors.py --stock stock-lopia-clean \
|
||||
data/external-shelves/wikimedia-commons
|
||||
|
|
@ -28,7 +31,13 @@ if current_dir not in sys.path:
|
|||
|
||||
import cv2 # noqa: E402
|
||||
|
||||
from eval_identity import LOCAL_ACCEPT, LocalLaneAdapter # noqa: E402
|
||||
from eval_identity import ( # noqa: E402
|
||||
LIVE_LONG_SIDE,
|
||||
LOCAL_ACCEPT,
|
||||
LocalLaneAdapter,
|
||||
at_live_resolution,
|
||||
)
|
||||
from identity_lanes import TEXT_MIN_SHARED # noqa: E402
|
||||
|
||||
|
||||
def main(argv: List[str] | None = None) -> int:
|
||||
|
|
@ -40,9 +49,11 @@ def main(argv: List[str] | None = None) -> int:
|
|||
args = parser.parse_args(argv)
|
||||
|
||||
from engine import build_default_engine, EngineSettings
|
||||
from live import LiveSettings
|
||||
|
||||
engine = build_default_engine(EngineSettings(stock_dir=args.stock))
|
||||
lane = LocalLaneAdapter(args.stock)
|
||||
conf = LiveSettings().conf
|
||||
for directory in args.directories:
|
||||
manifest_path = os.path.join(directory, "manifest.json")
|
||||
try:
|
||||
|
|
@ -65,14 +76,15 @@ def main(argv: List[str] | None = None) -> int:
|
|||
if image is None:
|
||||
continue
|
||||
started = time.perf_counter()
|
||||
detections = engine.detect(image)
|
||||
frame = at_live_resolution(image)
|
||||
detections = engine.detect(frame, conf=conf)
|
||||
accepted = 0
|
||||
for detection in detections:
|
||||
box = detection.get("box") or detection.get("bbox")
|
||||
if not box:
|
||||
continue
|
||||
x1, y1, x2, y2 = [int(v) for v in box]
|
||||
crop = image[max(0, y1):y2, max(0, x1):x2]
|
||||
crop = frame[max(0, y1):y2, max(0, x1):x2]
|
||||
if crop.size == 0:
|
||||
continue
|
||||
decision = lane.decide(crop, lane.rank(crop), accept=LOCAL_ACCEPT,
|
||||
|
|
@ -93,6 +105,14 @@ def main(argv: List[str] | None = None) -> int:
|
|||
"dataset": os.path.basename(directory.rstrip("/")),
|
||||
"catalog": args.stock,
|
||||
"note": "Unrelated shelves: every accept is a false accept by construction.",
|
||||
# The configuration the numbers above were measured under, so the
|
||||
# stored evidence is checkable against the constants it claims.
|
||||
"config": {
|
||||
"frame_long_side": LIVE_LONG_SIDE,
|
||||
"detect_conf": conf,
|
||||
"local_accept": LOCAL_ACCEPT,
|
||||
"text_min_shared": TEXT_MIN_SHARED,
|
||||
},
|
||||
"images": len(rows),
|
||||
"detections": detections,
|
||||
"false_accepts": accepts,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue