Pytesseract识别数独数字不准确,如何优化识别精度?
数独数字识别错误的修复方案
你编写的数独数字提取函数如下:
import cv2 import numpy as np import pytesseract # 补充原代码缺失的config配置(针对单数字识别优化) config = '--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789' def extract_sudoku(image_path): image = cv2.imread(image_path) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 0) thresholded = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) contours, _ = cv2.findContours(thresholded.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) sudoku_contour = None for contour in contours: area = cv2.contourArea(contour) if area > 5000: epsilon = 0.02 * cv2.arcLength(contour, True) approx = cv2.approxPolyDP(contour, epsilon, True) if len(approx) == 4: sudoku_contour = approx break if sudoku_contour is None: print("Sudoku grid not found.") return dest_corners = np.array([[0, 0], [0, 450], [450, 450], [450, 0]], dtype=np.float32) transform_matrix = cv2.getPerspectiveTransform(sudoku_contour.astype(np.float32), dest_corners) warped = cv2.warpPerspective(image, transform_matrix, (450, 450)) grid = np.zeros((9, 9), dtype=np.uint8) cell_size = warped.shape[0] // 9 for i in range(9): for j in range(9): cell = warped[i * cell_size:(i + 1) * cell_size, j * cell_size:(j + 1) * cell_size] digit = pytesseract.image_to_string(cell, config=config) if digit: # 处理识别结果中的空白字符 grid[i, j] = int(digit.strip()) return grid
测试第二张数独图片时,输出结果存在错误:
[[0 0 0 6 0 0 9 1 0] [8 6 9 0 0 0 0 0 0] [0 1 0 0 0 9 4 6 0] [0 7 6 0 0 0 8 0 0] [0 9 0 0 6 0 0 4 0] [0 0 7 9 1 0 3 0 0] [0 7 5 8 0 0 0 2 0] [0 0 0 0 0 0 9 7 1] [0 0 1 0 0 6 0 8 0]]
针对识别错误(尤其是数字7的识别问题),可以从以下几个方向优化:
一、优化单元格预处理
- 去除网格线干扰:透视变换后的图像可能残留细网格线,直接干扰识别。用形态学操作清除:
# 提取单元格后添加以下处理 cell_gray = cv2.cvtColor(cell, cv2.COLOR_BGR2GRAY) # 创建结构元素,分别去除横线和竖线 horizontal_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (cell_size//2, 1)) vertical_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (1, cell_size//2)) cell_gray = cv2.morphologyEx(cell_gray, cv2.MORPH_OPEN, horizontal_kernel, iterations=1) cell_gray = cv2.morphologyEx(cell_gray, cv2.MORPH_OPEN, vertical_kernel, iterations=1) # 自动阈值二值化 _, cell_thresh = cv2.threshold(cell_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) - 添加白边聚焦数字:数字靠近单元格边缘时,识别准确率会下降。给图像添加白边让数字处于中心区域:
cell_thresh = cv2.copyMakeBorder(cell_thresh, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=(255,255,255)) - 裁剪数字区域:只保留单元格中的数字部分,去掉空白区域:
contours, _ = cv2.findContours(cell_thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if contours: # 找到最大的轮廓(即数字) x, y, w, h = cv2.boundingRect(max(contours, key=cv2.contourArea)) cell_thresh = cell_thresh[y:y+h, x:x+w] # 缩放至标准尺寸,提升识别稳定性 cell_thresh = cv2.resize(cell_thresh, (32,32), interpolation=cv2.INTER_AREA)
二、调整Tesseract识别配置
- 锁定字符范围:确保只识别0-9的数字,避免干扰字符,配置参数用:
其中config = '--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789'--psm 10是单字符识别模式,完美匹配数独单元格的单数字场景。 - 替换优化训练集:如果默认训练数据对数字7识别效果差,可以下载针对印刷体数字优化的Tesseract训练集替换,或自己标注少量数独数字进行微调。
三、利用数独规则修正错误
数独有严格的规则:每行、每列、每个3x3小九宫格内数字不重复。可以用这个规则反向修正识别结果:
- 遍历网格,标记重复出现的数字为疑似错误,结合上下文重新验证。
- 对识别模糊的单元格先标记为0,用数独求解算法填充后,反向核对识别结果。
四、替换为自定义CNN识别模型
如果Tesseract始终无法解决数字7的识别问题,可以用基于MNIST数据集训练的CNN模型替代。MNIST包含大量手写/印刷体数字样本,训练后对数字的识别准确率极高,完全适配数独场景。
内容的提问来源于stack exchange,提问作者Krizsan 0596
相关产品推荐
相关产品推荐

