[Python] Template matching for Cart Counting

Discussão em 'Python' iniciado por Stack, Janeiro 18, 2025.

  1. Stack

    Stack Membro Participativo

    I really do not know anything about python, i just made this codes with chatgpt and my iq effect. I want to ask, how to make faster cart counter app? I made this for Pishti game. It works, counts but sometimes passing. How to improve my code or which template matching i need to use.

    My templates same with the cards i want to be counted. Any advise better than TM_CCOEFF_NORMED

    import cv2
    import numpy as np
    import tkinter as tk
    import threading
    import time
    import pyautogui
    from datetime import datetime, timedelta

    # Kart şablonlarını yükle
    card_templates = {
    '2_sinek': cv2.imread('kartlar/2s.png', cv2.IMREAD_GRAYSCALE),
    '2_kupa': cv2.imread('kartlar/2k.png', cv2.IMREAD_GRAYSCALE),
    '2_maça': cv2.imread('kartlar/2m.png', cv2.IMREAD_GRAYSCALE),
    '2_karo': cv2.imread('kartlar/2q.png', cv2.IMREAD_GRAYSCALE),
    '3_sinek': cv2.imread('kartlar/3s.png', cv2.IMREAD_GRAYSCALE),
    '3_kupa': cv2.imread('kartlar/3k.png', cv2.IMREAD_GRAYSCALE),
    '3_maça': cv2.imread('kartlar/3m.png', cv2.IMREAD_GRAYSCALE),
    ...
    }

    card_counts = {card.split('_')[0]: 0 for card in card_templates.keys()}


    card_last_seen = {card: None for card in card_templates.keys()} # Son görülen zaman

    # HERE
    def capture_screen(region=None):
    if region:
    # Belirli bir bölgenin ekran görüntüsünü al
    screen = np.array(pyautogui.screenshot(region=region))
    else:
    # Tüm ekranın görüntüsünü al
    screen = np.array(pyautogui.screenshot())

    screen = cv2.cvtColor(screen, cv2.COLOR_RGB2BGR) # RGB -> BGR
    return screen
    # Kartları tespit et
    def detect_cards(screen):
    gray_screen = cv2.cvtColor(screen, cv2.COLOR_BGR2GRAY)
    detected_cards = {}

    for card, template in card_templates.items():
    result = cv2.matchTemplate(gray_screen, template, cv2.TM_CCOEFF_NORMED)
    threshold = 0.98 # Eşleşme oranı
    locations = np.where(result >= threshold)

    for pt in zip(*locations[::-1]):
    if card not in detected_cards:
    detected_cards[card] = []
    detected_cards[card].append(pt)

    return detected_cards


    def update_display(stop_event):
    global root, labels


    root = tk.Tk()
    root.title("Kart Sayımı")

    # Kart sayıları için etiketler
    labels = {}
    for i, card in enumerate(card_counts.keys()):
    label = tk.Label(root, text=f"{card}: {card_counts[card]}", font=('Helvetica', 14))
    label.grid(row=i, column=0)
    labels[card] = label

    # "Yenile" butonunu oluştur
    def reset_counts():
    reset_gui()

    reset_button = tk.Button(root, text="Yenile", command=reset_counts)
    reset_button.grid(row=len(card_counts), column=0)


    def update():
    if not stop_event.is_set():
    sorted_cards = sorted(card_counts.items(), key=lambda x: (x[1] != 3, x[1] != 4, x[0]))
    for idx, (card, count) in enumerate(sorted_cards):
    color = 'red' if count == 3 else 'green' if count == 4 else 'black'
    labels[card].config(text=f"{card}: {count}", fg=color)
    labels[card].grid(row=idx, column=0)
    root.after(500, update) # 0.5 saniye sonra tekrar çalıştır

    update()
    root.mainloop()


    def track_cards(stop_event):
    global card_last_seen # card_last_seen değişkenini global olarak kullan
    last_reset_time = datetime.now()

    while not stop_event.is_set():
    region = (400, 0, 1000, 1000)
    screen = capture_screen(region=region)

    detected_cards = detect_cards(screen)
    # Sayıları güncelle
    for card, locations in detected_cards.items():
    card_number = card.split('_')[0]

    # Eğer kart 100 saniye içinde sayılmadıysa
    if card_last_seen[card] is None or datetime.now() - card_last_seen[card] > timedelta(seconds=100):
    # Kart sayılabilir, sayımı artır
    card_counts[card_number] += 1
    card_last_seen[card] = datetime.now() # Kartı saydık, son görülen zamanı güncelle

    # Kart sayımlarını anlık olarak güncelle
    print(f"Detected cards: {detected_cards}")
    print(f"Card counts: {card_counts}")

    # 0.1 saniye sonra tekrar çalıştır
    time.sleep(0.2)


    def reset_gui():
    global card_counts, card_last_seen


    card_counts = {card.split('_')[0]: 0 for card in card_templates.keys()}
    card_last_seen = {card: None for card in card_templates.keys()}

    for card in labels:
    labels[card].config(text=f"{card}: 0", fg='black')

    stop_event = threading.Event()

    def start_gui_thread():
    thread_gui = threading.Thread(target=update_display, args=(stop_event,))
    thread_gui.daemon = True
    thread_gui.start()

    def start_tracking():
    track_cards(stop_event)

    start_gui_thread() # GUI'yi başlat
    start_tracking() # Kartları takip etmeye başla

    Continue reading...

Compartilhe esta Página