使用 TensorFlow 构建 AI 驱动的算牌器

社区文章 发布于 2024 年 6 月 27 日

image/jpeg

二十一点中的算牌一直以来都是熟练玩家用来对抗庄家的一种策略。传统上,这需要玩家在脑海中记录已发高牌和低牌的总数。随着人工智能和计算机视觉的进步,我们现在可以自动化这个过程。本指南将引导您使用 TensorFlow 构建一个 AI 驱动的算牌器,它可以从实时视频流中识别牌并使用 Hi-Lo 系统进行算牌。

概述

我们将涵盖以下步骤

  1. 数据收集
  2. 数据预处理
  3. 构建和训练卷积神经网络 (CNN)
  4. 将 CNN 与实时视频流集成
  5. 实时算牌

1. 数据收集

首先,我们需要一个扑克牌图像数据集。该数据集应包含每张牌(2 到 A)的多张图像,来自不同的牌组和角度,以确保我们的模型具有鲁棒性。根据其牌面值标记这些图像。

收集图像

  • 搜索公开可用的扑克牌数据集或手动拍摄扑克牌照片。
  • 确保光照、背景和角度的多样性,以使模型更具适应性。

组织数据

  • 为每个牌面值创建目录(例如,`2`、`3`、`4`、...、`10`、`J`、`Q`、`K`、`A`)。
  • 将相应的图像放入这些目录中。

2. 数据预处理

接下来,我们将对图像进行预处理,以确保它们适合训练神经网络。

调整大小和归一化

  • 将所有图像调整到一致的大小(例如,64x64 像素)。
  • 将像素值归一化到 0 到 1 的范围。

数据分割

  • 将数据集划分为训练集、验证集和测试集(例如,70% 训练集、20% 验证集、10% 测试集)。

预处理代码

import tensorflow as tf
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# Define directories
train_dir = 'dataset/train'
val_dir = 'dataset/validation'
test_dir = 'dataset/test'

# Image data generators
train_datagen = ImageDataGenerator(rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True)
val_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

# Load datasets
train_data = train_datagen.flow_from_directory(train_dir, target_size=(64, 64), batch_size=32, class_mode='sparse')
val_data = val_datagen.flow_from_directory(val_dir, target_size=(64, 64), batch_size=32, class_mode='sparse')
test_data = test_datagen.flow_from_directory(test_dir, target_size=(64, 64), batch_size=32, class_mode='sparse')

3. 构建和训练 CNN

我们现在将定义、编译和训练一个卷积神经网络 (CNN) 来识别牌。

定义模型

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense

model = Sequential([
    Conv2D(32, (3, 3), activation='relu', input_shape=(64, 64, 3)),
    MaxPooling2D(pool_size=(2, 2)),
    Conv2D(64, (3, 3), activation='relu'),
    MaxPooling2D(pool_size=(2, 2)),
    Flatten(),
    Dense(128, activation='relu'),
    Dense(13, activation='softmax')  # 13 classes for card ranks
])

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

训练模型

model.fit(train_data, epochs=25, validation_data=val_data)

评估模型

loss, accuracy = model.evaluate(test_data)
print(f'Test Accuracy: {accuracy}')

4. 与实时视频流集成

现在,让我们将训练好的模型与实时视频流集成,以实时识别扑克牌。

捕捉视频帧

import cv2

cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    if not ret:
        break

    # Preprocess the frame (resize and normalize)
    img = cv2.resize(frame, (64, 64))
    img = img / 255.0
    img = img.reshape(1, 64, 64, 3)

    # Predict the card
    prediction = model.predict(img)
    card_index = prediction.argmax()

    # Map index to card label
    card_labels = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K', 'A']
    card_label = card_labels[card_index]

    # Display the prediction on the frame
    cv2.putText(frame, card_label, (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2, cv2.LINE_AA)
    cv2.imshow('Card Classifier', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

5. 实时算牌

我们现在可以将牌识别与我们的算牌功能集成,以在二十一点中保持实时牌数总计。

算牌函数

def count_cards(cards):
    count = 0
    for card in cards:
        if card in ['2', '3', '4', '5', '6']:
            count += 1
        elif card in ['10', 'J', 'Q', 'K', 'A']:
            count -= 1
    return count

实时更新牌数

current_count = 0
recognized_cards = []

cap = cv2.VideoCapture(0)
while True:
    ret, frame = cap.read()
    if not ret:
        break

    img = cv2.resize(frame, (64, 64))
    img = img / 255.0
    img = img.reshape(1, 64, 64, 3)

    prediction = model.predict(img)
    card_index = prediction.argmax()
    card_label = card_labels[card_index]

    recognized_cards.append(card_label)
    current_count = count_cards(recognized_cards)

    cv2.putText(frame, f'Card: {card_label}', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2, cv2.LINE_AA)
    cv2.putText(frame, f'Count: {current_count}', (50, 100), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 0, 0), 2, cv2.LINE_AA)
    cv2.imshow('Card Classifier', frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

结论

通过遵循这些步骤,您可以使用 TensorFlow 构建一个复杂的 AI 驱动算牌器。该项目展示了深度学习和计算机视觉在自动化二十一点算牌等复杂任务方面的强大能力。与任何 AI 模型一样,通过更多数据、更好的预处理和更复杂的模型架构,可以进一步提高性能。

社区

注册登录 发表评论