最近几天,我一直在尝试从图片中获取数独网格,而我一直在努力获取网格的较小正方形。
我正在处理下面的图片。我认为使用Canny滤镜处理图像会很好,但效果不佳,我无法获得每个正方形的每个轮廓。然后,我将自适应阈值,大津和经典阈值放入测试中,但是每次似乎都无法捕捉到每个小方块。
最终目标是获取包含数字的单元格,并使用pytorch识别数字,所以我真的很想对数字有一些清晰的印象,因此识别不会出错:)
会有人对如何实现这一目标有想法吗?
在此先多谢! :D
最佳答案
这是一个潜在的解决方案:
imutils.contours.sort_contours()
和top-to-bottom
和left-to-right
参数这是初始二进制图像(左),并过滤出数字+修复的网格线+倒置图像(右)
这是每个单元格迭代的可视化
每个单元格中检测到的数字
码
import cv2
from imutils import contours
import numpy as np
# Load image, grayscale, and adaptive threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV,57,5)
# Filter out all numbers and noise to isolate only boxes
cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 1000:
cv2.drawContours(thresh, [c], -1, (0,0,0), -1)
# Fix horizontal and vertical lines
vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1,5))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, vertical_kernel, iterations=9)
horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,1))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, horizontal_kernel, iterations=4)
# Sort by top to bottom and each row by left to right
invert = 255 - thresh
cnts = cv2.findContours(invert, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
(cnts, _) = contours.sort_contours(cnts, method="top-to-bottom")
sudoku_rows = []
row = []
for (i, c) in enumerate(cnts, 1):
area = cv2.contourArea(c)
if area < 50000:
row.append(c)
if i % 9 == 0:
(cnts, _) = contours.sort_contours(row, method="left-to-right")
sudoku_rows.append(cnts)
row = []
# Iterate through each box
for row in sudoku_rows:
for c in row:
mask = np.zeros(image.shape, dtype=np.uint8)
cv2.drawContours(mask, [c], -1, (255,255,255), -1)
result = cv2.bitwise_and(image, mask)
result[mask==0] = 255
cv2.imshow('result', result)
cv2.waitKey(175)
cv2.imshow('thresh', thresh)
cv2.imshow('invert', invert)
cv2.waitKey()
注意:排序思路是根据Rubrik cube solver color extraction中以前的旧答案改编而成的。
关于python - 如何使用OpenCV获取数独网格的单元格?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59182827/