重啟撲克機器人之路:從OCR到程式碼重構的一天

更新於 發佈於 閱讀時間約 8 分鐘

今天繼續在撲克桌況辨識上奮鬥,決定使用OCR來處理文字辨識的部分。相較於OpenHoldem時期需要一個個擷取數字Template進行比對的方式,OCR確實帶來了效率的提升,短短半小時就完成了基礎的辨識功能。

raw-image

然而道路總是充滿意想不到的挑戰。在測試不同撲克軟體時,發現介面上的英文字會干擾數字辨識的準確度。原本想說把它們納入辨識區域應該不會有什麼問題,反正在辨識後再取用數字部分即可,結果卻造成了意外的困擾。尋求AI建議後,得到的解決方案反而越來越複雜,就為了處理這麼一個看似簡單的問題。最後我選擇了更務實的做法,直接略過英文字只擷取數字的Region。這個決定讓我再次體會到,在實作中,找到一個「夠用」的解決方案,有時比追求完美的解法更重要。

raw-image

下午的時候,開始著手整理Project的程式碼結構。過去總是習慣把所有程式碼都寫在一個Jupyter Notebook裡,結構鬆散且難以維護。今年我決定提早開始規劃程式碼架構,希望能避免之前的慘痛教訓。在AI的指導下,開始把不同功能的程式碼分門別類地放入適當的資料夾中。

poker_detector/
├── src/
│ ├── __init__.py
│ ├── detector/
│ │ ├── __init__.py
│ │ ├── card_detector.py
│ │ ├── text_detector.py
│ │ └── template_matcher.py
│ ├── models/
│ │ ├── __init__.py
│ │ └── card.py
│ ├── utils/
│ │ ├── __init__.py
│ │ ├── image_preprocessing.py
│ │ └── device_connector.py
│ └── config/
│ ├── __init__.py
│ └── regions.py
├── main.py
└── requirements.txt

這個重構過程中遇到了Python模組匯入的老問題 - 從不同資料夾匯入類別或函式總是會出錯。有趣的是,這個問題我之前就遇過好幾次,每次解決後卻總是忘記解法,下次又得重新摸索。這次我決定把解決方案好好記錄下來:必須在每個資料夾建立__init__.py檔案,並在主程式中正確設定路徑。這個看似簡單的問題卻花了我半小時才解決,但至少這次的經驗提醒了我確實記錄的重要性。

import sys
import os

# Get the directory of the current file and append the project root to sys.path

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
#text_detector.py

import cv2

import pytesseract

from src.utils.image_preprocessing import ImagePreprocessor

import numpy as np



class TextDetector:

@staticmethod

def extract_number(text: str) -> float:

numbers = ''.join(c for c in text if c.isdigit() or c == '.')

try:

return float(numbers)

except ValueError:

return 0.0



def detect_text(self, roi: np.ndarray, is_dark_background: bool = False) -> str:

if is_dark_background:

processed = ImagePreprocessor.preprocess_for_ocr_dark_background(roi)

else:

processed = ImagePreprocessor.preprocess_for_ocr(roi)

return pytesseract.image_to_string(processed, config='--psm 7 digits')



def detect_value(self, roi: np.ndarray, is_dark_background: bool = False) -> float:

text = self.detect_text(roi, is_dark_background)

return self.extract_number(text)
#image_preprocessing.py
import cv2

import numpy as np



class ImagePreprocessor:

@staticmethod

def preprocess_for_template(image: np.ndarray) -> np.ndarray:

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

binary = cv2.adaptiveThreshold(

gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,

cv2.THRESH_BINARY_INV, 11, 2

)

kernel = np.ones((3,3), np.uint8)

binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel)

return binary



@staticmethod

def preprocess_for_ocr(roi: np.ndarray) -> np.ndarray:

gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)

_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)

scaled = cv2.resize(binary, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)

denoised = cv2.fastNlMeansDenoising(scaled)

