Building an AI-Powered Card Counter with TensorFlow
Card counting in Blackjack has long been a strategy used by skilled players to gain an advantage over the house. Traditionally, this requires keeping a mental tally of high and low cards dealt. With advancements in artificial intelligence and computer vision, we can now automate this process. This guide will walk you through building an AI-powered card counter using TensorFlow, which can recognize cards from a live video stream and count them using the Hi-Lo system.
Overview
We'll cover the following steps:
- Data Collection
- Data Preprocessing
- Building and Training a Convolutional Neural Network (CNN)
- Integrating the CNN with a Live Video Stream
- Counting Cards in Real-Time
1. Data Collection
First, we need a dataset of playing card images. This dataset should include multiple images of each card (2 through Ace) from various decks and angles to ensure our model is robust. Label these images according to their ranks.
Collecting Images
- Search for publicly available playing card datasets or manually take photos of cards.
- Ensure diversity in lighting, backgrounds, and angles to make the model more adaptable.
Organizing Data
- Create directories for each card rank (e.g.,
2
,3
,4
, ...,10
,J
,Q
,K
,A
). - Place corresponding images into these directories.
2. Data Preprocessing
Next, we'll preprocess our images to ensure they are suitable for training a neural network.
Resizing and Normalizing
- Resize all images to a consistent size (e.g., 64x64 pixels).
- Normalize pixel values to a range of 0 to 1.
Splitting Data
- Divide your dataset into training, validation, and test sets (e.g., 70% training, 20% validation, 10% test).
Preprocessing Code
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. Building and Training the CNN
We will now define, compile, and train a Convolutional Neural Network (CNN) to recognize the cards.
Defining the Model
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'])
Training the Model
model.fit(train_data, epochs=25, validation_data=val_data)
Evaluating the Model
loss, accuracy = model.evaluate(test_data)
print(f'Test Accuracy: {accuracy}')
4. Integrating with a Live Video Stream
Now, let's integrate our trained model with a live video stream to recognize cards in real-time.
Capturing Video Frames
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. Counting Cards in Real-Time
We can now integrate the card recognition with our card counting function to keep a running tally of the count in Blackjack.
Card Counting Function
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
Updating the Card Count in Real-Time
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()
Conclusion
By following these steps, you can build a sophisticated AI-powered card counter using TensorFlow. This project demonstrates the power of deep learning and computer vision in automating complex tasks like card counting in Blackjack. As with any AI model, the performance can be further improved with more data, better preprocessing, and more sophisticated model architectures.