从python中的数独谜题中提取网格 [英] Extracting grid from a sudoku puzzle in python

查看:72
本文介绍了从python中的数独谜题中提取网格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在 python 中学习 OpenCV,我试图在这个图像上绘制网格的轮廓以从中提取数独谜题

I am currently learning OpenCV in python, and I am trying to draw over the contour of the grid on this image to extract the sudoku puzzle from it

这是我为这个特定问题编写的代码:

This is the code I wrote for this specific problem:

CONST_IMAGE_PATH = "sudoku-original.jpg"
CONST_COEFF = 0.02
def main():
   originalImage = cv2.imread(CONST_IMAGE_PATH)
   img = cv2.imread(CONST_IMAGE_PATH,0)
   img = cv2.medianBlur(img,5)
   img = cv2.adaptiveThreshold(img , 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY,11,2)
   img = cv2.bitwise_not(img,img)
   print "thresholding the image"
   cv2.imshow("Thresholded", img)
   kernel = np.empty((3,3),'uint8')
   kernel[0][0] = 0
   kernel[0][1] = 1
   kernel[0][2] = 0
   kernel[1][0] = 1
   kernel[1][1] = 1
   kernel[1][2] = 1
   kernel[2][0] = 0
   kernel[2][1] = 1
   kernel[2][2] = 0
   dilated = cv2.dilate(img,kernel)
   cv2.imshow("Dilated", dilated)
   print "detecting the grid"
   (contours, _) = cv2.findContours(img.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
   contours = sorted(contours, key = cv2.contourArea , reverse = True)
   screenCnt = None


   for contour in contours: 
        perimeter = cv2.arcLength(contour,True)
        approx = cv2.approxPolyDP(contour, CONST_COEFF*perimeter , True)
        if len(approx) == 4: 
            if perimeter > maxPerimeter: 
                maxPerimeter = perimeter
                screenCnt = approx


   cv2.drawContours(originalImage , [screenCnt], -1, (0,255,0), 3)
   cv2.imshow("SudokuPuzzle", originalImage)
   cv2.waitKey(0)

然而发生的事情不是在整个网格上绘制,而是在右下角的框上绘制.

However what happens is instead of drawing over the whole grid it just draws over the lower right box.

为什么会发生这种情况,我可以在代码中更改哪些内容来绘制整个网格?

Why is this happening and what can I change in my code to draw over the whole grid ?

推荐答案

显然是错误的一件事:

(contours, _) = cv2.findContours(dilated.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

应该是 dilated.copy() 而不是 img.copy() .一开始我以为没什么大不了的,最大的轮廓应该还是网格边缘,但是测试表明,如果你不扩大图像,那么最大的轮廓就是这个东西

Should be dilated.copy() instead of img.copy() . At first I thought that it wasn't a big deal and the biggest contour should still be the grids edge, but testing shows that if you don't dilate the image then the biggest contour is this thing

这就是它在 if len(approx) == 4 子句中被忽略的原因.

And this is why it was ignored in the if len(approx) == 4 clause.

这篇关于从python中的数独谜题中提取网格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