重啟撲克機器人之路 -4 :當簡單反而是答案

重啟撲克機器人之路 -4 :當簡單反而是答案

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

今天在開發撲克牌辨識系統時,遇到了一個有趣的轉折。原本信心滿滿地以為數字辨識已經相當穩定,可以進入下一階段的開發,結果實際測試時卻發現數字7經常被誤判,有時候stack size的數值還會莫名其妙變成"00"。

面對這個問題,我第一時間選擇向AI尋求解方。它們提供了各種看似專業的建議:調整OCR配置、使用白名單限制數字、加強圖片預處理...甚至還建議同時使用三種不同的辨識方法來取平均值。每個建議聽起來都很有道理,AI們也都以相當確切的口吻表達,這反而讓我陷入一個誤區 - 不斷嘗試新的解決方案,卻忽略了最基本的問題排查。

經過一整天的嘗試與挫折,我終於意識到應該先寫個簡單的debug程序,看看圖片在預處理前後的變化。諷刺的是,我發現原始圖片的辨識效果反而最好,所有的預處理反而讓圖片變得更模糊。這個發現讓我哭笑不得,卻也帶來重要的啟示:有時候最簡單的方法可能才是最好的解答,而過度依賴AI的建議反而會讓我們忽略了最基本的問題排查流程。

def detect_text(self, roi: np.ndarray) -> str:

#processed = ImagePreprocessor.preprocess_for_ocr(roi)

return pytesseract.image_to_string(roi, config='--psm 7 digits')
# My godish...

另外今天也在Git上遇到了一些困擾,不小心進入了detached head狀態,折騰了好一陣子才解決。這讓我意識到雖然平時只使用基本的Git功能,但確實需要花些時間深入學習這個工具。然而在Project開發正緊鑼密鼓的當下,要在「專注開發」和「學習新知」之間找到平衡確實不容易。

這一天的經歷讓我重新思考了對AI的依賴程度。它們的建議固然看似精確且充滿自信,但有時這種自信反而會誤導我們。相較之下,與真人討論時的不確定性反而更能激發我思考和探索。即便在AI時代,保持獨立思考和基本的問題排查能力依然至關重要。

拯救我的debug:

import os

import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import cv2

import numpy as np

from src.utils.device_connector import DeviceConnector

from src.utils.image_preprocessing import ImagePreprocessor

from src.detector.text_detector import TextDetector

from src.config.regions import STACK_REGIONS, BET_REGIONS, POT_REGION


class OCRDebugger:

def __init__(self):

self.device = DeviceConnector.connect_device()

self.text_detector = TextDetector()


def capture_screen(self):

screenshot_data = self.device.screencap()

nparr = np.frombuffer(screenshot_data, np.uint8)

return cv2.imdecode(nparr, cv2.IMREAD_COLOR)


def debug_region(self, screen, region, name):

# Extract region

roi = screen[region['y1']:region['y2'], region['x1']:region['x2']]

# Save original ROI

cv2.imwrite(f"debug_images/{name}_original.png", roi)

# Get preprocessed image

preprocessed = ImagePreprocessor.preprocess_for_ocr(roi)

cv2.imwrite(f"debug_images/{name}_preprocessed.png", preprocessed)

# Get OCR result

text = self.text_detector.detect_text(roi)

value = self.text_detector.extract_number(text)

return {

'text': text,

'value': value,

'roi': roi,

'preprocessed': preprocessed

}


def run_debug(self):

# Create debug_images directory if it doesn't exist

os.makedirs("debug_images", exist_ok=True)

# Capture screen

screen = self.capture_screen()

cv2.imwrite("debug_images/full_screen.png", screen)

# Debug each region

regions_to_check = {

'hero_stack': STACK_REGIONS['hero'],

'villain_stack': STACK_REGIONS['villain'],

'hero_bet': BET_REGIONS['hero'],

'villain_bet': BET_REGIONS['villain'],

'pot': POT_REGION

}

results = {}

for name, region in regions_to_check.items():

results[name] = self.debug_region(screen, region, name)

# Print results

print("\n=== OCR Debug Results ===")

for name, result in results.items():

print(f"\n{name.upper()}:")

print(f"Raw OCR text: '{result['text']}'")

print(f"Extracted value: {result['value']}")

print("\nDebug images have been saved to the 'debug_images' directory")

print("Check the images to see the exact regions being captured and their preprocessing")



def main():

debugger = OCRDebugger()

debugger.run_debug()



if __name__ == "__main__":

main()


avatar-img
傑劉的沙龍
3會員
18內容數
留言
avatar-img
留言分享你的想法!
傑劉的沙龍 的其他內容
記錄了對撲克數據庫程式碼的深入理解,以及如何通過精確的查詢獲得準確的分析結果。通過重新組織action type的分類,讓後續的數據分析變得更加高效。這個數據庫將是撲克機器人專案的重要組成部分,用於建立更精確的對手模型。
記錄了在建構撲克數據庫過程中遇到的挑戰和收穫。探討了自建系統與現成工具的差異,以及如何確保數據準確性。同時反思了精確表達查詢需求的重要性,以及自建系統潛在的長期價值。
記錄了在撲克機器人開發中從機器學習模型轉向建立自定義數據庫的過程,以及這個策略轉變背後的思考。通過分析真實玩家的行動分布,希望能訓練出更有效的撲克機器人。
記錄了對撲克數據庫程式碼的深入理解,以及如何通過精確的查詢獲得準確的分析結果。通過重新組織action type的分類,讓後續的數據分析變得更加高效。這個數據庫將是撲克機器人專案的重要組成部分,用於建立更精確的對手模型。
記錄了在建構撲克數據庫過程中遇到的挑戰和收穫。探討了自建系統與現成工具的差異,以及如何確保數據準確性。同時反思了精確表達查詢需求的重要性,以及自建系統潛在的長期價值。
記錄了在撲克機器人開發中從機器學習模型轉向建立自定義數據庫的過程,以及這個策略轉變背後的思考。通過分析真實玩家的行動分布,希望能訓練出更有效的撲克機器人。