搜索
Hi~登录注册
查看: 881|回复: 0

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

[复制链接]

0

主题

0

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2021-8-7 10:26:15 | 显示全部楼层 |阅读模式
目录


  • 1、将棋盘分割成19x19的小方格
  • 2、根据像素占比识别是否是黑色棋子
  • 3、根据像素占比识别是否是白色棋子
  • 4、将棋盘棋子位置通过列表表示
  • 完备代码如下:
这一篇主要实现定位棋子位置及识别棋子颜色。
围棋棋盘原图如下:



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



如今根据新图,进行棋子位置的定位

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

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



若想将棋盘分割成19x19的小方格,需要知道以下几个参数。
  1. small_length=38  #每个小格宽高qizi_zhijing=38#棋子直径zuoshangjiao=20#棋盘四周的宽度
复制代码
这些可以使用imagewathch(VS下opencv的插件)工具,方便的知道,这个工具可以实时检察图像的宽高,某个位置的像素值。这个工具的使用可以看我另外一篇文章:opencv用VS2013调试时用Image Watch插件检察图片,代替一堆数据,直观很多。
下面是将原图分割成19X19小方格的代码
  1. 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、根据像素占比识别是否是黑色棋子





上面三种图像是我们分割成小方格后的三种主要形态,分别代表黑色棋子,白色棋子以及无棋子。此中黑色棋子最好查找,我们将图像进行灰度化——二值化后,通过统计黑色像素占比高出一定数值,就能知道该处是否有黑色棋子。
这里我将统计黑色占比的代码,封装成了一个函数,如下;
  1. """  "********************************************************************************************函数功能 :统计二值化图片黑色像素点百分比*输入参数 :输入裁剪后图像,*返 回 值 :返回黑色像素点占比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、根据像素占比识别是否是白色棋子

同样的,我们可以统计像素中白色占比,来进行识别该位置是否是白色棋子,但是这里需要注意一个问题,如果按照上面黑色棋子识别方法进行灰度化、二值化会造成白色棋子和无棋子分辨不了,二者都有大面积的白色,因此这里需要调整二值化的阈值,分开无棋子和白色棋子的图像。
封装好的代码如下:
  1. """  "********************************************************************************************函数功能 :统计二值化图片白色像素点百分比*输入参数 :输入裁剪后图像,*返 回 值 :返回白色像素点占比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:代表黑色
代码如下:
  1. list = [[0 for i in range(19)] for j in range(19)]
复制代码
当为黑色棋子时:
  1. list[hang][lie]=2#黑色#print("当前棋子为黑色")print("第", i, "行,第", j, "列棋子为黑色:", i, j)
复制代码
当为白色棋子时:
  1. list[hang][lie] = 1  # 白色#print("当前棋子为白色")print("第", i, "行,第", j, "列棋子为白色:", i, j)
复制代码
效果图如下:



完备代码如下:
  1. from PIL import ImageGrabimport numpy as npimport cv2from glob import globimport 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 而余数是 0    return modChardef 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  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定位棋子位置及识别棋子颜色的文章就介绍到这了,更多相关python定位棋子位置及识别棋子颜色内容请搜刮脚本之家从前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

游客
回复
您需要登录后才可以回帖 登录 | 点我注册

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