首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenCV -移除数独拼图中的网格线

OpenCV -移除数独拼图中的网格线
EN

Stack Overflow用户
提问于 2012-11-08 01:07:40
回答 1查看 3.5K关注 0票数 3

我正在编写一个Android应用程序,从图片中提取一个数独拼图。对于9x9 Sudoku网格中的每个单元格,我需要确定它是包含数字1到9中的一个还是空白。以下是我算法的大致笔画:

  • 自适应阈值拼图
  • 扩展以减少要考虑的等高线数
  • 找到拼图的轮廓,并将其扭曲成正方形。
  • 将正方形划分为81个相等的单元格;寻找至少20%的白色像素的单元格。
  • 找到最接近这些细胞中心的白色斑点,并得到它的边界矩形。
  • 使用字符识别(k近邻/Tesseract/等)在边界矩形内的图像部分。

虽然我可以用一个简单的填充物移除数独拼图的厚厚的外部边界,但内部的网格线并不是连续的,即使在膨胀之后,也不能轻易地移除。为了举例说明,下面是移除外部网格线之后的示例Sudoku:

Problem:有时,一个单元格中有足够多的网格线,超过20%的像素是白色的,所以下面是这样一个单元格的示例:

我考虑过打开图像以降低内部网格线的可见性。我可以使用Hough变换或 post中描述的方法来找到网格线,作为展开的前奏。然而,我看不到任何其他显著的好处,不扭曲,它应该是更安全和更容易只是完全删除网格线。

或者,我可以修改我的预处理,使内部网格线保持完整。目前我的预处理是:

代码语言:javascript
复制
    Imgproc.GaussianBlur(mat, mat, new Size(11,11), 0);
    Imgproc.adaptiveThreshold(mat, matBW, 255, 
        Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 5, 2);
    Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_CROSS, new Size(3, 3));
    Imgproc.dilate(matBW, matBW, kernel);

在阈值化之前,需要使用高斯模糊来降低噪声。扩张是为了确保外部网格线连接,但不足以重新连接内线。

如何在不影响图像其余部分的情况下,始终删除内部网格线?

非常感谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-08 03:40:41

如果您不想做一个适当的解曲,那么在digit_present测试中使用较小的单元可能是值得的。

假设左上角单元格有坐标(x1、y1、x2、y1)==(0、0、10、10)。您可以将一个新单元定义为(x1+k,y1+k,x2-k,y2-k),k=min(x2-x1,y2-y1)/4。

另一种可能有效的策略是在测试之前使用糜烂,这取决于网格线的厚度和数字的厚度。

最后,您可以将所有单元格提供给分类器,并使用它的置信指数(如果有的话);如果分类器的置信度太低,则可能不是一个数字。

如果所有这些方法都失败了,为了进行填充,无论如何您都必须获得网格线的扭曲,所以您最好进行反扭曲

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13280952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档