【发布时间】:2012-10-28 04:07:43
【问题描述】:
我正在编写一个 Android 应用程序来从图片中提取数独谜题。对于 9x9 数独网格中的每个单元格,我需要确定它是否包含数字 1 到 9 之一或是否为空白。以下是我算法的大致思路:
- 自适应阈值谜题
- 扩张以减少要考虑的轮廓数量
- 找到拼图的轮廓并将其变形为正方形
- 将正方形分成81个相等的单元格;寻找具有至少 20% 白色像素的单元格
- 找到最靠近这些单元格中心的白色斑点并获取其边界矩形
- 对边界矩形内的图像部分使用字符识别(k-nearest neighbours/Tesseract/etc.)
虽然我可以使用简单的填充来移除数独谜题的粗外边框,但内部网格线不是连续的,即使在膨胀之后也是如此,并且不能那么容易地移除。为了便于说明,以下是移除外部网格线后的示例数独:
问题:有时,一个单元格中有足够多的网格线,超过 20% 的像素是白色的,所以 我误认为该单元格中有一个数字.以下是此类单元格的示例:
我考虑过取消扭曲图像以降低内部网格线的可见性。我可以使用霍夫变换或this 帖子中描述的方法来查找网格线作为展开的前奏。但是,我没有看到展开变形的任何其他显着好处,并且完全删除网格线应该既安全又容易。
或者,我可以修改我的预处理,以便内部网格线保持不变。目前我的预处理是:
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);
高斯模糊对于降低阈值之前的噪声是必要的。膨胀是为了确保外部网格线已连接,但不足以重新连接内部线。
如何在不影响图像其余部分的情况下始终如一地移除内部网格线?
非常感谢。
【问题讨论】:
-
我可能遗漏了一些明显的东西,但是为什么您需要删除网格线?如果你已经把识别出的数字排列成一个网格,你就不能重新合成图像吗?
-
我的目的是找出数独网格的每个单元格中有哪些数字。为此,我需要识别哪些单元格中没有任何内容。如果网格线仍然存在,则某些单元格中会出现一些东西,因为超过 20% 的像素可能是白色的。
-
@Hammer 我在我的问题中提到了那个帖子 :) 所以应该让他们的链接更暗。
标签: image-processing opencv sudoku