我正在寻找算法,给定一个包含填字游戏的图像
填字游戏本身可以被认为是规则的(即我对由某些程序生成并作为图像发布的填字游戏感兴趣,而不是扫描基于纸张的填字游戏),我希望程序能够在没有需要除图像位图以外的任何输入。
我可以想到一些强力多通道方法来做到这一点(基本上使用imagemagick的hit-and-miss filter的变体,然后在图像上循环寻找剩余的点)但是我希望人们有更好的想法谁真正了解图像处理。
答案 0 :(得分:7)
这是一个非常广泛的问题,但我会尝试给你一些指示。 这些是您需要采取的步骤:
在这里(1,2,3)你有一个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尺寸模板)
由于填字游戏网格具有相对恒定的形状(尤其是填字游戏编译器的固定输出),因此创建原型模板并成功匹配(和对齐)检测到的区域以提取形状信息应该相对容易