You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: live decode starved by runaway QR fallbacks on cluttered crops
Real-capture repro (anyd-capture-1 (6): Suntory bottle, EAN-13 4901777300521):
the locator boxed the barcode perfectly and tracked it for 376 cycles, yet
nothing ever decoded. The crop worker processed crops in order and scan_all
spent 4.5 s NATIVE (10 s+ in wasm) on a 336x672 kanji ingredient panel before
reaching the barcode crop, which decodes in 1.3 ms. Every dispatch starved the
same way, so locks either never appeared or expired between reads.
The hog was the QR fourth-corner refinement sweep: its grid radius grows with
the (falsely estimated, often huge) module size of clutter triples, and it
full-samples + RS-decodes every placement for up to four bogus hypotheses.
Library:
- refine_fourth_corner now walks placements nearest-first from the affine
prediction (a genuine curved capture decodes within a step or two) under a
global work budget counted in sampled modules, and caps the sweep radius;
the busy text crop drops 4486 ms -> 208 ms native (~600 ms wasm) with every
curved/real-world QR test still passing
- new decode1d wasm export: 1D-only scan for crops the locator already
classified as linear — 7 ms in wasm on the repro EAN crop
Demo:
- crop worker routes by candidate family (linear -> decode1d, else full
decode) and runs linear crops first
- results stream per crop instead of per batch, so a decoded barcode shows
up immediately rather than after the slowest clutter crop
- worker onerror clears the busy flag — a dead worker no longer silently
disables decoding for the rest of the session
- cropdecode diagnostic example (crop + per-stage timing + raw luma dump)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
0 commit comments