VV游戏

 找回密码
 立即注册
查看: 187|回复: 0

中国象棋实时分析棋局——棋子识别方法分析

[复制链接]

5

主题

8

帖子

17

积分

新手上路

Rank: 1

积分
17
发表于 2023-3-5 00:41:14 | 显示全部楼层 |阅读模式
识别棋子有两种方式


  • 使用霍夫变换圆检测定位棋子位置,再自己训练一个cnn模型识别棋子(共有10个不同的字),最后识别棋子颜色
    这种方法存在一个问题,如果换了一种不同大小的棋子,圆就检测不出来,需要重新调整参数。cnn模型采用的是VGG16网络结构,每个不同的棋子用了约1000张图片进行训练,效果不好,总是有一两个棋子识别不出来。
  • 使用目标检测算法
    这种方法就很通用,上一个方法还要把所有检测出来的圆放到模型里识别,这种方法只要一张截图,目前主流的目标检测算法有YOLO、SSD、Faster RCNN等算法。个人倾向于使用SSD,它会把图形划分为38x38、19x19、10x10、5x5、3x3、1x1的网格,比较符合棋盘结构。
识别棋盘

通过霍夫变换获取线段,再从这些线段里获取棋盘格子的宽高以及棋盘边缘的宽高
象棋棋谱之表格识别(一)
作者:冒泡的肥皂
目标检测训练模型

我此次训练使用了200多张图片,效果还可以,能准确的识别出棋子。
对棋子进行分类
# 黑方
bk # 将
ba # 仕
bb # 象
bn # 马
br # 车
bc # 炮
bp # 卒
# 红方
rk # 帅
ra # 仕
rb # 相
rn # 马
rr # 车
rc # 炮
rp # 兵图片标注是件很浪费时间的事情,因为棋子是圆形的,所以可以用霍夫变换圆检测来标注,打开LabelImg执行下面代码就可以把棋子框起来,再手动改棋子名字
import cv2 as cv
import pyautogui
import numpy as np

left = 420
top = 60
width = 855
height = 940

def labelImg(pixel_pos):
    print(pixel_pos)
    # 按下创建box
    pyautogui.moveTo(70,620,duration=0.5)
    pyautogui.click()

    pyautogui.moveTo(left + pixel_pos[0], top + pixel_pos[1],duration=0.5)
    pyautogui.dragTo(left + pixel_pos[0]+pixel_pos[2], top + pixel_pos[1]+pixel_pos[3],button='left',duration=0.5)
    pyautogui.press('enter')

def recognize(img):
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    # 检测棋盘上的圆
    circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, 50, param1=2, param2=30, minRadius=21, maxRadius=33)

    piece_img_list = []  # cv.imread图片
    piece_info_list = []  # 棋子信息(x,y,r,piece_name)
    piece_pixel_pos = []
    for i in circles[0, :]:
        x = int(i[0])  # 圆心x
        y = int(i[1])  # 圆心y
        r = int(i[2])  # 圆半径
        piece_img = img[y - r:y + r, x - r:x + r]
        piece_img_list.append(piece_img)
        piece_info_list.append([x, y, r, ''])
        piece_pixel_pos.append([x - r,max(y - r,0),  2*r,2*r])

    # 排序从左到右,从上到下
    piece_pixel_pos = sorted(piece_pixel_pos,key=lambda x:(x[1],x[0]),reverse=False)

    # 把棋子标注出来
    for i in range(len(piece_img_list)):
        piece_img = piece_img_list
        cv.rectangle(piece_img, (0, 0), (2 * piece_info_list[2], 2 * piece_info_list[2]), 255, 2)
        labelImg(piece_pixel_pos)
    return img

if __name__ == '__main__':
    img = pyautogui.screenshot(region=(left, top, width, height))
    img = np.array(img)
    img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

    # 识别圆的位置
    img = recognize(img)软件效果展示

软件效果展示
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|VV游戏

GMT+8, 2025-4-13 18:09 , Processed in 0.111170 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表