Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing OpenCV-从数独游戏中删除网格线_Image Processing_Opencv_Sudoku - Fatal编程技术网

Image processing OpenCV-从数独游戏中删除网格线

Image processing OpenCV-从数独游戏中删除网格线,image-processing,opencv,sudoku,Image Processing,Opencv,Sudoku,我正在编写一个Android应用程序,从图片中提取数独游戏。对于9x9数独网格中的每个单元格,我需要确定它是包含数字1到9中的一个,还是为空。以下是我的算法的大致要点: 自适应阈值 展开以减少要考虑的轮廓数 找到拼图的轮廓并将其扭曲成正方形 将正方形分成81个相等的单元格;查找至少有20%白色像素的单元格 找到最靠近这些单元格中心的白色斑点,并获得其边框 对边界矩形内的图像部分使用字符识别(k-最近邻/Tesseract/等) 虽然我可以用一个简单的泛光填充去除数独游戏厚厚的外部边界,但内部

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

  • 自适应阈值
  • 展开以减少要考虑的轮廓数
  • 找到拼图的轮廓并将其扭曲成正方形
  • 将正方形分成81个相等的单元格;查找至少有20%白色像素的单元格
  • 找到最靠近这些单元格中心的白色斑点,并获得其边框
  • 对边界矩形内的图像部分使用字符识别(k-最近邻/Tesseract/等)
虽然我可以用一个简单的泛光填充去除数独游戏厚厚的外部边界,但内部网格线并不连续,即使在膨胀之后,也不能如此容易地去除。以下是移除外部网格线后的示例数独:

问题:有时,一个单元格中有足够多的网格线,超过20%的像素是白色的,因此我错误地检测到该单元格中有数字。以下是此类单元的示例:

我考虑过取消图像的旋转以降低内部网格线的可见性。我可以使用Hough变换或post中描述的方法来查找网格线,作为取消旋转的前奏。但是,我看不到取消网格线有任何其他显著的好处,完全删除网格线应该更安全、更容易

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

    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);
在阈值化之前,高斯模糊是减少噪声的必要条件。膨胀是为了确保外部网格线连接,但不足以重新连接内部网格线

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


非常感谢。

如果您不想进行适当的卸载,那么使用较小的单元格进行数字测试可能是值得的

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

另一个可能有效的策略是在测试前使用,这取决于网格线的厚度与数字的对比

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


如果所有这些方法都失败了,为了进行填充,您必须获得网格线的扭曲,因此您也可以取消扭曲

我可能遗漏了一些明显的内容,但为什么需要删除网格线?如果你已经将识别出的数字排列在一个网格中,你就不能重新合成图像吗?我的目的是找出数独网格的每个单元格中都有哪些数字。要做到这一点,我需要识别哪些细胞中没有任何东西。如果网格线仍然存在,一些单元格中会出现一些东西,因为超过20%的像素可能是白色的。@Hammer我在我的问题中提到了那篇文章:)所以应该使它们的链接更暗。这些都是很好的建议。不幸的是,它们都有缺点。腐蚀会推动某些数字低于20%白色像素的单元格。使用较小的单元格可以删除一些由于扭曲而靠近单元格边缘的数字。最好的解决方案可能是取消对齐,然后使用更小的单元格(可能是每边的1/10,而不是每边的1/4)。此外,您可能想看看我对OP的编辑。我想知道我是否可以修改预处理以保持内线从一开始就连接。@1''删除一些数字应该不会有问题,只要数字的某些部分仍在单元格内,您就不需要使用相同的单元格进行数字显示测试和分类。关于预处理,我会尝试更改阈值(2),也可能更改块大小。实际上,看起来5和2是最佳值。在大范围的数值范围内,不可能使粗网格线旁边的细网格线部分变为白色,这可能是因为外部网格线的所有黑色像素将阈值降低了太多。不过,在这两个测试中使用不同的单元格非常有意义!这很可能是最好的解决办法。