Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/352.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
Python 如何使用OpenCV获取数独网格的单元格?_Python_Image_Opencv_Image Processing_Sudoku - Fatal编程技术网

Python 如何使用OpenCV获取数独网格的单元格?

Python 如何使用OpenCV获取数独网格的单元格?,python,image,opencv,image-processing,sudoku,Python,Image,Opencv,Image Processing,Sudoku,在过去的几天里,我一直在尝试从图片中获取数独网格,我一直在努力获取网格中较小的正方形。 我正在画下面的图片。我原以为用canny过滤器处理图像会很好,但事实并非如此,我无法得到每个正方形的每个轮廓。然后我把自适应阈值,大津,和一个经典的阈值测试,但每次,它似乎不能捕捉到每一个小正方形 最终的目标是获取包含数字的单元格,并使用pytorch识别数字,因此我非常希望获得一些数字的清晰图像,这样识别就不会出错:) 有人知道如何实现这一点吗? 提前多谢!:D 如果图像只包含紧密贴合的数独网格,实现它的一

在过去的几天里,我一直在尝试从图片中获取数独网格,我一直在努力获取网格中较小的正方形。 我正在画下面的图片。我原以为用canny过滤器处理图像会很好,但事实并非如此,我无法得到每个正方形的每个轮廓。然后我把自适应阈值,大津,和一个经典的阈值测试,但每次,它似乎不能捕捉到每一个小正方形

最终的目标是获取包含数字的单元格,并使用pytorch识别数字,因此我非常希望获得一些数字的清晰图像,这样识别就不会出错:)

有人知道如何实现这一点吗? 提前多谢!:D


如果图像只包含紧密贴合的数独网格,实现它的一个粗略方法是将图像分成相等的9X9网格,然后尝试提取每个网格中的数字。

以下是一个潜在的解决方案:

  • 获取二值图像。将图像转换为灰度并

  • 过滤掉所有数字和噪声,以仅隔离方框。我们使用过滤来删除数字,因为我们只需要每个单独的单元格

  • 修复网格线。使用来修复网格线
  • 按从上到下和从左到右的顺序对每个单元格进行排序。我们使用with
    从上到下和
    从左到右
    参数将每个单元格按顺序组织起来

  • 这是初始二值图像(左)和过滤掉的数字+修复的网格线+反转图像(右)

    这里是每个单元迭代的可视化

    每个单元格中检测到的数字

    代码

    导入cv2
    从imutils导入等高线
    将numpy作为np导入
    #加载图像、灰度和自适应阈值
    image=cv2.imread('1.png')
    灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
    阈值=cv2。自适应阈值(灰色,255,cv2。自适应阈值高斯C,cv2。阈值二进制INV,57,5)
    #过滤掉所有数字和噪音,仅隔离方框
    cnts=cv2.查找对象(阈值、cv2.RETR\u树、cv2.链近似值、简单值)
    如果len(cnts)==2个其他cnts[1],则cnts=cnts[0]
    对于碳纳米管中的碳:
    面积=cv2。轮廓面积(c)
    如果面积小于1000:
    cv2.拉深轮廓(阈值[c],-1,(0,0,0),-1)
    #固定水平线和垂直线
    垂直内核=cv2.getStructuringElement(cv2.MORPH_RECT,(1,5))
    thresh=cv2.morphologyEx(thresh,cv2.MORPH\u CLOSE,垂直内核,迭代次数=9)
    水平内核=cv2.getStructuringElement(cv2.MORPH_RECT,(5,1))
    thresh=cv2.morphologyEx(thresh,cv2.MORPH\u CLOSE,水平核,迭代次数=4)
    #按从上到下排序,每行按从左到右排序
    反转=255-阈值
    cnts=cv2.findContours(反转、cv2.RETR\u树、cv2.CHAIN\u近似、简单)
    如果len(cnts)==2个其他cnts[1],则cnts=cnts[0]
    (CNT,u)=等高线。等高线排序(CNT,方法=“从上到下”)
    数独行=[]
    行=[]
    对于枚举(碳纳米管,1)中的(i,c):
    面积=cv2。轮廓面积(c)
    如果面积小于50000:
    行。追加(c)
    如果i%9==0:
    (CNT,u)=等高线。等高线排序(行,方法=“从左到右”)
    数独行追加(cnts)
    行=[]
    #遍历每个框
    对于数独行中的行:
    对于第行中的c:
    掩码=np.zero(image.shape,dtype=np.uint8)
    cv2.绘制轮廓(掩模,[c],-1,(255255),-1)
    结果=cv2.按位_和(图像、掩码)
    结果[掩码==0]=255
    cv2.imshow(“结果”,结果)
    cv2.等待键(175)
    cv2.imshow('thresh',thresh)
    cv2.imshow(“反转”,反转)
    cv2.waitKey()
    

    注意:排序思想是根据中以前的答案改编而成的

    步骤:

    ########## To view all the extracted digits ###############
    _, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
    axs = axs.flatten()
    for img, ax in zip(list_images, axs):
        ax.imshow(cv2.resize(img,(64,64)))
    plt.show()
    
  • 图像预处理(关闭操作)
  • 查找数独方块并创建遮罩图像
  • 寻找垂直线
  • 寻找水平线
  • 寻找网格点
  • 纠正缺陷
  • 从每个单元格中提取数字
  • 代码:
    翘曲:

    ########## To view all the extracted digits ###############
    _, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
    axs = axs.flatten()
    for img, ax in zip(list_images, axs):
        ax.imshow(cv2.resize(img,(64,64)))
    plt.show()
    

    th3:

    ########## To view all the extracted digits ###############
    _, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
    axs = axs.flatten()
    for img, ax in zip(list_images, axs):
        ax.imshow(cv2.resize(img,(64,64)))
    plt.show()
    

    扭曲2:

    ########## To view all the extracted digits ###############
    _, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
    axs = axs.flatten()
    for img, ax in zip(list_images, axs):
        ax.imshow(cv2.resize(img,(64,64)))
    plt.show()
    

    数独结果:


    所有提取的数字:

    ########## To view all the extracted digits ###############
    _, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
    axs = axs.flatten()
    for img, ax in zip(list_images, axs):
        ax.imshow(cv2.resize(img,(64,64)))
    plt.show()
    

    参考文献:

    ########## To view all the extracted digits ###############
    _, axs = plt.subplots(1, len(list_images), figsize=(24, 24))
    axs = axs.flatten()
    for img, ax in zip(list_images, axs):
        ax.imshow(cv2.resize(img,(64,64)))
    plt.show()
    

    您是否尝试过使用流行的搜索引擎搜索opencv数独?我尝试过,但没有找到使用非常扭曲的网格的示例。因此,我在网上搜索的代码对这张图片不起作用。难道你不能拍更好的照片吗?或者甚至只是更好地调整对比度,使其成为带有黑色数字的二值图像,那么你就不需要担心网格,只需使用tesseract来选择数字-你试过了吗?如果你这样做了,请在你的问题中总结一下你尝试过并拒绝过的其他事情,这样阅读你的问题的人就不会浪费时间提出建议。论坛上有很多关于寻找网格单元的帖子,特别是对于棋盘格。尝试搜索和检查代码。这实际上是我尝试的第一件事。问题是,大多数情况下,我无法使网格完美匹配为正方形。因此,一个单元格看起来像半个数字,上面有一条线。这通常是网格顶部的4或6发生的情况。但是,如果你有一个技术,使图像不失真,使其成为一个完美的正方形,我很乐意接受它!