Sudoku Flow

测量数独照片识别器带给我们的经验

更新于 2026年11月5日

怎样才算读对

只有81个格全部正确,一道题才算读对:错一个数字就成了另一道题。所以我们按整道题计数,而不是按格计数。两种计法可能讲出截然不同的结论,本页就是例子:在印刷题照片上,识别器现在能读对98.9%的格,但整题读对的比例几乎没变,因为大多数错格集中在少数几张难认的图片里。

我们还统计最危险的一类错误:读错了却仍然恰好只有一个解的题目。真正的数独只有一个解,所以读出无解或多解的结果会立即被发现。读错但只有一个解的题目看起来没有问题,因此求解器会标出每一个它没有把握的格,并请你在求解前将这些格与你的题目核对。

只有200张图片时,结果的精确度是有限的。对于主要结果,我们给出95%区间(Wilson 区间):200张图片中的89.5%意味着真实比例很可能在84.5%到93.0%之间。

我们用来测试的图片

我们从两个公开数据集入手。Lexski 的 Sudoku Image Recognition 数据集(CC0)有1400张图片,大多是网上分享的截图和照片:各种风格的应用、深色主题、铅笔标记、在纸上解到一半的题目。Baptiste Wicht 和 Jean Hennebert 的数据集(CC BY 4.0)收录了用手机拍摄的报纸数独,其中一些已用笔手工填完。

在做任何改动之前,我们先留出了三个测试集:200张 Lexski 图片、40张报纸照片和40道手工填完的报纸题目。工作期间我们既没有用它们训练,也没有查看它们。所有决定都基于另外200张 Lexski 图片(即调优集)作出,测试集只在最后读取一次。

起点

10月31日的第一个版本完全读对了200张 Lexski 图片中的101张、40张报纸照片中的34张,40道填完的题目则一道也没读对。它的大部分问题出在识别数字之前。它把最大的近似正方形墨迹当作盘面,而在截图上,这个形状常常把页眉或数字键盘也包了进去,深色主题中细细的灰色线条则完全被漏掉。在调优集的200张图片中,它只有118张把网格定位在了正确的位置。

我们一步步改了什么

每一行是一项改动,数字表示改动后200张调优图片中被完全读对的张数。最后三行属于第二轮。

改动完全读对的调优图片(共200张)
第一个版本,10月31日99
按线条寻找网格:每个方向十条等距线129
并排评判网格;尝试平移一格136
利用淡细线寻找网格138
完整切出各格;用真实格学习数字161
小型网络标出盘面位置162
沿书页弯曲处跟踪线条163
更好的数字网络,铅笔标记单独成类173
三个数字网络取平均177
谨慎的唯一解规则;填完的盘面整体读取177
第二轮:全尺寸照片先减半再缩小178
第二轮:短而淡的墨迹视为铅笔标记179
第二轮:侧转照片由全部三个网络判断179

大部分提升来自三项改动。现在按线条来寻找网格:每一个对盘面位置的猜测都会被对齐到每个方向十条等距的线上,再并排比较评判,一个专门标出盘面位置的小型网络也参与投票。每个格都被完整切出,这样铅笔标记在角落里仍然显得很小,深色方块上的浅色数字看起来就像纸上的墨迹。数字网络改为从 Lexski 训练图片中切出的真实格来学习,并把铅笔标记单独作为一类。现在由三个分开训练的小型网络读取每个格,并对它们的答案取平均,因为它们出错的格各不相同。

填完的题目会得到额外帮助。当盘面上有79个或更多数字时,识别器会寻找最可能的完整网格,使每一行、每一列和每一宫都包含1到9。逐格读取时,40道手写测试题中只有7道被完全读对;作为填完的数独整体读取时,40道全部读对。

第二轮又加入了三项较小的改动。全尺寸的手机照片在缩小之前会先逐级减半,这样细线和铅笔笔画会被平均进去,而不会被跳过。如果某个格中的墨迹比盘面上有把握的数字既短得多、又淡得多,就会被视为可能的铅笔标记。侧转照片的旋转方向改由全部三个网络共同判断,而不是只由一个网络判断。

一张带铅笔标记和彩色数字的深色主题数独截图:盘面已被拉正,线条交点以绿色标出;81个格以小图显示;读出的数字以蓝色显示,不含铅笔标记
一张我们生成的深色主题截图:拉正后的盘面及其找到的线条交点;网络所看到的81个格;以及读取结果。铅笔标记被排除在外。

没有帮助的尝试

这些我们也在调优集上测量过,最终没有采用:

  • 更大的数字网络:用59,000个权重代替42,000个,只多读对了一张调优图片,在浏览器中却慢了3.8倍。
  • 3000张带铅笔标记和深色主题的生成应用截图:用与不用,分数都一样。
  • 读取彩色而非灰度图像,使红笔与黑色墨迹一样深:多读对两张调优图片,但手写识别变差了。
  • 把训练用的数字扭曲得更像手写:手写识别变差了。
  • 让唯一解规则改动更多的格:读对的题目更多了,但读错却只有一个解的危险题目也更多了。
  • 用新数据重新训练这三个网络,或改用四个或六个网络:差异在噪声范围内,所以沿用了最初的网络。
  • 对于被画面边框截断的盘面,把图片边缘当作盘面边缘:读错的图片和新读对的一样多。

首批测试集上的结果

各测试集中被完全读对的题目数,分别为第一个版本和当前识别器的结果:

测试集10月31日现在
网上分享的截图和照片(Lexski)图片数: 20010150.5%17989.5%
报纸照片(Wicht 和 Hennebert)图片数: 403485.0%40100.0%
手工填完的报纸题目(Wicht 和 Hennebert)图片数: 4000.0%40100.0%

