基于python定位棋子位置及识别棋子颜色

目录
  • 1、将棋盘分割成19x19的小方格
  • 2、根据像素占比识别是否是黑色棋子
  • 3、根据像素占比识别是否是白色棋子
  • 4、将棋盘棋子位置通过列表表示
  • 完整代码如下:

这一篇主要实现定位棋子位置及识别棋子颜色。

围棋棋盘原图如下:

经过上一章节处理,已经将棋盘位置找到,如下图:

现在根据新图,进行棋子位置的定位

1、将棋盘分割成19x19的小方格

为了定位出棋盘每个交叉点上,是否有棋子,需要将棋盘分割成19X19的小方格,由于围棋棋盘每个交叉线直接距离相同,是矩形,因此分割成小方格十分容易,如下图:

若想将棋盘分割成19x19的小方格,需要知道以下几个参数。

small_length=38  #每个小格宽高
qizi_zhijing=38#棋子直径
zuoshangjiao=20#棋盘四周的宽度

这些可以使用imagewathch(VS下opencv的插件)工具,方便的知道,这个工具可以实时查看图像的宽高,某个位置的像素值。这个工具的使用可以看我另外一篇文章:opencv用VS2013调试时用Image Watch插件查看图片,代替一堆数据,直观很多。
下面是将原图分割成19X19小方格的代码

img = cv2.imread("src.jpg")
cv2.imshow("src",img)
#变量定义
small_length=38  #每个小格宽高
qizi_zhijing=38#棋子直径
zuoshangjiao=20#棋盘四周的宽度

for i in range(19):
    for j in range(19):
        #print(i,j)
        lie = i
        hang = j
        Tp_x = small_length * lie
        Tp_y = small_length * hang
        Tp_width = qizi_zhijing
        Tp_height = qizi_zhijing

        #测试用
        cv2.rectangle(img, (Tp_x, Tp_y), (Tp_x + Tp_width, Tp_y + Tp_height),(255, 0, 0), 2)
        cv2.imwrite('img.jpg', img)
        img_temp=img[Tp_y:Tp_y+Tp_height, Tp_x:Tp_x+Tp_width]#参数含义分别是:y、y+h、x、x+w
        cv2.imwrite('img_temp3.jpg', img_temp)
        cv2.imshow("3", img_temp)
        cv2.waitKey(20)

2、根据像素占比识别是否是黑色棋子



上面三种图像是我们分割成小方格后的三种主要形态,分别代表黑色棋子,白色棋子以及无棋子。其中黑色棋子最好查找,我们将图像进行灰度化——二值化后,通过统计黑色像素占比超过一定数值,就能知道该处是否有黑色棋子。

这里我将统计黑色占比的代码,封装成了一个函数,如下;

"""  "*******************************************************************************************
*函数功能 :统计二值化图片黑色像素点百分比
*输入参数 :输入裁剪后图像,
*返 回 值 :返回黑色像素点占比0-1之间
*编写时间 : 2021.6.30
*作    者 : diyun
********************************************************************************************"""
def Heise_zhanbi(img):
    [height, width, tongdao] = img.shape
    #print(width, height, tongdao)
    # cv2.imshow("3", img)
    # cv2.waitKey(20)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # cv2.imshow("binary", gray)
    # cv2.waitKey(100)

    etVal, threshold = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)
    # cv2.imshow("threshold", threshold)
    # cv2.waitKey(200)
    a = 0
    b = 0
    counter = 0#;/*目标像素点个数*/
    zhanbi = 0#;/*目标像素点比值*/
    for row in range(height):
        for col in range(width):
            val = threshold[row][col]
            if (val) == 0:#黑色
                a = a + 1
            else:
                b = b + 1
    zhanbi = (float)(a) / (float)(height*width)
    #print("黑色像素个数", a, "黑色像素占比", zhanbi)
    return zhanbi

3、根据像素占比识别是否是白色棋子

同样的,我们可以统计像素中白色占比,来进行识别该位置是否是白色棋子,但是这里需要注意一个问题,如果按照上面黑色棋子识别方法进行灰度化、二值化会造成白色棋子和无棋子分辨不了,二者都有大面积的白色,因此这里需要调整二值化的阈值,分开无棋子和白色棋子的图像。

