使用图像处理进行填字游戏数字化

sta*_*kit 5 python opencv image-processing

我是图像处理的新手。我需要将图像文件中的填字游戏网格转换为相应的二进制等价物,即输出应该是一个数组,其中 1 表示黑色方块,0 表示白色方块。此外,图像中的所有其他无关信息(如文本等)都将被忽略并仅数字化网格。

角点检测算法可以帮助我们检测填字游戏的角点,然后使用暴力对像素块进行相应的数字化吗?这是最好的方法吗?或者是否有任何有效的方法来完成该任务?我更喜欢基于 python 的解决方案。

填字游戏样本

Abi*_*n K 4

我认为你不需要在这里使用角点检测。只需使用轮廓本身,您就可以解决它(如果您的图像是直接的)。下面是打印上面图像的数组的代码。代码已注释:

import numpy as np
import cv2

img = cv2.imread('cross.jpg')    
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)    
ret, thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV)
thresh2 = cv2.bitwise_not(thresh)

contours,hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, 1)

max_area = -1

# find contours with maximum area
for cnt in contours:
    approx = cv2.approxPolyDP(cnt, 0.02*cv2.arcLength(cnt,True), True)
    if len(approx) == 4:
        if cv2.contourArea(cnt) > max_area:
            max_area = cv2.contourArea(cnt)
            max_cnt = cnt
            max_approx = approx

# cut the crossword region, and resize it to a standard size of 130x130
x,y,w,h = cv2.boundingRect(max_cnt)
cross_rect = thresh2[y:y+h, x:x+w]
cross_rect = cv2.resize(cross_rect,(130,130))

# you need to uncomment these lines if your image is rotated
#new_pts = np.float32([[0,0], [0,129],[129,129],[129,0]])
#old_pts = max_approx.reshape(4,2).astype('float32')
#M = cv2.getPerspectiveTransform(old_pts,new_pts)
#cross_rect = cv2.warpPerspective(thresh2,M,(130,130))

cross = np.zeros((13,13))

# select each box, if number of white pixels is more than 50, it is white box
for i in xrange(13):
    for j in xrange(13):
        box = cross_rect[i*10:(i+1)*10, j*10:(j+1)*10]
        if cv2.countNonZero(box) > 50:
            cross.itemset((i,j),1)

print cross
Run Code Online (Sandbox Code Playgroud)

对于上面的图像,我得到了这样的输出:

[[ 0.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  0.  1.  0.  1.  0.  1.  0.  0.  0.  1.  0.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  1.  1.]
 [ 1.  0.  1.  0.  1.  0.  1.  0.  1.  0.  1.  0.  1.]
 [ 1.  1.  1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  0.  0.  0.  1.  0.  1.  0.  1.  0.  1.  0.  1.]
 [ 1.  1.  1.  1.  0.  0.  0.  0.  0.  1.  1.  1.  1.]
 [ 1.  0.  1.  0.  1.  0.  1.  0.  1.  0.  0.  0.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  0.  1.  1.  1.  1.  1.]
 [ 1.  0.  1.  0.  1.  0.  1.  0.  1.  0.  1.  0.  1.]
 [ 1.  1.  1.  1.  0.  1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  0.  1.  0.  0.  0.  1.  0.  1.  0.  1.  0.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  0.]]
Run Code Online (Sandbox Code Playgroud)

我编写了一个代码来从图像中提取数独详细信息,并在下面的链接中提供了详细说明(教程不完整)。您可以参考他们了解更多详情:

http://opencvpython.blogspot.com/2012/06/sudoku-solver-part-1.html

http://opencvpython.blogspot.com/2012/06/sudoku-solver-part-2.html

http://opencvpython.blogspot.com/2012/06/some-common-questions.html