从python中的数独谜题中提取网格

时间:2016-05-22 17:11:36

标签: python opencv numpy

我目前正在使用python学习OpenCV,我正试图在此图像上绘制网格轮廓以从中提取数独谜题 enter image description here

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

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)

然而,发生的事情不是画在整个网格上,而是在右下方框上画画。 enter image description here

为什么会发生这种情况,我可以在代码中更改整个网格?

1 个答案:

答案 0 :(得分:3)

有一件事是错的,显然是:

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

应该是dilated.copy()而不是img.copy()。起初我认为这不是什么大问题,最大的轮廓应该仍然是网格边缘,但测试表明,如果你不扩大图像,那么最大的轮廓就是这个东西

enter image description here

这就是为什么它在if len(approx) == 4子句中被忽略了。