封装好的代码如下:

"""  "*******************************************************************************************
*函数功能 :统计二值化图片白色像素点百分比
*输入参数 :输入裁剪后图像,
*返 回 值 :返回白色像素点占比0-1之间
*编写时间 : 2021.6.30
*作    者 : diyun
********************************************************************************************"""
def Baise_zhanbi(img):
    [height, width, tongdao] = img.shape
    #print(width, height, tongdao)
    # cv2.imshow("3", img)
    # cv2.waitKey(20)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # cv2.imshow("binary", gray)
    # cv2.waitKey(100)

    etVal, threshold = cv2.threshold(gray, 235, 255, cv2.THRESH_BINARY)
    # cv2.imshow("threshold", threshold)
    # cv2.waitKey(200)
    a = 0
    b = 0
    counter = 0#;/*目标像素点个数*/
    zhanbi = 0#;/*目标像素点比值*/
    for row in range(height):
        for col in range(width):
            val = threshold[row][col]
            if (val) == 0:#黑色
                a = a + 1
            else:
                b = b + 1
    zhanbi = (float)(b) / (float)(height*width)
    #print("白色像素个数", b, "白色像素占比", zhanbi)
    return zhanbi

效果图如下:

4、将棋盘棋子位置通过列表表示

我们新建一个19*19的列表来存储棋子,列表中:

0:代表无棋子
1:代表白色
2:代表黑色

代码如下:

list = [[0 for i in range(19)] for j in range(19)]

当为黑色棋子时:

list[hang][lie]=2#黑色
#print("当前棋子为黑色")
print("第", i, "行,第", j, "列棋子为黑色:", i, j)

当为白色棋子时:

list[hang][lie] = 1  # 白色
#print("当前棋子为白色")
print("第", i, "行,第", j, "列棋子为白色:", i, j)

效果图如下:

完整代码如下:

from PIL import ImageGrab
import numpy as np
import cv2
from glob import glob
import os

import time

#Python将数字转换成大写字母
def getChar(number):
    factor, moder = divmod(number, 26) # 26 字母个数
    modChar = chr(moder + 65)          # 65 -> 'A'
    if factor != 0:
        modChar = getChar(factor-1) + modChar # factor - 1 : 商为有效值时起始数为 1 而余数是 0
    return modChar
def getChars(length):
    return [getChar(index) for index in range(length)]

"""  "*******************************************************************************************
*函数功能 :统计二值化图片黑色像素点百分比
*输入参数 :输入裁剪后图像,
*返 回 值 :返回黑色像素点占比0-1之间
*编写时间 : 2021.6.30
*作    者 : diyun
********************************************************************************************"""
def Heise_zhanbi(img):
    [height, width, tongdao] = img.shape
    #print(width, height, tongdao)
    # cv2.imshow("3", img)
    # cv2.waitKey(20)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # cv2.imshow("binary", gray)
    # cv2.waitKey(100)

    etVal, threshold = cv2.threshold(gray, 125, 255, cv2.THRESH_BINARY)
    # cv2.imshow("threshold", threshold)
    # cv2.waitKey(200)
    a = 0
    b = 0
    counter = 0#;/*目标像素点个数*/
    zhanbi = 0#;/*目标像素点比值*/
    for row in range(height):
        for col in range(width):
            val = threshold[row][col]
            if (val) == 0:#黑色
                a = a + 1
            else:
                b = b + 1
    zhanbi = (float)(a) / (float)(height*width)
    #print("黑色像素个数", a, "黑色像素占比", zhanbi)
    return zhanbi