return denoised
avatar-img
1會員
8內容數
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
傑劉的沙龍 的其他內容
記錄了在開發撲克機器人時,在選擇使用傳統的template matching方法還是新的機器學習技術間的掙扎,最終決定採用雙軌並行的開發策略。
這篇文章簡要分享我在 Coursera 完成 Google Prompt Essentials 的學習心得,並解釋如何運用「Task、Context、Reference、Evaluate、Iterate」五大步驟來優化與 AI 的互動。
一位程式小白開發撲克機器人的過程,從選擇Python語言、使用ADB和OpenCV處理手機截圖和畫面識別,到探討更穩健的撲克牌辨識方法(例如,使用fast.ai學習過的圖像辨識),以及策略核心開發的挑戰。文章也提到開發流程的規劃,以及選擇Python語言以降低入門門檻的考量。
記錄了在開發撲克機器人時,在選擇使用傳統的template matching方法還是新的機器學習技術間的掙扎,最終決定採用雙軌並行的開發策略。
這篇文章簡要分享我在 Coursera 完成 Google Prompt Essentials 的學習心得,並解釋如何運用「Task、Context、Reference、Evaluate、Iterate」五大步驟來優化與 AI 的互動。
一位程式小白開發撲克機器人的過程,從選擇Python語言、使用ADB和OpenCV處理手機截圖和畫面識別,到探討更穩健的撲克牌辨識方法(例如,使用fast.ai學習過的圖像辨識),以及策略核心開發的挑戰。文章也提到開發流程的規劃,以及選擇Python語言以降低入門門檻的考量。
你可能也想看
Google News 追蹤
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本篇介紹單人遊戲的核心架構與邏輯,涵蓋發牌、抽牌、出牌及遊戲結算等重要步驟。文章也詳細介紹了使用 socket.io 建立連線的過程,並說明如何利用 React Hooks 管理遊戲狀態,提及後端伺服器如何處理玩家加入房間的事件,並簡要介紹了房間資訊的管理,此文將分為多篇進一步介紹遊戲事件部分。
我一直都很喜歡需要動腦的遊戲,因此最近深陷於德州撲克的魅力中無法自拔 今天,為了消磨陪伴男友唸書的時間,我從圖書館拿了一本標題為《人生賽局》的書 作者為一位哈佛畢業的心理學家,為了了解人們在自我控制及機率、運氣相關事件發生時的心態,因此給自己一年的時間,向頂尖撲克大師學習撲克
Thumbnail
原版的官方規則導入記分機制,但因為計算過於繁複,所以一般遊玩時較少採用。本變體規則旨在還原原規則的策略性,並保留平常的遊玩樂趣。 1. 配件準備 4枚不同顏色的棋子(紅、藍、黃、綠),以及一張標記0~15的場地。 2. 記分方式 一開始所有棋子都在0的位置。每一局結束時,贏家以外的所有人拿出
學習如何提升子效,不浪費每一手棋的價值,透過精妙的佈局,不僅拓展你的棋界視野,更能在對局中一展長才⚫️⚪️
現今進入了高手人手一機的 「AI時代」一 每步棋都有最佳解+勝率參考 卻仍然要強調基本功 為什麼呢?
Thumbnail
Ae 小技巧:卡牌旋轉 動態後記系列會記錄一些我在製作中的記錄,可能是分解動畫、小技巧、發想、腳本......等等。 每篇都是小短篇,就是補充用的小筆記,沒有前後順序,可跳著閱讀。
前言 上文提及訓練記憶術時常使用撲克牌做為訓練內容,在訓練時首先必須先將每一張的撲克牌轉換成一個圖像,然後以一次翻開兩張撲克牌的方式翻開,並迅速將這兩張圖像聯結在一起,接著將之放置在一個事先規畫好的固定的位置上,如此一一將兩張圖像聯結在一起,並將之放置在不同的位置上,在回憶時,順著位置走一圈就
Thumbnail
曼哈頓 規則https://punchboardgame.pixnet.net/blog/post/463394453 這是一款老桌遊,規則和計分方式相對簡單,但整體的遊玩體驗是很好的。 我所遊玩的是新版的擴充版本,增加了額外的計分規則,也會讓每一次的策略都有所變化,最後呈現出完全不同的結果。
成績刷新的通知立即出現在了所有正在操作象棋軟件的玩家的屏幕上,以滾條的方式播放着。 雖然這款軟件是專門供玩家與人機對抗的,但卻並非真正意義上的單機遊戲。 因爲有排行榜的原因,所以但凡某榜單的第一名被替換,都會進行全服公告。 這全服公告一出,所有在玩玩家都不淡定了。 “什麼!5分10秒,這傢伙
Thumbnail
現代社會跟以前不同了,人人都有一支手機,只要打開就可以獲得各種資訊。過去想要辦卡或是開戶就要跑一趟銀行,然而如今科技快速發展之下,金融App無聲無息地進到你生活中。但同樣的,每一家銀行都有自己的App時,我們又該如何選擇呢?(本文係由國泰世華銀行邀約) 今天我會用不同角度帶大家看這款國泰世華CUB
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本篇介紹單人遊戲的核心架構與邏輯,涵蓋發牌、抽牌、出牌及遊戲結算等重要步驟。文章也詳細介紹了使用 socket.io 建立連線的過程,並說明如何利用 React Hooks 管理遊戲狀態,提及後端伺服器如何處理玩家加入房間的事件,並簡要介紹了房間資訊的管理,此文將分為多篇進一步介紹遊戲事件部分。
我一直都很喜歡需要動腦的遊戲,因此最近深陷於德州撲克的魅力中無法自拔 今天,為了消磨陪伴男友唸書的時間,我從圖書館拿了一本標題為《人生賽局》的書 作者為一位哈佛畢業的心理學家,為了了解人們在自我控制及機率、運氣相關事件發生時的心態,因此給自己一年的時間,向頂尖撲克大師學習撲克
Thumbnail
原版的官方規則導入記分機制,但因為計算過於繁複,所以一般遊玩時較少採用。本變體規則旨在還原原規則的策略性,並保留平常的遊玩樂趣。 1. 配件準備 4枚不同顏色的棋子(紅、藍、黃、綠),以及一張標記0~15的場地。 2. 記分方式 一開始所有棋子都在0的位置。每一局結束時,贏家以外的所有人拿出
學習如何提升子效,不浪費每一手棋的價值,透過精妙的佈局,不僅拓展你的棋界視野,更能在對局中一展長才⚫️⚪️
現今進入了高手人手一機的 「AI時代」一 每步棋都有最佳解+勝率參考 卻仍然要強調基本功 為什麼呢?
Thumbnail
Ae 小技巧:卡牌旋轉 動態後記系列會記錄一些我在製作中的記錄,可能是分解動畫、小技巧、發想、腳本......等等。 每篇都是小短篇,就是補充用的小筆記,沒有前後順序,可跳著閱讀。
前言 上文提及訓練記憶術時常使用撲克牌做為訓練內容,在訓練時首先必須先將每一張的撲克牌轉換成一個圖像,然後以一次翻開兩張撲克牌的方式翻開,並迅速將這兩張圖像聯結在一起,接著將之放置在一個事先規畫好的固定的位置上,如此一一將兩張圖像聯結在一起,並將之放置在不同的位置上,在回憶時,順著位置走一圈就
Thumbnail
曼哈頓 規則https://punchboardgame.pixnet.net/blog/post/463394453 這是一款老桌遊,規則和計分方式相對簡單,但整體的遊玩體驗是很好的。 我所遊玩的是新版的擴充版本,增加了額外的計分規則,也會讓每一次的策略都有所變化,最後呈現出完全不同的結果。
成績刷新的通知立即出現在了所有正在操作象棋軟件的玩家的屏幕上,以滾條的方式播放着。 雖然這款軟件是專門供玩家與人機對抗的,但卻並非真正意義上的單機遊戲。 因爲有排行榜的原因,所以但凡某榜單的第一名被替換,都會進行全服公告。 這全服公告一出,所有在玩玩家都不淡定了。 “什麼!5分10秒,這傢伙