目次
- 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的列表来存储棋子,列表中:复制代码 代码如下:- 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 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定位棋子位置及辨认棋子颜色内容请搜刮脚本之家从前的文章或继续浏览下面的相关文章盼望各人以后多多支持脚本之家! |