这段代码在运行不正常
(注:功能为,任意给定一张带有棋子的象棋棋盘图像,请识别棋盘中的棋子是什么颜色、是什么棋子及相应的坐标是多少)
代码如下,怎么修改呀
# 图片二值化
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
from PIL import Image
img = Image.open('C:/Users/ZengFH/Desktop/2.png')
# 模式L”为灰色图像,它的每个像素用8个bit表示,0表示黑,255表示白,其他数字表示不同的灰度。
Img = img.convert('L')
plt.subplot(1,2,1),plt.imshow(Img)
#Img.save("test1.jpg")
# 自定义灰度界限,大于这个值为黑色,小于这个值为白色
threshold = 200
table = []
for i in range(256):
if i < threshold:
table.append(0)
else:
table.append(1)
# 图片二值化
photo = Img.point(table, '1')
plt.subplot(1,2,2),plt.imshow(photo)
#photo.save("test2.jpg")
plt.show()
#竖线以x坐标进行排序
sx = sorted(sx, key=lambda x: x[0])
#直线以Y坐标进行排序
zx = sorted(zx, key=lambda x: x[2])
#对于竖线进行过滤
sxFilter=[]
if len(sx)>0:
sxFilter.append(sx[0])
tempsx = sx[0]
# 从第二个开始提取
for i in range(len(sx))[1:]:
# 这是竖线的x坐标值间距要大于10
if (sx[i][0] - tempsx[0]) > 10:
tempsx = sx[i]
sxFilter.append(sx[i])
#棋子识别
#根据轮廓获取最小矩形边框
x, y, w, h = cv.boundingRect(cnts[i])
#轮廓获取得到的是上面图,下面的会有一些干扰项
#通过拿到边框的坐标,然后根据宽高的比例进行过滤,我这里根据宽高的差
x, y, w, h = cv.boundingRect(cnts[i])
print(x,y,w,h)
if(abs(w-h)>20):
continue
#识别之前要做的是边框排序,根据上面拿到的轮廓数据
#这里按照Y,X递增的方式进行
questionCnts2 = sorted(questionCnts.copy(), key=lambda x: (x[1],x[0]))
#排序我这里遇到了问题,因为每行棋子识别的时候,坐标有些高低差导致排序结果可能跟棋盘显示有些出入
#其实识别之后可以根据上一篇文章得到的棋盘表格一步一步的得到棋子,我这里没做
#我用了个笨办法处理的 就是每行的Y轴根据个大致范围固定了
if abs(y - 19) < 20:
y = 19
if abs(y - 88) < 20:
y = 88
#拿到了边框后我们可以根据边框截取抠图了
x, y, w, h = questionCnts2[i]
# print(x, y, w, h)
im = img[y:y + h, x:x + w]
#抠图后然后根据模板匹配算法得到最匹配的模板
result = cv.matchTemplate(cv.resize(old_img,None,fx=0.8, fy=0.8, interpolation = cv.INTER_CUBIC),tempImg,cv.TM_CCOEFF)
(_, score, _, _) = cv.minMaxLoc(result)
if check_score == 0 or score > check_score:
#最大得分项
check_score = score
#最大得分项的文件名,然后根据字典获取棋子名称
#字典
check_img = fileName
#棋谱保存
#第一排的棋子高度大概就在19左右
if abs(y - 19) < 20:
y = 19
chess_array=[[] for i in range(10)]
if(len(sxFilter)==9 and len(zxFilter)==10):
#竖线 直线
print("---------------------")
for i in range(len(zxFilter)):
for j in range(len(sxFilter)):
#直线的坐标
x1,x2,y1,y2=zxFilter[i]
#竖线坐标
x3,x4,y3,y4=sxFilter[j]
check = False
print(zxFilter[i],"-",sxFilter[j],i,j)
for k in range(len(questionCnts)):
x, y, w, h=questionCnts[k]
#获取中心坐标
centre_x=x+w/2
centre_y=y+h/2
#范围之内匹配成功
print(centre_x,"-",centre_y)
#这里写的匹配误差在25之内
if(abs(centre_x-x3)<25 and abs(centre_y-y1)<25):
print("命中!")
check=True
#抠图
im = img[y:y + h, x:x + w]
#识别
orc = get_match(im)
if orc is not None:
chess_array[i].append(orc)
else:
print("未识别...")
if not check:
chess_array[i].append("空空空")
else:
print("识别出错了!")
你这明显代码复制别人的都串位了,理论上下面的代码都应该放在上面那个for I in range循环的下面,你可以再去看看源代码页面那一块儿。
你这槽点巨多。。。首先opencv不支持中文路径,你图片读取就有问题了。其次,你这路径要么使用/,要么使用\\。还有你这缩进错误了,导致后面全部乱掉了