이미지가 주어진 미로를 표현하고 해결하는 가장 좋은 방법은 무엇입니까?
JPEG 이미지 (위에서 볼 수 있듯이)를 읽으면 그것을 읽는 가장 좋은 방법은 무엇입니까? 데이터 구조로 구문 분석하고 미로를 해결합니까? 첫 번째 본능은 이미지를 픽셀 단위로 읽고 이미지를 부울 값의 목록 (배열)에 저장하는 것입니다 : True
흰색 픽셀 및 False
흰색이 아닌 픽셀 (색상을 버릴 수 있음). 이 방법의 문제점은 이미지가 "픽셀 완벽"하지 않을 수 있다는 것입니다. 즉, 벽 어딘가에 흰색 픽셀이 있으면 의도하지 않은 경로가 만들어 질 수 있습니다.
또 다른 방법 (약간의 생각 후에 나에게 온)은 이미지를 캔버스에 그려진 경로 목록 인 SVG 파일로 변환하는 것입니다. 이런 식으로 경로 True
는 경로 또는 벽을 False
나타내는 이동 가능한 공간을 나타내는 동일한 종류의 목록 (부울 값)으로 읽을 수 있습니다 . 이 방법의 문제는 변환이 100 % 정확하지 않고 모든 벽을 완전히 연결하지 않아 간격이 생기는 경우에 발생합니다.
SVG로 변환 할 때의 문제는 선이 "완벽하게"직선적이지 않다는 것입니다. 그 결과 경로는 3 차 베 지어 곡선이됩니다. 정수로 인덱싱 된 부울 값의 목록 (배열)을 사용하면 곡선이 쉽게 전달되지 않고 곡선의 해당 선이 계산되어야하지만 목록 색인과 정확히 일치하지는 않습니다.
나는이 방법 중 하나가 효과적 일 수 있지만 그렇게 큰 이미지가 주어지면 비효율적이며 더 좋은 방법이 있다고 가정합니다. 이것이 가장 효율적이고 (또는 가장 복잡하지 않은) 어떻게 이루어 집니까? 가장 좋은 방법이 있습니까?
그런 다음 미로를 해결합니다. 처음 두 방법 중 하나를 사용하면 본질적으로 행렬로 끝납니다. 이 답변 에 따르면 , 미로를 표현하는 좋은 방법은 나무를 사용하는 것이고, 그것을 해결하는 좋은 방법은 A * 알고리즘을 사용하는 것입니다 . 이미지에서 나무를 어떻게 만들 수 있습니까? 어떤 아이디어?
TL; DR
파싱하는 가장 좋은 방법은? 어떤 데이터 구조로? 상기 구조는 어떻게 도움이되고 / 후진 해결에 도움이됩니까?
업데이트
@Thomas가 numpy
권장하는 것처럼 @Mikhail이 Python으로 작성한 것을 구현하여 내 손을 사용해 보았습니다. 알고리즘이 정확하다고 생각하지만 원하는대로 작동하지 않습니다. 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)
a 아래로 이동 하여로 for.if
대체 해야한다고 확신합니다 visited.append(np)
. 큐에 추가되면 버텍스가 방문됩니다. 실제로이 배열의 이름은 "queued"여야합니다. 완료되면 BFS를 종료 할 수도 있습니다.