我正在编写一个Android应用程序,从图片中提取数独谜题。对于9x9的数独网格中的每个单元格,我需要确定它是否包含数字1到9或为空。以下是我的算法的概要:
- 自适应阈值化拼图 - 膨胀以减少要考虑的轮廓数量 - 查找拼图的轮廓并将其扭曲成正方形 - 将正方形分成81个相等的单元格;查找至少有20%白色像素的单元格 - 找到最靠近这些单元格中心的白色斑点,并获取其边界矩形 - 在边框矩形内部的图像部分上使用字符识别(k最近邻/Tesseract等)
尽管我可以使用简单的洪水填充方法去除数独拼图的粗外边框,但即使进行膨胀处理后,内部网格线也不连续,不能轻易地去除。以下是去除外部网格线后的样例数独图片:
有时候,单元格中的网格线数量足够多,使得其中超过20%的像素为白色,因此我会误检测这个单元格为其中有一个数字。这里是这样一个单元格的示例:
我考虑过对图像进行变形以减少内部网格线的可见性。我可以使用Hough变换或这篇文章中描述的方法来找到网格线,作为变形的前奏。但是,我没有看到任何其他重要的变形好处,而且完全去除网格线应该更安全和更容易。
或者,我可以修改我的预处理,使内部网格线保持不变。目前我的预处理为:
高斯模糊在阈值处理之前是必要的,以减少噪点。膨胀操作可以确保外部网格线连接在一起,但不足以重新连接内部线条。
如何稳定地去除内部网格线,而不影响图像的其他部分?
非常感谢。
- 自适应阈值化拼图 - 膨胀以减少要考虑的轮廓数量 - 查找拼图的轮廓并将其扭曲成正方形 - 将正方形分成81个相等的单元格;查找至少有20%白色像素的单元格 - 找到最靠近这些单元格中心的白色斑点,并获取其边界矩形 - 在边框矩形内部的图像部分上使用字符识别(k最近邻/Tesseract等)
尽管我可以使用简单的洪水填充方法去除数独拼图的粗外边框,但即使进行膨胀处理后,内部网格线也不连续,不能轻易地去除。以下是去除外部网格线后的样例数独图片:
有时候,单元格中的网格线数量足够多,使得其中超过20%的像素为白色,因此我会误检测这个单元格为其中有一个数字。这里是这样一个单元格的示例:
我考虑过对图像进行变形以减少内部网格线的可见性。我可以使用Hough变换或这篇文章中描述的方法来找到网格线,作为变形的前奏。但是,我没有看到任何其他重要的变形好处,而且完全去除网格线应该更安全和更容易。
或者,我可以修改我的预处理,使内部网格线保持不变。目前我的预处理为:
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);
高斯模糊在阈值处理之前是必要的,以减少噪点。膨胀操作可以确保外部网格线连接在一起,但不足以重新连接内部线条。
如何稳定地去除内部网格线,而不影响图像的其他部分?
非常感谢。