在 Lexski 图片上,识别器从50.5%提升到89.5%(84.5%到93.0%),读错却只有一个解的题目从7道降到4道。这4道中有3道,多出的那个数字正是该格应填的数字,因此题目仍会得出正确的解;第4道是一个印刷清晰的1,而数据集把该格标为空格。179道中有177道在第一轮结束时就已读对。最后两道是在第二轮、我们研究过失败案例之后才读对的,因此这个测试集已不再是未经接触的。

40道全对听起来很完美,但40张图片只能说明真实比例高于约91%。还有一项我们本该先做的检查:40张报纸测试照片中有4张也出现在该数据集的训练集中,其中两张逐像素相同。去掉这4张,结果是36道中36道读对。

新测试:任何版本都没见过的200张照片

那时首批测试集已经被读取过,失败案例也已被研究过,所以它们已无法告诉我们识别器在从未见过的图片上表现如何。我们在 Hugging Face、Kaggle、GitHub、Zenodo、Figshare 和 AIcrowd 上搜寻了更多带标注的数独照片。大多数数据集是生成的盘面、单个数字,或是 Wicht 照片的副本。有三个 GitHub 合集包含真实的带标注照片,全部是印刷题目:一本公开题集的100张照片(NatalijaPetric/SudokuDataset)、80张以报纸为主的照片(mineshpatel1/sudoku-solver,已剔除49张本身就是 Wicht 照片的图片和一张副本),以及来自布加勒斯特大学一门计算机视觉课程项目的20张印刷题纸(danielsociu/SudokuRecognition)。

这三个合集都没有注明许可,所以我们只用它们来测量:从不用于训练,也不在此处展示。图片清单在做任何改动之前就已确定并保存,依据文件哈希和标注按规则选出,而且直到第二轮最后一项改动完成之前都没有打开过这些图片。之后,识别器的每个版本各读取它们一次。表中统计的是被完全读对的题目数。

来源10月31日第一轮现在
一本公开题集(NatalijaPetric)照片数: 1007979.0%7676.0%7878.0%
以报纸为主(mineshpatel1)照片数: 806581.3%6885.0%6986.3%
印刷题纸(布加勒斯特大学课程)照片数: 2020100.0%20100.0%20100.0%
全部200张照片数: 20016482.0%16482.0%16783.5%

在识别器从未见过的印刷题目上,两轮的全部工作带来的变化不大。第一个版本完全读对了其中的82.0%,当前版本为83.5%(77.7%到88.0%):新读对14道,又丢了11道。真正改善的是格:读对的格从94.2%提高到98.9%,网格在每张照片中都被找到,而不是200张中的195张。读错却只有一个解的题目:之前5道,现在6道。

这些退步有明确的原因。为了读取铅笔标记和深色主题,现在每个格都被完整切出,淡淡的墨迹也会计入。在薄薄的报纸上,背面的内容会透过来,既淡又是镜像的,新识别器会把这些阴影读成数字;第一个版本只看格中最大的墨迹形状,从来看不到它们。在卷曲的书页上,盘面的外框线或宫线可能落进格内,被读成1。

有两处未读对其实是标注错误:照片上是3和9,标注却写作9和8;照片上是4,标注却写作2。按正确标注计算,当前识别器的读对率为84.5%。

仍会出错的地方

200张新照片中有33张没有被完全读对。其中22张是那本公开题集的书页:靠近书脊处,页面的卷曲超出了识别器能跟踪的程度,于是线条落进格内被读成1,或者角上的格在切割时跨过了一条线。7张是背面透印的报纸。其余是一张带摩尔纹的屏幕照片、一个被读成1的盘面边缘,以及那两处标注错误。

200张 Lexski 图片中有21张没有被完全读对:铅笔标记被读成数字,包括擦掉的铅笔留下淡淡数字痕迹的情况(7张);多出一个数字,大多是单独一个铅笔标记被当成填入的数字(5张);网格位置错误或未找到,出现在格与格之间没有线条的应用主题或手绘网格上(5张);不常见的方块样式和颜色(4张)。

为什么没到97%,以及下一步

所有处理都在你的浏览器中运行:一个224 KB的模型和约850行 JavaScript,在笔记本电脑上每张照片的处理时间中位数约为300毫秒,在把处理器降速四倍(相当于一部慢速手机)时约为1.2秒。在这个预算内,更大的网络并没有帮助。剩下的是长尾问题:卷曲的书页、透印、铅笔标记和不常见的应用风格。我们找到的每个公开带标注数据集现在都已被使用或看过,所以下一轮需要我们自己拍摄并标注的照片,并在这些照片上修复和测量淡墨迹与书页卷曲的问题。

如何获得最佳扫描效果

  • 将手机正对题目上方,让整个网格都在画面内。
  • 把书或报纸压平:在印刷题目上,大多数识别失败都是书页卷曲造成的。
  • 对于薄报纸,在页面背后垫一张白纸,以免背面内容透过来。
  • 在题目上写铅笔标记之前先扫描。
  • 求解之前,将求解器标出的格与你的题目核对。

数据与来源

试用求解器 →

数独应用图标

想玩更多这样的数独?

我们还开发了一款适用于 iPhone、iPad、Mac 和 Android 的数独应用。应用完全没有广告,可以离线使用。你请求提示时,它会展示解题技巧,而不是直接填入一个数字。

Sudoku Flow 由 Rubigo Games 制作,他们也是本站推荐的数独应用的开发者。