想做什麼
想做一個牌桌上的攝影機可以即時辨識牌面 然後算出翻牌前的勝率給你看 主要是給剛開始玩德州撲克的人用的 幫助建立對手牌強度的直覺
牌面辨識
用 YOLOv5 做撲克牌辨識 攝影機接在 ESP32-S3 上面架在牌桌上方 訓練資料用的是 Roboflow 的 Poker Cards 資料集 52 張牌各種角度跟光線都有
做下來幾個心得:
- 資料增強比資料量重要 Roboflow 內建的增強效果就蠻好的
- 小物件真的很難偵測 被手或籌碼擋住的牌要花很多時間在標註上
- ESP32 上面跑推論每一毫秒都有差 最後用 YOLOv5s 小型版
勝率計算
偵測到手牌之後跑蒙地卡羅模擬 算兩個玩家的翻牌前勝率
做法:
- 偵測到的牌當固定輸入
- 剩下的牌隨機發 跑幾千次
- 每次用德州撲克的牌型排名判定
- 勝率 = 贏的次數 / 總次數
引擎用 C/C++ 寫 加上多行程處理之後 200,000 次模擬從 6.87 秒降到 1.90 秒 快了 72%
前端
Flask 做了一個即時的網頁 顯示偵測到的牌 玩家位置 勝率 WebSocket 自動更新 牌面一變畫面就跟著動 跑在 port 38999
架構
攝影機 (ESP32-S3) → YOLOv5 偵測 → 牌面狀態
↓
蒙地卡羅引擎 (C/C++, 多行程) → 勝率
↓
Flask Server → 即時網頁 UI
整套用 Docker 包起來(ghcr.io/jotpalch/aiot-texas-hold-em-smart-table)
心得
語言比例大概是 64% C 21% C++ 10% Python 5% HTML 效能吃重的部分(偵測跟模擬)用 C/C++ Python 跟 Flask 負責串起來跟顯示
做完最大的感覺是真實世界的 ML 大部分時間不是在調模型 是在搞管線 攝影機要穩 推論要快 多行程要對 整套在實際打牌的時候不能掛掉
原始碼在 GitHub