如何获得数独网格的4点数独求解器项目

问题描述

我当时在做数独求解器的一个项目,结果被卡住了。 首先,我必须从图像中提取网格。 我正在测试的图像是: the Sudoku image on which i was just testing my code!

为了从图像中获得最大的网格,我应用了绘制轮廓,cannyedge检测和轮廓线。 然后应用粗线,然后我得到了所有线条。

这是代码: 导入cv2 将numpy导入为np def get_sudo_rid(name,size):

img=name
original=img.copy()
img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
graymain=cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
ath=cv2.adaptiveThreshold(graymain,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY_INV,39,10)

contours,hierarchy=cv2.findContours(ath,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
area=[]
maxarea=0
cnt=contours[0]
for i in contours:
    if cv2.contourArea(i)>maxarea:
        cnt=i
        maxarea=cv2.contourArea(i)
blank= np.zeros(img.shape,np.uint8)

image=cv2.drawContours(blank,[cnt],-1,(255,255),5)
edges=cv2.Canny(image,40,150)
lines=cv2.HoughLines(edges,1,np.pi/180,100)
print(len(lines))
print(lines)
createhor=[]
createver=[]
created=[]
anglediff= 800
rhodiff= 800
flag=0
count = 2
for line in lines:
    for(rho,theta) in line:
        flag=0
        for (rho1,theta1) in created:
            if(abs(rho-rho1) < rhodiff and abs(theta-theta1)<anglediff):
                flag=1
        if(flag==0):
            a=np.cos(theta)
            b=np.sin(theta)
            xo=a*rho
            yo=b*rho
            x1=int( xo + 1000*(-b))
            y1=int( yo + 1000*(a))
            x2=int( xo + 1000*(-b))
            y2=int( yo +1000*(a))
            print(x1,x2,y1,y2)

由此我得到11分: -957 -957 532 532, -956 -956 539 539, -1002 -1002 115115, -1002 -1002 108108, 116116 -1004 -1004, 435435 -1015 -1015, 428428 -1015 -1015, 123123 -1004 -1004, -1000 -1000 138 138, -946 -946 560 560, -1000 -1000 131131,

之后,为了获得水平线和垂直线,我应用了基本的if-else条件: 但这不起作用:

d=np.linalg.norm(np.array((x1,0))-np.array((x2,y2,0)))
            cv2.line(img,(x1,y1),(x2,y2),(0,0),2)

            m=abs(1/np.tan(theta))
            if(m<1):
                createhor.append((rho,theta))
            else:
                createver.append((rho,theta))
print(len(createhor))
print(len(createver))      
points=[]
for (rho,theta) in createhor:
    for (rho1,theta1) in createver:
        if(rho,theta)!=(rho1,theta1):
            a=[[np.cos(theta),np.sin(theta)],[np.cos(theta1),np.sin(theta1)]]
            b=[rho,rho1]
            cos=np.linalg.solve(a,b)
            if list(cos) not in points:
                points.append(list(cos))
                #print(a,b)
print(len(points))
points.sort()

输出-createhor- 7,
createver-4

我试图在图像中添加数独的点列表中的四个点: 但我没有得到4分,总分是:28

我什至试图消除那些与anglediff和rhoddiff大于10的线,但是即使在那一点之后,点的长度仍然保持28

您能帮我得到sudoky网格的4个角点吗?

解决方法

这是使用cv2.findContourscv2.approxPolyDP并最终进行透视变换的一种方法:

import cv2
from imutils.perspective import four_point_transform

image = cv2.imread('test_sudoku.jpg')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)[:,:,2]
gray = cv2.GaussianBlur(gray,(3,3),0)
edged = cv2.Canny(gray,50,200)

cnts = cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts,key = cv2.contourArea,reverse = True)[:1]

for c in cnts:
    peri = cv2.arcLength(c,True)
    approx = cv2.approxPolyDP(c,0.02 * peri,True)
    if len(approx) == 4:
        screenCnt = approx
        break

warped = four_point_transform(image,screenCnt.reshape(4,2))

cv2.imshow("Warped",warped)
cv2.waitKey(0)

输出扭曲网格:

enter image description here

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...