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

Python OCR识别数独图像为数字网格 现有代码运行结果不符预期

数独OCR识别代码修复方案

你现有代码无法输出预期的结构化数独网格,核心问题如下:

  • 轮廓分组逻辑错误:靠累计9个轮廓就归为一行的逻辑完全不可靠,findContours会返回数独外框、残留噪点等多余轮廓,分组必然错位。
  • 缺少透视矫正环节:测试样例中的数独存在倾斜变形,直接在原图上分割单元格会出现行列不对齐、大小不一的问题。
  • 无OCR识别环节:原有代码仅实现了单元格弹窗预览,没有数字识别逻辑,无法输出结构化数字结果。
  • 形态学参数硬编码:固定的核大小、迭代次数对样例图适配差,修复网格线时要么残留数字笔画,要么糊住单元格区域。

测试用数独样例图如下:
数独样例图像


修复后实现逻辑

调整流程后稳定性大幅提升,不需要手动调大量轮廓筛选参数:

  1. 预处理后定位数独外边框的四边形轮廓
  2. 通过透视变换将倾斜的数独矫正为450450的标准正方形,每个单元格固定为5050像素
  3. 直接按固定尺寸切分81个单元格,省略不稳定的轮廓排序步骤
  4. 对每个单元格做笔画占比判断,空单元格填0,有数字的单元格调用Tesseract做单字符OCR识别
  5. 最终输出9*9的结构化数独网格

可运行代码

先安装依赖:
pip install opencv-python imutils numpy pytesseract

注意:除了Python包,还需要安装Tesseract OCR引擎本体,Windows用户如果没把Tesseract加入系统环境变量,需要在代码中指定tesseract_cmd的本地路径。

import cv2
import numpy as np
import pytesseract
from imutils.perspective import four_point_transform

# Windows用户未配置环境变量时取消注释,修改为自己的Tesseract安装路径
# pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

# 读取并预处理图像
image = cv2.imread('Sample.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (7, 7), 0)
thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2)

# 定位数独外边框(最大的四边形轮廓)
cnts, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)
sudoku_contour = None
for c in cnts:
    perimeter = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.02 * perimeter, True)
    if len(approx) == 4:
        sudoku_contour = approx
        break

# 透视矫正为450*450的标准正方形
warped = four_point_transform(image, sudoku_contour.reshape(4, 2))
warped_gray = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
warped_thresh = cv2.adaptiveThreshold(warped_gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 21, 5)

# 切分单元格并识别数字
sudoku_grid = []
cell_size = 50  # 450 / 9 = 50,每个单元格固定50*50像素
for row_idx in range(9):
    current_row = []
    for col_idx in range(9):
        # 裁掉单元格边缘5像素,避免把网格线纳入识别区域
        cell = warped_thresh[
            row_idx*cell_size + 5 : (row_idx+1)*cell_size - 5,
            col_idx*cell_size + 5 : (col_idx+1)*cell_size - 5
        ]
        # 统计白色像素(数字笔画)占比,占比过低判定为空格
        non_zero_ratio = cv2.countNonZero(cell) / (cell.shape[0] * cell.shape[1])
        if non_zero_ratio < 0.05:
            current_row.append(0)
            continue
        # 配置Tesseract为单字符识别模式,仅识别1-9数字
        ocr_config = '--psm 10 -c tessedit_char_whitelist=123456789'
        recognize_res = pytesseract.image_to_string(cell, config=ocr_config).strip()
        current_row.append(int(recognize_res) if recognize_res.isdigit() else 0)
    sudoku_grid.append(current_row)

# 输出结构化结果
print("识别得到的数独网格(0代表空格):")
for row in sudoku_grid:
    print(row)

# 预览矫正后的数独图像
cv2.imshow("Warped Sudoku", warped)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行说明
  • 将数独样例图命名为Sample.jpg放在脚本同目录下运行
  • 运行后控制台会直接打印9*9的数独列表,0对应该位置没有数字
  • 如果识别准确率不够,可以调整二值化参数,或者对单元格做额外的腐蚀/膨胀预处理优化数字显示

内容的提问来源于stack exchange,提问作者YasserKhalil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 03:24:18