diff --git a/.claude/memory/project_hardware.md b/.claude/memory/project_hardware.md index 45b52ab..024569e 100644 --- a/.claude/memory/project_hardware.md +++ b/.claude/memory/project_hardware.md @@ -1,30 +1,23 @@ --- name: project-hardware description: Железо и настройки камеры для проекта -metadata: - node_type: memory +metadata: type: project - originSessionId: 3ee145c7-aca2-4844-98fa-84c57114d04a --- **Камера:** Logitech StreamCam → /dev/video2 (индекс 2). /dev/video0 — UVC Camera (другая). **Монитор:** 2×2560×1440 (HDMI-0 и DP-0). GGPoker на одном мониторе. -**Оптимальные настройки камеры** (автоматически подобраны 2026-06-17, сохранены в settings.json): -- focus=60 (ручной, autofocus=0) -- sharpness=192 -- exposure=500 (ручная, auto_exposure=0) -- resolution_idx=1 (1280×720) +**Настройки камеры:** Все на автоматике. settings.json содержит только `{"resolution_idx": 2}`. +Камера работает в 1920×1080 без ручного фокуса/экспозиции. -**Координаты GGPoker окна в webcam-кадре 1280×720:** -- Таблица стола: x=15:760, y=55:685 -- Борд-карты: y1=220, y2=370, x1=330, x2=640 -- Левая карта героя: y=438:478, x=472:530 -- Правая карта героя: y=438:478, x=530:585 +**Калибровка зон:** calibration.json — координаты в 1920×1080 пространстве. +Создаётся через `python3 calibrate.py` — перетаскивать рамки мышью. +Зоны: board_card_1-5 (зелёные), hero_card_1-2 (синие), player_0-7 (фиолетовые, для дилера). -**Проблема карт героя:** нижняя часть экрана частично выходит за кадр камеры — нужно опустить камеру чуть ниже. +**Qt шрифт fix:** Liberation Sans fonts в .venv/lib/python3.12/site-packages/cv2/qt/fonts/ -**Why:** Координаты зависят от положения камеры. При смещении — пересчитывать. +**Why:** Координаты зависят от положения камеры. При смещении — перекалибровать. -**How to apply:** Перед работой с координатами — сначала сделать снапшот и проверить актуальность. +**How to apply:** Если карты не распознаются — проверить актуальность calibration.json снапшотом. diff --git a/.claude/memory/project_overview.md b/.claude/memory/project_overview.md index 0283cbb..08d0a54 100644 --- a/.claude/memory/project_overview.md +++ b/.claude/memory/project_overview.md @@ -1,23 +1,35 @@ --- name: project-overview description: Общий обзор проекта — покер-анализатор для GGPoker через вебкамеру -metadata: - node_type: memory +metadata: type: project - originSessionId: 3ee145c7-aca2-4844-98fa-84c57114d04a --- Проект — покер-анализатор: вебкамера снимает монитор с GGPoker, Python распознаёт карты и считает equity. **Файлы:** -- `main.py` — просмотр камеры с настройками (trackbars), сохранение в settings.json -- `analyzer.py` — основной пайплайн: webcam → OCR → Monte Carlo → совет -- `webcam_scraper.py` — адаптер для подключения webcam к dickreuter_poker скраперу -- `virtualbox/` — заглушка модуля (dickreuter импортирует virtualbox, он не нужен) -- `files/` — спрайт-лист карт (table_card.png + card.json), не совпадает со стилем GGPoker -- `settings.json` — настройки камеры (автоматически подобраны) -- `tmp/` — все временные файлы, снапшоты +- `main.py` — просмотр webcam (чистое окно WINDOW_GUI_NORMAL, закрытие крестиком/ESC) +- `analyzer.py` — основной анализатор: 2 окна (Webcam с рамками зон + Info с текстом) +- `calibrate.py` — ручная калибровка зон мышью (перетаскивать рамки, S=сохранить) +- `calibration.json` — координаты зон 1920×1080: board_card_1-5, hero_card_1-2, player_0-7 +- `settings.json` — только resolution_idx=2 (камера на автоматике, без ручных настроек) +- `templates/` — rank_2..rank_A.png (13), suit_c/d/h/s.png (4), 2c..As.png (52 full-card) +- `files/` — clubs/diamants/hards/spades.png (GGPoker стиль), D.png (дилер), numbers_ranks.png +- `virtualbox/` — заглушка модуля для dickreuter_poker +- `tmp/` — временные файлы (чистить после работы) + +**Распознавание карт:** +- Ранг: OCR через Tesseract на большой цифре в нижней части зоны +- Масть: shape-matching по шаблонам suit_*.png из numbers_ranks.png, fallback на HSV цвет +- Шаблоны создаются venv python (system python пишет файлы недоступные venv!) +- Всегда создавать шаблоны через: `/home/isaevea/python/pp/.venv/bin/python` + +**Статус (2026-06-17):** +- Борд карты: распознаются хорошо (K♥ Q♦ 9♥ J♣ и т.д.) +- Hero карты: распознаются если видны (10♦ 9♦) +- Дилерская кнопка: template matching через D.png +- Monte Carlo equity: работает через dickreuter montecarlo_numpy2 **Why:** Пользователь анализирует покерные видео/игры в реальном времени. -**How to apply:** При любой работе с проектом — знать эту структуру. tmp/ для всех временных файлов. +**How to apply:** tmp/ для всех временных файлов; шаблоны создавать через venv python. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de5c721 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +.idea/ +/.git + +**/files/**/* +!**/files/**/ +!**/files/**/.gitkeep + diff --git a/analyzer.py b/analyzer.py index 2f21516..771931a 100644 --- a/analyzer.py +++ b/analyzer.py @@ -554,7 +554,19 @@ def main(): cv2.imshow(WIN_INFO, draw_info_panel(state)) - cv2.imshow(WIN_CAM, cv2.resize(frame, (960, 540))) + display = cv2.resize(frame, (960, 540)) + sx, sy = 960/1920, 540/1080 + for key, v in calib.items(): + if 'board' in key: col = (0, 200, 0) + elif 'hero' in key: col = (0, 140, 255) + elif 'player' in key:col = (180, 0, 180) + else: continue + x1,y1 = int(v['x1']*sx), int(v['y1']*sy) + x2,y2 = int(v['x2']*sx), int(v['y2']*sy) + cv2.rectangle(display, (x1,y1), (x2,y2), col, 1) + cv2.putText(display, key.split('_')[-1], (x1+2,y1+11), + FONT, 0.30, col, 1) + cv2.imshow(WIN_CAM, display) k = cv2.waitKey(1) & 0xFF if k in (27, ord('q')): break