从图像中分类和提取填字游戏网格的算法

时间:2014-01-30 04:15:55

标签: algorithm image-processing computer-vision

我正在寻找算法,给定一个包含填字游戏的图像

  1. 将图片裁剪为填字游戏
  2. 区分regularbarred填字游戏
  3. 提取网格大小和黑色方块/条的位置
  4. 填字游戏本身可以被认为是规则的(即我对由某些程序生成并作为图像发布的填字游戏感兴趣,而不是扫描基于纸张的填字游戏),我希望程序能够在没有需要除图像位图以外的任何输入。

    我可以想到一些强力多通道方法来做到这一点(基本上使用imagemagick的hit-and-miss filter的变体,然后在图像上循环寻找剩余的点)但是我希望人们有更好的想法谁真正了解图像处理。

4 个答案:

答案 0 :(得分:7)

这是一个非常广泛的问题,但我会尝试给你一些指示。 这些是您需要采取的步骤:

  1. 检测填字游戏的位置
  2. 检测填字游戏的网格。为此,您需要一些计算机视觉算法(例如Hough lines detector)。
  3. 对于每个单元格,您需要查找是否有字符。要做到这一点,你只需简单地分析细胞所具有的白色“量”
  4. 对于包含角色的单元格,您需要识别它。为此,您需要OCR,我建议您Tesseract
  5. 解决填字游戏创建自己的算法。您可以使用this
  6. 在这里(123)你有一个Python中的数独求解器的例子。第一步是您的问题所共有的,因此您可以使用OpenCV来解决它:

    import cv2
    import numpy as np
    
    #Load the Black and White image
    img =  cv2.imread('sudoku.jpg')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    gray = cv2.GaussianBlur(gray,(5,5),0)
    thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)
    
    #Detect the lines of the sudoku
    contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    #Detect the square of the Sudoku
    biggest = None
    max_area = 0
    for i in contours:
            area = cv2.contourArea(i)
            if area > 100:
                    peri = cv2.arcLength(i,True)
                    approx = cv2.approxPolyDP(i,0.02*peri,True)
                    if area > max_area and len(approx)==4:
                            biggest = approx
                            max_area = area
    

答案 1 :(得分:1)

尝试使用hough变换找到正方形,当你使用直方图检查方块时,是否使用阈值对其灰度值进行黑暗或白色方块

答案 2 :(得分:1)

使用链接的填字游戏的屏幕截图作为示例,我假设:

  • 填字游戏网格清晰,即水平和垂直网格线以精确像素绘制,具有恒定的深色,并且网格单元内没有噪声,
  • 填字游戏是黑色或其他相对较暗的颜色("黑色")白色或浅灰色("白色"),
  • 线索编号写在左上角,
  • 填字游戏是矩形且规则的。

然后,您可以从上到下扫描图像,找到足够长度的水平黑线。一条线以黑色像素开始,以白色像素结束。其他像素是指示它不是一条线。 (这是为了清除文本和按钮。)对垂直线做同样的事情。

理想情况下,您现在拥有填字游戏线。如果您的图片没有裁剪为填字游戏,则可能会出现误报,例如按钮边框。要查找填字游戏线,请按长度对其进行排序,并查找相同长度的最大连续块。除非你有一些degenerate cases

,否则这些应该是你的填字游戏

现在做一个水平和垂直线的嵌套循环,但跳过第一行。在两条线的交叉点的西北方向看两三个像素。如果像素是暗的,则表示空白。如果它很轻,它就是一个细胞。这种启发式似乎运作良好。我在这里说黑暗和光明,因为一些填字游戏在打印时使用灰色单元格来节省墨水,并且屏幕截图中突出显示了一些单元格。

如果你最终没有空白,你就会有一个禁止的填字游戏。您可以通过检查单元格边框左侧和右侧的像素之一是否为黑色来找到条形图。

最后,提示:如果您想使用算法查找使用填字游戏编译器生成的填字游戏中的单元格,请查看源代码。你会找到一个Javascript文件/puzzles/sample/cryptic_demo/cryptic_demo_xml.js的链接,它将填字游戏作为XML字符串,它也为你提供了线索作为奖励。

较早版本的填字游戏编译器,例如用于Independent Cryptic的填字游戏编译器将数据隐藏在从applet加载的文件中。该文件的格式是二进制文件,但如果您知道原始数据,则不难读取。

答案 3 :(得分:1)

考虑另一种方法。

这在很多方面类似于对象识别,计算机视觉

一种方法是使用像openCV这样的框架,通过一些你想要检测的样本进行训练,可以检测到任何类似的结果

(基于Viola-Jones算法进行对象检测的javascript库,openCV也使用,作者是HAAR.js

除此之外(或类似的替代方案),有可能构建一个" visual"您要检测的填字游戏模板(以比例不变的方式)

扫描图像,查找图像部分与模板的相关性(复杂度O(N * M),N图像尺寸,M尺寸模板)

由于填字游戏网格具有相对恒定的形状(尤其是填字游戏编译器的固定输出),因此创建原型模板并成功匹配(和对齐)检测到的区域以提取形状信息应该相对容易