User reports all 34 cells classified as 미인식 with score 0.00 even
when the grid was correctly cropped. Multiple compounding issues:
1. _is_empty required mean<60 (dark) AND std<14. HDR/bright captures
produce pinkish empty slots with mean ~150-180, so even empty cells
fell through to template matching. Drop the mean check; uniformity
alone (std<18 grayscale, std<22 per-channel) is the real signal.
2. Score 0.00 across the board strongly suggests templates list was
empty (only path that returns exactly 0.0). Track per-bucket load
counts (slabs_ok/fail, artifacts_ok/fail) and surface them in the
GUI status bar so a CDN failure is immediately visible. Currently
no signal at all on download failure.
3. min_score 0.55 was tuned against simulator-clean renders. Real game
captures have decorative cell borders, stack-count badges in
corners, HDR shader effects. Lower to 0.35 and inset cell crops by
16% on each side before matching to skip the decorative frame.
4. Add 디버그 저장 button + dump_debug() that saves screenshot.png,
bbox_crop.png, cells/<row>-<col>.png, and report.txt with top-3
matches per cell to %LOCALAPPDATA%/sephiria_inv/debug/<timestamp>/.
Lets us iterate on tuning from real captures without round-tripping
raw screenshots through chat each time.
- window_capture.py: enumerate top-level windows (pygetwindow) and
capture a specific one via PrintWindow PW_RENDERFULLCONTENT (works
on non-focused windows). Linux falls back to mss region grab.
- recognizer.py: replace MAE matcher with NCC over numpy vectors.
Each rotatable slab generates 4 templates (0/90/180/270). Adds 248
artifact templates and an empty-cell heuristic (low mean/std-dev).
Cells below confidence floor are tagged "unknown" — likely merged
"?" boxes.
- gui.py: new ScreenshotFrame with [게임 창 선택] button → window
picker dialog → bbox crop → recognize → editable preview grid with
per-cell CellEditor that handles slab / artifact / merged(?) / empty.
Merged cells let user pick which two slabs got combined + a level.
- artifacts.py + bundled _artifacts.json (248 entries from
WhiteDog1004/sephiria) for matching and rendering.
- renderer.py: factored CDN fetch into _fetch_image; added
fetch_artifact_image().
- requirements.txt: + numpy, pygetwindow (Win), pywin32 (Win).
- docker-build-cmd.sh: upgrade PyInstaller to 5.x inside cdrx
container so numpy DLL manifest reads work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>