You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 22:35:00