最近在做一个围棋棋盘棋子识别项目,这是该项目第二篇,系列文章如下:

1、基于python及图像识别的围棋棋盘棋子识别1——定位棋盘位置
2、基于python及图像识别的围棋棋盘棋子识别2——定位棋子位置及识别棋子颜色
3、基于python及图像识别的围棋棋盘棋子识别3——耗时优化(一行代码速度提高600倍)
4、基于python及图像识别的围棋棋盘棋子识别4——源码及使用说明

基于python及图像识别的围棋棋盘棋子识别2——定位棋子位置及识别棋子颜色

  • 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 = ihang = jTp_x = small_length * lieTp_y = small_length * hangTp_width = qizi_zhijingTp_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+wcv2.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 = 0b = 0counter = 0#;/*目标像素点个数*/zhanbi = 0#;/*目标像素点比值*/for row in range(height):for col in range(width):val = threshold[row][col]if (val) == 0:#黑色a = a + 1else:b = b + 1zhanbi = (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 = 0b = 0counter = 0#;/*目标像素点个数*/zhanbi = 0#;/*目标像素点比值*/for row in range(height):for col in range(width):val = threshold[row][col]if (val) == 0:#黑色a = a + 1else:b = b + 1zhanbi = (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 osimport 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 而余数是 0return 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 = 0b = 0counter = 0#;/*目标像素点个数*/zhanbi = 0#;/*目标像素点比值*/for row in range(height):for col in range(width):val = threshold[row][col]if (val) == 0:#黑色a = a + 1else:b = b + 1zhanbi = (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 = 0b = 0counter = 0#;/*目标像素点个数*/zhanbi = 0#;/*目标像素点比值*/for row in range(height):for col in range(width):val = threshold[row][col]if (val) == 0:#黑色a = a + 1else:b = b + 1zhanbi = (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.shapeimg2 = 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 = 0maxarea = 0nextarea = 0maxint = 0for c in contours:if cv2.contourArea(c) > maxarea:maxarea = cv2.contourArea(c)maxint = ii += 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 = ihang = jTp_x = small_length * lieTp_y = small_length * hangTp_width = qizi_zhijingTp_height = qizi_zhijingimg_temp=img[Tp_y:Tp_y+Tp_height, Tp_x:Tp_x+Tp_width]#参数含义分别是:y、y+h、x、x+wheise_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  listif __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及图像识别的围棋棋盘棋子识别2——定位棋子位置及识别棋子颜色相关推荐

  1. 基于python及图像识别的围棋棋盘棋子识别4——源码及使用说明

    最近在做一个围棋棋盘棋子识别项目,这是该项目第四篇,系列文章如下: 1.基于python及图像识别的围棋棋盘棋子识别1--定位棋盘位置 2.基于python及图像识别的围棋棋盘棋子识别2--定位棋子位 ...

  2. 基于Python实现的微信好友数据分析——抓取好友性别、位置、头像签名

    最近微信迎来了一次重要的更新,允许用户对"发现"页面进行定制.不知道从什么时候开始,微信朋友圈变得越来越复杂,当越来越多的人选择"仅展示最近三天的朋友圈",大概 ...

  3. 基于Python实现图画转换字符画

    微信改版,加星标不迷路! 基于Python实现图画转换字符画 作者:阿广 概述 前言 准备工作 识别原理 静态图像处理 动态图像处理 结果 阿广说 群聊交流 福利一刻 推荐阅读 前言 前几天写了基于P ...

  4. python动图转换成字符画动图_基于Python实现图画转换字符画

    微信改版,加星标不迷路! 基于Python实现图画转换字符画 作者:阿广 概述 前言 准备工作 识别原理 静态图像处理 动态图像处理 结果 阿广说 群聊交流 福利一刻 推荐阅读 前言 前几天写了基于P ...

  5. 基于Python的人脸表情管理系统设计与实现

    目 录 摘 要 I Abstract II 第一章 绪论 1 1.1 研究背景及意义 1 1.2 研究现状 1 1.3 本文研究的主要内容 3 第二章 人脸表情识别基础 4 2.1 常见的表情数据库 ...

  6. 基于Python,dlib实现人脸关键点检测

    @代码实现及安装过程 基于Python,dlib实现人脸关键点检测 dilb 在做人脸检测人脸识别方面用到比较多的.face_recognition就是基于dlib实现的. 这篇文章将使用Python ...

  7. 基于python pyqt的围棋游戏制作

    文章目录 1.初始化棋盘 2.初始化棋子 3.开始游戏 4.落子设置 5.吃子判断 6 悔棋和弃一子 7 重新开始.推出与切换棋盘 8 显示 9 初始化 本文使用python中的pygame库设计制作 ...

  8. python 用turtle库画围棋棋盘和正、余弦函数图形

    一.如何画围棋棋盘. 围棋棋盘共有19纵19横.其中,位于(0,0)的星位叫天元,其余8个星位坐标分别是:(-6,6),(0,6),(6,6),(-6,0),(6,0),(-6,-6),(0,-6), ...

  9. python 绘制围棋棋盘_围棋之规则基础(一)

    ★本期导读: 一.围棋的下法 二.气 ★正文: 一.围棋的下法 1. 对局双方各执一色棋子. 2. 空枰开局. 3. 黑先白后,交替着一子于棋盘的交叉点上. 4. 棋子下定后,不再向其它点移动. 5. ...

  10. 基于python 使用sikuli图像识别

    基于python使用sikuli图像识别 import time from jpype import * 参考如下代码段: if __name__ == '__main__':startJVM(r'C ...

最新文章

  1. springboot 做表白墙_学校表白墙有多羞耻??!辣眼分析数千条表白内容,原来脱单秘密在这里.......
  2. 3、Python 基础类型 -- List 列表类型
  3. 布隆过滤器避免redis缓存穿透
  4. 文章和随笔的标题好像没有HtmlEnCode。
  5. asp建站系统源码_三款适用于企业建站的CMS建站系统
  6. socket接收的消息怎么更新到页面_利用socketio实现简易即时消息服务
  7. Hash算法中的CRC
  8. Java开发笔记(六十九)泛型类的定义及其运用
  9. spring 多线程 写入数据库 和 写入 xml文件
  10. 综述-自动驾驶中基于图像的3D目标检测
  11. 萤火虫算法_一种优化方法:蜂鸟优化算法
  12. 国内OA办公自动化系统现状
  13. 洛谷P1640 [SCOI2010]连续攻击游戏 (二分图) HQG_AC 的博客
  14. 企业微信如何查看,或更换手机号
  15. MySql 如何查询某一天内的数据
  16. cassandra多个数据中心实现异地容灾
  17. 利用反向代理服务器,加快国内对国外主机的访问
  18. NEUQ ACM预备队训练-week5(图的基础存图和dfs)
  19. 计算机图形学中的常用模型
  20. v-model的实现原理

热门文章

  1. jquery蝴蝶飞舞网页动画js特效代码
  2. mp4格式的视频流传输下实现边下边播
  3. 【阿里巴巴Java编程规范学习 二】Java基本编程规约(下)
  4. linux 使用rtl8153 USB网卡
  5. 学习笔记:弱监督学习-valse青年会议
  6. 所用软件安装及环境配置
  7. 一文看懂P2P原理及UDP穿透
  8. oracle实验7 pl/sql编程基础
  9. 百度有趣的面试智力题
  10. 机械专业热门选题 论文+图纸+PPT