简体   繁体   English

在python中从数独难题中提取网格

[英]Extracting grid from a sudoku puzzle in python

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 我目前正在使用python学习OpenCV,并且尝试在此图像上绘制网格的轮廓以从中提取数独难题 在此处输入图片说明

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 ? 为什么会发生这种情况,我可以在代码中进行哪些更改以绘制整个网格?

The one thing that was wrong, apparently: 一件错误的事情,显然是:

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

Should be dilated.copy() instead of img.copy() . 应该是dilated.copy()而不是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 起初我以为这没什么大不了的,最大轮廓应该仍然是网格边缘,但是测试表明,如果不对图像进行扩张,那么最大轮廓就是这个东西

在此处输入图片说明

And this is why it was ignored in the if len(approx) == 4 clause. 这就是为什么它在if len(approx) == 4子句中被忽略的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM