python opencv模板匹配制作 记牌器

基于opencv的模板匹配制作的 记牌器

基于python opencv的模板匹配制作的记牌器

实现思路,通过python win32获取程序的窗口句柄,然后后台自动截屏,针对每屏进行扑克牌匹配,实现识别开局,自家扑克、底牌、上下家出牌识别,记录对局剩余扑克,自动识别游戏结束,重新统计对局

已实现功能

功能截图

在这里插入图片描述
在这里插入图片描述

功能视频演示

记牌器演示 学习

仓库地址

gitee:https://gitee.com/css_code/happy-fight-opencv.git
github:https://github.com/cShen-code/happy-fight-opencv.git

技术栈

  • python
  • PyQt5
  • win32gui
  • cv2

安装

# 安装 opencv 使用清华镜像下载
pip install python-opencv -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install win32gui -i https://pypi.tuna.tsinghua.edu.cn/simple

进入正题

思考:
1、python 如何截屏指定窗口?
2、想要截图的窗口不在顶层,肉眼不可见怎么办呢?

查看想要截图的窗口句柄

工具:spy++ 下载地址
使用方法:
在这里插入图片描述

在这里插入图片描述
拖动Finder Tool 工具到目标窗口,得到窗口句柄caption和class,这里咱们主要用到 caption

获取游戏截图

import win32gui, win32ui, win32con
import cv2
import numpy as np


def screen():
    hWnd = win32gui.FindWindow(None, "欢(删)乐(删)斗(删)地(删)主")
    left, top, right, bot = win32gui.GetWindowRect(hWnd)
    width = right - left
    height = bot - top
    # 窗口隐藏或最小化,无法截图
    if top < 0:
        return None
    # 返回句柄窗口的设备环境,覆盖整个窗口,包括非客户区,标题栏,菜单,边框
    hWndDC = win32gui.GetWindowDC(hWnd)
    # 创建设备描述表
    mfcDC = win32ui.CreateDCFromHandle(hWndDC)
    # 创建内存设备描述表
    saveDC = mfcDC.CreateCompatibleDC()
    # 创建位图对象准备保存图片
    saveBitMap = win32ui.CreateBitmap()
    # 为bitmap开辟存储空间
    saveBitMap.CreateCompatibleBitmap(mfcDC, width, height)
    # 将截图保存到saveBitMap中
    saveDC.SelectObject(saveBitMap)
    saveDC.BitBlt((0, 0), (width, height), mfcDC, (0, 0), win32con.SRCCOPY)
    # 保存截图
    # saveBitMap.SaveBitmapFile(saveDC, "img_Winapi.bmp")
    signedIntsArray = saveBitMap.GetBitmapBits(True)
    img = np.fromstring(signedIntsArray, dtype='uint8')
    img.shape = (height, width, 4)
    # 保存bitmap到内存设备描述表
    img = cv2.resize(img, (1040, 629), interpolation=cv2.INTER_CUBIC)
    img = cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
    # cv2.imwrite('screen.png', img)
    # 返回一张可以给opencv 使用的图片
    return img


# 调用截图方法,获取截图结果
img = screen()

# 转为灰色通道的图片
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 显示图片
cv2.imshow('img', img_gray)
# 任意键退出
cv2.waitKey(0)

运行效果:
在这里插入图片描述

截取感兴趣区域

# 调用截图方法,获取截图结果
img = screen()

# 转为灰色通道的图片,截取自己的出牌区域
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)[350:622, 10:1042]
# 显示图片
cv2.imshow('img', img_gray)
# 任意键退出
cv2.waitKey(0)

运行效果:
在这里插入图片描述

第三步,模板匹配

在这里插入图片描述
模板文件我已经整理好,在代码仓库中

# 模板匹配方法
def matchImgNum(bgImg, templeteImg, threshold=0.92):
    '''
    bgImg:截图出来的底片
    templeteImg;模板图片
    threshold:对比精确度
    '''
    res = cv2.matchTemplate(bgImg, templeteImg, cv2.TM_CCOEFF_NORMED)
    tt = bgImg.copy()
    w, h = templeteImg.shape[::-1]
    loc = np.where(res >= threshold)
    num = 0
    if len(loc[0]) != 0:
        last = 0
        # 排序
        loc[1].sort()
        for point in loc[1]:
            if abs(last - point) > 5:
                num += 1
                # if save:
                # print(save)
                for pt in zip(*loc[::-1]):
                    cv2.rectangle(tt, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
                cv2.imwrite('res223.png', tt)
            last = point
    return num


# 调用截图方法,获取截图结果
img = screen()
# 转为灰色通道的图片,截取自己的出牌区域
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)[350:622, 10:1042]

# 读取 模板, 扑克4
temp = cv2.imread('templete/fangkuai_10.png', 0)
num = matchImgNum(img, temp, 0.85)
print('匹配出结果', num)

运行效果:
匹配出结果 4
在这里插入图片描述
ok,目前为止我们已经可以准确识别出自己的卡牌和数量,下一篇文章中我们将继续演示识别其他玩家的出牌和地板,以及剩余的扑克,和出牌过程中的动态修改剩余纸牌数量

仓库地址

gitee:https://gitee.com/css_code/happy-fight-opencv.git

github:https://github.com/cShen-code/happy-fight-opencv.git

下载尝鲜

git仓库中上传了成品文件,下载即可体验

  • 10
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 22
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值