"""  "*******************************************************************************************
*函数功能 :统计二值化图片白色像素点百分比
*输入参数 :输入裁剪后图像,
*返 回 值 :返回白色像素点占比0-1之间
*编写时间 : 2021.6.30
*作    者 : diyun
********************************************************************************************"""
def Baise_zhanbi(img):
    [height, width, tongdao] = img.shape
    #print(width, height, tongdao)
    # cv2.imshow("3", img)
    # cv2.waitKey(20)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # cv2.imshow("binary", gray)
    # cv2.waitKey(100)

    etVal, threshold = cv2.threshold(gray, 235, 255, cv2.THRESH_BINARY)
    # cv2.imshow("threshold", threshold)
    # cv2.waitKey(200)
    a = 0
    b = 0
    counter = 0#;/*目标像素点个数*/
    zhanbi = 0#;/*目标像素点比值*/
    for row in range(height):
        for col in range(width):
            val = threshold[row][col]
            if (val) == 0:#黑色
                a = a + 1
            else:
                b = b + 1
    zhanbi = (float)(b) / (float)(height*width)
    #print("白色像素个数", b, "白色像素占比", zhanbi)
    return zhanbi

"""  "*******************************************************************************************
*函数功能 :定位棋盘位置
*输入参数 :截图
*返 回 值 :裁剪后的图像
*编写时间 : 2021.6.30
*作    者 : diyun
********************************************************************************************"""
def dingweiqizi_weizhi(img):
    '''********************************************
    1、定位棋盘位置
    ********************************************'''
    #img = cv2.imread("./screen/1.jpg")

    image = img.copy()
    w, h, c = img.shape
    img2 = np.zeros((w, h, c), np.uint8)
    img3 = np.zeros((w, h, c), np.uint8)
    # img = ImageGrab.grab() #bbox specifies specific region (bbox= x,y,width,height *starts top-left)

    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    lower = np.array([10, 0, 0])
    upper = np.array([40, 255, 255])
    mask = cv2.inRange(hsv, lower, upper)
    erodeim = cv2.erode(mask, None, iterations=2)  # 腐蚀
    dilateim = cv2.dilate(erodeim, None, iterations=2)

    img = cv2.bitwise_and(img, img, mask=dilateim)
    frame = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, dst = cv2.threshold(frame, 100, 255, cv2.THRESH_BINARY)
    contours, hierarchy = cv2.findContours(dst, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    #cv2.imshow("0", img)

    i = 0
    maxarea = 0
    nextarea = 0
    maxint = 0
    for c in contours:
        if cv2.contourArea(c) > maxarea:
            maxarea = cv2.contourArea(c)
            maxint = i
        i += 1

    # 多边形拟合
    epsilon = 0.02 * cv2.arcLength(contours[maxint], True)
    if epsilon < 1:
        print("error :   epsilon < 1")
        pass

    # 多边形拟合
    approx = cv2.approxPolyDP(contours[maxint], epsilon, True)
    [[x1, y1]] = approx[0]
    [[x2, y2]] = approx[2]

    checkerboard = image[y1:y2, x1:x2]
    # cv2.imshow("1", checkerboard)
    # cv2.waitKey(1000)
    #cv2.destroyAllWindows()
    return checkerboard

"""  "*******************************************************************************************
*函数功能 :定位棋子颜色及位置
*输入参数 :裁剪后的图像
*返 回 值 :棋子颜色及位置列表
*编写时间 : 2021.6.30
*作    者 : diyun
********************************************************************************************"""
def dingweiqizi_yanse_weizhi(img):
    '''********************************************
    2、识别棋盘棋子位置及颜色及序号;
    ********************************************'''
    #img = cv2.imread("./checkerboard/checkerboard_1.jpg")
    img = cv2.resize(img, (724,724), interpolation=cv2.INTER_AREA)
    #cv2.imshow("src",img)
    #cv2.waitKey(1000)

    #变量定义
    small_length=38  #每个小格宽高
    qizi_zhijing=38#棋子直径
    zuoshangjiao=20#棋盘四周的宽度

    list = [[0 for i in range(19)] for j in range(19)]
    #print(list)

    for i in range(19):
        for j in range(19):

            lie = i
            hang = j

            Tp_x = small_length * lie
            Tp_y = small_length * hang
            Tp_width = qizi_zhijing
            Tp_height = qizi_zhijing

            img_temp=img[Tp_y:Tp_y+Tp_height, Tp_x:Tp_x+Tp_width]#参数含义分别是:y、y+h、x、x+w

            heise_zhanbi=Heise_zhanbi(img_temp)
            if heise_zhanbi>0.5:
                list[hang][lie]=2#黑色
                print("第", j+1, "行,第", i+1, "列棋子为黑色")
                #print("当前棋子为黑色")
            else:
                baise_zhanbi = Baise_zhanbi(img_temp)
                if baise_zhanbi > 0.15:
                    list[hang][lie] = 1  # 白色
                    print("第", j+1, "行,第",i+1 , "列棋子为白色")
                    #print("当前棋子为白色")
                else:
                    list[hang][lie] = 0  # 无棋子
                    #print("当前位置没有棋子")
            #print(heise_zhanbi)
    #cv2.imshow("2",img)
    #print("\n")
    #print(list)
    return  list

if __name__ =="__main__":
    list0 = [[0 for i in range(19)] for j in range(19)]
    list_finall = []
    img = cv2.imread("./screen/9.jpg")

    '''********************************************
    1、定位棋盘位置
    ********************************************'''
    img_after=dingweiqizi_weizhi(img)
    #cv2.imshow("src",img)

    '''********************************************
    2、识别棋盘棋子位置及颜色及序号;
    ********************************************'''
    list1=dingweiqizi_yanse_weizhi(img_after)
    print(list1)

到此这篇关于基于python定位棋子位置及识别棋子颜色的文章就介绍到这了,更多相关python定位棋子位置及识别棋子颜色内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • python识别围棋定位棋盘位置

    目录 效果图 思路分析 源码:定位棋盘位置 最近需要做一个围棋识别的项目,首先要将棋盘位置定位出来,效果图如下: 效果图 原图 中间处理效果 最终结果 思路分析 我们利用python opencv的相关函数进行操作实现,根据棋盘颜色的特征,寻找到相关特征,将棋盘区域抠出来.最好从原始图像中将棋盘位置截取出来. 源码:定位棋盘位置 from PIL import ImageGrab import numpy as np import cv2 from glob import glob imglis

  • 基于python定位棋子位置及识别棋子颜色

    目录 1.将棋盘分割成19x19的小方格 2.根据像素占比识别是否是黑色棋子 3.根据像素占比识别是否是白色棋子 4.将棋盘棋子位置通过列表表示 完整代码如下: 这一篇主要实现定位棋子位置及识别棋子颜色. 围棋棋盘原图如下: 经过上一章节处理,已经将棋盘位置找到,如下图: 现在根据新图,进行棋子位置的定位 1.将棋盘分割成19x19的小方格 为了定位出棋盘每个交叉点上,是否有棋子,需要将棋盘分割成19X19的小方格,由于围棋棋盘每个交叉线直接距离相同,是矩形,因此分割成小方格十分容易,如下图:

  • 基于Python实现简单的人脸识别系统

    目录 前言 基本原理 代码实现 创建虚拟环境 安装必要的库 前言 最近又多了不少朋友关注,先在这里谢谢大家.关注我的朋友大多数都是大学生,而且我简单看了一下,低年级的大学生居多,大多数都是为了完成课程设计,作为一个过来人,还是希望大家平时能多抽出点时间学习一下,这种临时抱佛脚的策略要少用嗷.今天我们来python实现一个人脸识别系统,主要是借助了dlib这个库,相当于我们直接调用现成的库来进行人脸识别,就省去了之前教程中的数据收集和模型训练的步骤了. B站视频:用300行代码实现人脸识别系统_哔

  • 基于Python实现智能停车场车牌识别计费系统

    目录 项目结构 主要代码 实现效果 前段时间练习过的一个小项目,今天再看看,记录一下~ 项目结构 说明: datefile文件夹:保存车辆信息表的xlsx文件 file文件夹:保存图片文件夹.ic_launcher.jpg是窗体的右上角图标文件:income.png是实现收入统计的柱状图(下一篇文章实现):key.txt是使用百度的图片识别AI接口申请的key:test.jpg保存的是摄像头抓取的图片 venv文件夹:项目所需要的各种模块,即项目运行环境 btn.py文件:按钮模块 main.p

  • 基于Python实现简易的植物识别小系统

    导语 "  花草树木 皆有呈名 热爱自然,从认识自然开始 " 现在的植物爱好者,遇到不认得的植物.怎么办呢? 前几天去逛商场,一进商城一一一一门口的花店吸引了我的注意:摆放在店门口的各色鲜花植物花卉真的特别好看! 忍不住进门逛了一圈,发现我真的不认识,种类太多,对花卉的品种了解颇少. 回来之后找到了2款简单好用的植物识别APP一一一伴侣跟形色蛮好用的! 闲着也是闲着:默默用Python编写了一款简单的植物识别系统给大家正好la~ 正文 1)环境安装 本文用到的环境:Python3.7 

  • python+OpenCV实现车牌号码识别

    基于python+OpenCV的车牌号码识别,供大家参考,具体内容如下 车牌识别行业已具备一定的市场规模,在电子警察.公路卡口.停车场.商业管理.汽修服务等领域已取得了部分应用.一个典型的车辆牌照识别系统一般包括以下4个部分:车辆图像获取.车牌定位.车牌字符分割和车牌字符识别 1.车牌定位的主要工作是从获取的车辆图像中找到汽车牌照所在位置,并把车牌从该区域中准确地分割出来 这里所采用的是利用车牌的颜色(黄色.蓝色.绿色) 来进行定位 #定位车牌 def color_position(img,ou

  • python微信跳一跳系列之棋子定位颜色识别

    python微信跳一跳,前言 这是python玩跳一跳系列博文中一篇,主要内容是用颜色识别的方法来进行跳跳小人的定位. 颜色识别 过观察,我们可以发现,尽管背景和棋子在不停的变化,但跳跳小人的形状和颜色基本保持不变,对于形状,我们在上一篇博文中已经采用模板匹配的方法来进行识别定位,效果非常好.这一篇博文就来对颜色识别进行验证. 基本思路 用HSV颜色空间对输入的图片进行处理,用某种指定的颜色进行蒙版mask处理进而得到二值化的黑白图像,膨胀和腐蚀后去除噪点,对轮廓区域进行计算,画出圆心和质心位置

  • python微信跳一跳系列之棋子定位像素遍历

    前言 在前几篇博客中,分别就棋子的颜色识别.模板匹配等定位方式进行了介绍和实践,这一篇博客就来验证一下github中最热门的跳一跳外挂中采用的像素遍历的方法. 方法说明 像素遍历的实质依然是颜色识别. 在github中给出的方法中,采用像素遍历的方法是: 从高度的1/3处开始至高度的2/3处进行遍历: 首先间隔50像素进行搜索 当像素的颜色和每一行开始的像素颜色不同时,认为找到了最上面的棋盘位置,则返回上一个间隔处开始遍历(i-50): 对每一行的像素都进行遍历,当满足给定的颜色范围时,记录最下

  • 基于Python实现人脸识别和焦点人物检测功能

    写在前面的话 基于dlib库的模型,实现人脸识别和焦点人物的检测.最后呈现的效果为焦点人物的识别框颜色与其他人物框不一样. 准备工作 需要安装好python环境,安装好dlib.opencv-python库等,具体可以看报错信息(可以使用PyCharm来运行和编辑py文件),然后把需要的库补全,文章最后会有完整代码,但是需要与shape_predictor_68_face_landmarks.dat模型文件同处一个路径下,然后启用.(百度可以下载到) 设计过程 因为是在自己电脑完成的必做题设计,

  • 基于Python搭建人脸识别考勤系统

    目录 介绍 人脸识别的实际应用 构建人脸识别系统的步骤 安装库 导入库 加载图像 查找人脸位置并绘制边界框 为人脸识别训练图像 构建人脸识别系统 人脸识别系统面临的挑战 结论 介绍 在本文中,你将学习如何使用 Python 构建人脸识别系统.人脸识别比人脸检测更进一步.在人脸检测中,我们只检测人脸在图像中的位置,但在人脸识别中,我们制作了一个可以识别人的系统. "人脸识别是验证或识别图片或视频中的人的挑战.大型科技巨头仍在努力打造更快.更准确的人脸识别模型." 人脸识别的实际应用 人脸

随机推荐