Real-time playing card detection and recognition using classical computer vision techniques.
This project identifies both rank and suit from a live camera stream and extends into interactive card-based games such as Blackjack.
- 🎥 Real-time card detection via camera
- 🂠 Rank recognition (A, K, Q, J, 2–10)
- ♥ Suit recognition (spade, heart, diamond, club)
- 🧠 Pure OpenCV pipeline (no machine learning)
- 🧩 Modular architecture (detector, GUI, templates, games)
- 🎮 Early-stage game integration (Blackjack prototype)
PlayingCardsOpenCV/
├── main.py # Entry point (runs the application)
├── config.py # Global configuration & tuning parameters
│
├── templates/ # Template images used for matching
│ ├── rank/ # Card ranks (A, 2–10, J, Q, K)
│ └── suit/ # Card suits (club, diamond, heart, spade)
│
├── src/
│ ├── __init__.py
│ │
│ ├── app.py # Main GUI, navigation & camera integration
│ │
│ ├── detector.py # Card detection (OpenCV pipeline)
│ ├── roi_extractor.py # Extract rank & suit regions
│ ├── template_matcher.py # Template matching logic
│ ├── image_utils.py # Image preprocessing utilities
│ │
│ ├── core/ # Core card engine (game-independent)
│ │ ├── __init__.py
│ │ ├── card.py # Card model (rank, suit)
│ │ ├── deck.py # Deck logic (shuffle, draw)
│ │ └── poker_hand.py # Poker hand evaluation
│ │
│ ├── games/ # Game logic implementations
│ │ ├── blackjack.py
│ │ ├── five_card_draw.py
│ │ └── war.py
│ │
│ └── ui/ # Reusable UI components
│ ├── __init__.py
│ └── scrollable.py
│
├── snapshot_frame.jpg # Example output snapshot
├── README.md
└── .gitignore
The project is organized into four main layers:
-
Computer Vision Layer
- Detects cards and extracts rank/suit regions
-
Core Engine
- Defines cards, deck behavior, and hand evaluation logic
-
Game Layer
- Implements game rules (Blackjack, Poker, War)
-
UI Layer
- Handles user interface and interaction (Tkinter)
This modular structure makes it easy to extend the system with new games or improved detection methods.
All parameters are defined in:
config.py
Example:
CAMERA_INDEX = 0 THRESH_BINARY_VALUE = 150 USE_CANNY = False
RANK_CONFIDENCE_THRESHOLD = 0.6 SUIT_CONFIDENCE_THRESHOLD = 0.6
MIN_CARD_AREA = 12000 POLY_EPSILON_RATIO = 0.02
These control detection accuracy, filtering, and performance.
- Card Detection
- Edge detection (Canny)
- Contour extraction
- Quadrilateral filtering
- Perspective Transform
- Warp card into top-down view
- Region Extraction
- Extract top-left corner
- Separate:
- Rank region
- Suit region
- Preprocessing
- Grayscale
- Thresholding
- Contour isolation
- Template Matching
- Resize to fixed size
- Compare with templates
- Output similarity score
Unlike single-character ranks, "10" consists of two symbols.
The system handles this by:
- Detecting multiple contours
- Merging them into a single bounding box
- Matching against a combined template
All templates must be:
- JPG format
- High contrast (black on white)
- Same font as cards
- Centered
- Clean (minimal noise)
Tested on:
- 📱 Redmi Note 11 (Pydroid 3 Premium)
The app now includes a Game Selection Menu:
- Scanner Only
- Blackjack
- Poker (planned)
- War (planned)
Blackjack (Current State)
- Card detection integrated
- Manual assignment:
- Add card to Player
- Add card to Dealer
- Score calculation
- Win / Lose detection
- Basic suggestions (Hit / Stand)
- Detects only one card at a time
- Sensitive to lighting conditions
- Template-dependent accuracy
- Rank detection is harder than suit detection
Camera not working
Could not open camera
➡ Try:
CAMERA_INDEX = 1
Wrong detections
- Adjust threshold:
THRESH_BINARY_VALUE = 140–180
- Improve templates (VERY important)
- Multi-card detection
- Better rotation handling
- Automatic game flow (no manual input)
- Performance optimization (mobile)
- Optional ML-based classifier
Alexandros Giannakis GitHub: https://github.com/AlexandrosGiann/PlayingCardsOpenCV