Quelle est la meilleure façon de représenter et de résoudre un labyrinthe avec une image?
Étant donné une image JPEG (comme vu ci-dessus), quelle est la meilleure façon de la lire, de l'analyser dans une structure de données et de résoudre le labyrinthe? Mon premier réflexe est de lire l'image pixel par pixel et de la stocker dans une liste (tableau) de valeurs booléennes: True
pour un pixel blanc, et False
pour un pixel non blanc (les couleurs peuvent être supprimées). Le problème avec cette méthode, c'est que l'image peut ne pas être "pixel parfait". Par cela, je veux simplement dire que s'il y a un pixel blanc quelque part sur un mur, il peut créer un chemin involontaire.
Une autre méthode (qui m'est venue après un peu de réflexion) consiste à convertir l'image en fichier SVG - qui est une liste de chemins tracés sur une toile. De cette façon, les chemins pourraient être lus dans le même type de liste (valeurs booléennes) où True
indique un chemin ou un mur, False
indiquant un espace de voyage. Un problème avec cette méthode se produit si la conversion n'est pas précise à 100% et ne connecte pas entièrement tous les murs, créant des écarts.
Un autre problème avec la conversion en SVG est que les lignes ne sont pas "parfaitement" droites. Il en résulte que les chemins sont des courbes de Bézier cubiques. Avec une liste (tableau) de valeurs booléennes indexées par des entiers, les courbes ne seraient pas transférées facilement et tous les points qui se trouvent sur la courbe devraient être calculés, mais ne correspondraient pas exactement aux indices de liste.
Je suppose que même si l'une de ces méthodes peut fonctionner (mais probablement pas), elles sont terriblement inefficaces compte tenu d'une si grande image et qu'il existe une meilleure méthode. Comment cela se fait-il (le plus efficacement et / ou avec le moins de complexité)? Existe-t-il même un meilleur moyen?
Vient ensuite la résolution du labyrinthe. Si j'utilise l'une des deux premières méthodes, je me retrouverai essentiellement avec une matrice. Selon cette réponse , un bon moyen de représenter un labyrinthe est d'utiliser un arbre, et un bon moyen de le résoudre est d'utiliser l' algorithme A * . Comment créer un arbre à partir de l'image? Des idées?
TL; DR La
meilleure façon d'analyser? Dans quelle structure de données? Comment cette structure aiderait-elle / entraverait-elle la résolution?
MISE À JOUR
J'ai essayé de mettre en œuvre ce que @Mikhail a écrit en Python, en utilisant numpy
, comme @Thomas l'a recommandé. Je pense que l'algorithme est correct, mais il ne fonctionne pas comme espéré. (Code ci-dessous.) La bibliothèque PNG est 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)
sous a for.if
et le remplacer par visited.append(np)
. Un sommet est visité une fois qu'il est ajouté à la file d'attente. En fait, ce tableau doit être nommé "en file d'attente". Vous pouvez également terminer BFS une fois que vous avez atteint l'arrivée.