如何通过图像表示和解决迷宫问题?
给定一个JPEG图像(如上所示),最好的方法是什么,可以将其读入,解析成某些数据结构并解决迷宫问题?我的第一反应是逐像素读取图像,并将其存储在布尔值列表(数组)中:True
表示白色像素,False
表示非白色像素(颜色可以丢弃)。这种方法的问题是,图像可能不是“像素完美”的。我指的是如果墙上有一个白色像素,它可能会创建一个意外的路径。另一种方法(经过一点思考后想到的)是将图像转换为SVG文件-这是在画布上绘制的路径列表。这样,路径可以读入相同类型的列表(布尔值),其中
True
表示路径或墙壁,False
表示可行走的空间。使用此方法时可能会出现问题,如果转换不是100%准确的,则无法完全连接所有墙壁,从而创建间隙。同样转换为SVG的问题是,线条不是“完美”的直线。这导致路径成为三次贝塞尔曲线。使用由整数索引的布尔值列表(数组),曲线将不容易传输,并且所有位于曲线上的点都必须计算,但不会完全匹配列表索引。
我认为其中一种方法可能有效(尽管可能不是),但考虑到这样一个大图像,它们的效率非常低,而且存在更好的方法。最佳方法是什么(最高效和/或最简单)?甚至有最佳方法吗?
然后是解决迷宫的问题。如果我使用前两种方法之一,我最终将得到一个矩阵。根据此答案,表示迷宫的好方法是使用树,解决它的好方法是使用A*算法。如何从图像创建树?有什么想法吗?
TL;DR 最佳解析方式?转换为哪种数据结构?该结构如何帮助/阻碍解决?
更新
我尝试使用numpy
实现了@Mikhail编写的Python代码,正如@Thomas建议的那样。我觉得算法是正确的,但它并没有像希望的那样工作。(下面是代码。)PNG库是PyPNG。
import png, numpy, Queue, operator, itertools
def is_white(coord, image):
""" Returns whether (x, y) is approx. a white pixel."""
a = True
for i in xrange(3):
if not a: break
a = image[coord[1]][coord[0] * 3 + i] > 240
return a
def bfs(s, e, i, visited):
""" Perform a breadth-first search. """
frontier = Queue.Queue()
while s != e:
for d in [(-1, 0), (0, -1), (1, 0), (0, 1)]:
np = tuple(map(operator.add, s, d))
if is_white(np, i) and np not in visited:
frontier.put(np)
visited.append(s)
s = frontier.get()
return visited
def main():
r = png.Reader(filename = "thescope-134.png")
rows, cols, pixels, meta = r.asDirect()
assert meta['planes'] == 3 # ensure the file is RGB
image2d = numpy.vstack(itertools.imap(numpy.uint8, pixels))
start, end = (402, 985), (398, 27)
print bfs(start, end, image2d, [])
visited.append(s)
移动到for.if
下,并用visited.append(np)
替换它。一旦顶点被添加到队列中,它就被访问过了。实际上,这个数组应该被命名为“queued”。一旦到达终点,您也可以终止BFS。 - Mikhail