首页 > 游戏动态

扑克排识別(扑克牌的识别)

2025-12-24 12:53:41

扑克牌识别概述

扑克牌识别是计算机视觉中的一个应用领域,主要用于自动识别扑克牌的花色和点数。

主要技术路线

1. 传统图像处理方法

python

import cv2

import numpy as np

def preprocess_card_image(image):

预处理扑克牌图像

# 转换为灰度图

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 高斯模糊去噪

blurred = cv2.GaussianBlur(gray, (5, 5), 0)

# 边缘检测

edges = cv2.Canny(blurred, 50, 150)

return edges

def detect_card_contour(edges):

检测扑克牌轮廓

contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for contour in contours:

# 近似多边形

epsilon = 0.02 * cv2.arcLength(contour, True)

approx = cv2.approxPolyDP(contour, epsilon, epsilon, True)

# 如果是四边形且面积足够大

if len(approx) == 4 and cv2.contourArea(contour) > 1000:

return approx

return None

2. 基于深度学习的识别方法

python

import torch

import torch.nn as nn

from torchvision import models, transforms

class PokerCardClassifier(nn.Module):

def __init__(self, num_classes=52):

super.__init__

# 使用预训练的ResNet作为基础网络

self.backbone = models.resnet18(pretrained=True)

self.backbone.fc = nn.Linear(self.backbone.fc.in_features, num_classes)

def forward(self, x):

return self.backbone(x)

# 数据预处理

transform = transforms.Compose([

transforms.Resize((224, 224)),

transforms.ToTensor,

transforms.Normalize(mean=[0.485, 0.456, 0.406],

红龙扑克app官方下载

std=[0.229, 0.224, 0.225])

])

完整的识别流程

python

class PokerCardRecognizer:

def __init__(self, model_path=None):

self.suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades']

self.ranks = ['Ace', '2', '3', '4', '5', '6', '7', '8',

'9', '10', 'Jack', 'Queen', 'King']

if model_path:

self.model = self.load_model(model_path)

else:

self.model = None

def extract_card_region(self, image):

提取扑克牌区域

# 1. 预处理

processed = preprocess_card_image(image)

# 2. 检测轮廓

contour = detect_card_contour(processed)

if contour is not None:

# 3. 透视变换矫正

warped = self.perspective_transform(image, contour)

return warped

return None

def perspective_transform(self, image, contour):

透视变换将扑克牌校正为矩形

# 对四个顶点排序:左上、右上、右下、左下

points = contour.reshape(4, 2)

rect = np.zeros((4, 2), dtype="float32")

# 计算四个点的中心

s = points.sum(axis=1)

rect[0] = points[np.argmin(s)] # 左上

rect[2] = points[np.argmax(s)] # 右下

# 计算点之间的差异

diff = np.diff(points, axis=1)

rect[1] = points[np.argmin(diff)] # 右上

rect[3] = points[np.argmax(diff)] # 左下

# 定义目标矩形尺寸

width = 200

height = 300

dst = np.array([

[0, 0],

[width-1, 0],

[width-1, height-1],

[0, height-1]

], dtype="float32")

# 计算透视变换矩阵

M = cv2.getPerspectiveTransform(rect, dst)

warped = cv2.warpPerspective(image, M, (width, height))

return warped

def recognize_card(self, card_image):

识别扑克牌

if self.model:

# 使用深度学习模型识别

return self.deep_learning_recognition(card_image)

else:

# 使用传统方法识别

return self.traditional_recognition(card_image)

def traditional_recognition(self, card_image):

传统识别方法

# 提取左上角区域(包含花色和点数)

corner_region = card_image[10:60, 10:50]

# 颜色分析识别花色

suit = self.recognize_suit_by_color(corner_region)

# 模板匹配识别点数

rank = self.recognize_rank_by_template(corner_region)

return f"{rank} of {suit}

def recognize_suit_by_color(self, region):

通过颜色识别花色

hsv = cv2.cvtColorvtColor(region, cv2.COLOR_BGR2HSV)

# 红色范围

red_lower1 = np.array([0, 100, 100])

red_upper1 = np.array([10, 255, 255])

red_lower2 = np.array([160, 100, 100])

100])

red_upper2 = np.array([180, 255, 255])

red_mask1 = cv2.inRange(hsv, red_lower1, red_upper1)

red_mask2 = cv2.inRange(hsv, red_lower2, red_upper2)

red_mask = red_mask1 | red_mask2

red_pixels = cv2.countNonZero(red_mask)

if red_pixels > 100:

return "Hearts" # 或 Diamonds,需要进一步区分

else:

return "Clubs" # 或 Spades,需要进一步区分

实际应用代码示例

python

def main:

# 初始化识别器

recognizer = PokerCardRecognizer

# 读取图像

image = cv2.imread('poker_table.jpg')

# 检测并识别所有扑克牌

cards = detect_all_cards(image, recognizer)

for i, card_info in enumerate(cards):

print(f"Card {i+1}: {card_info['rank']} of {card_info['suit']}")

cv2.imshow(f"Card {i+1}", card_info['image'])

cv2.waitKey(0)

cv2.destroyAllWindows

def detect_all_cards(image, recognizer):

检测图像中的所有扑克牌

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

blurred = cv2.GaussianBlur(gray, (7, 7), 0)

edges = cv2.Canny(blurred, 50, 150)

# 查找轮廓

contours, _ = cv2.findContours(edges, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cards = []

for contour in contours:

if cv2.contourArea(contour) > 5000: # 过滤小轮廓

epsilon = 0.02 * cv2.arcLength(contour, True)

approx = cv2.approxPolyDP(contour, epsilon, True)

if len(approx) == 4:

card_image = recognizer.extract_card_region(image)

if card_image is not None:

recognition_result = recognizer.recognize_card(card_image)

cards.append({

'image': card_image,

'contour': contour,

扑克排识別(扑克牌的识别)

'recognition': recognition_result

})

return cards

性能优化建议

1. 多尺度检测:在不同尺度下检测扑克牌

2. 非极大值抑制:避免重复检测同一张牌

3. GPU加速:使用CUDA加速DA加速深度学习推理

4. 缓存机制:缓存已识别的模板结果

常见挑战及解决方案

  • 光照变化:使用直方图均衡化和自适应阈值
  • 遮挡问题:结合局部特征和全局特征
  • 变形问题:使用透视变换进行校正
  • 实时性要求:优化算法复杂度,使用轻量级模型
  • 这个框架可以根据具体需求进行调整和扩展,以适应不同的应用场景。