Cách tốt nhất để đại diện và giải quyết một mê cung cho một hình ảnh là gì?
Đưa ra một hình ảnh JPEG (như đã thấy ở trên), cách tốt nhất để đọc nó, phân tích nó thành một số cấu trúc dữ liệu và giải quyết mê cung là gì? Bản năng đầu tiên của tôi là đọc hình ảnh theo pixel theo pixel và lưu trữ nó trong một danh sách (mảng) các giá trị boolean: True
cho pixel trắng và False
cho pixel không trắng (màu sắc có thể bị loại bỏ). Vấn đề với phương pháp này là hình ảnh có thể không phải là "pixel perfect". Điều đó có nghĩa đơn giản là nếu có một pixel trắng ở đâu đó trên tường thì nó có thể tạo ra một đường dẫn ngoài ý muốn.
Một phương pháp khác (xuất hiện sau một chút suy nghĩ) là chuyển đổi hình ảnh thành tệp SVG - đó là danh sách các đường dẫn được vẽ trên khung vẽ. Theo cách này, các đường dẫn có thể được đọc vào cùng một loại danh sách (giá trị boolean) trong đó True
chỉ ra một đường dẫn hoặc tường, False
biểu thị một không gian có thể đi được. Một vấn đề với phương pháp này phát sinh nếu chuyển đổi không chính xác 100% và không kết nối đầy đủ tất cả các bức tường, tạo ra các khoảng trống.
Ngoài ra, một vấn đề với việc chuyển đổi sang SVG là các đường thẳng không "hoàn hảo". Điều này dẫn đến các đường dẫn là các đường cong bezier hình khối. Với một danh sách (mảng) các giá trị boolean được lập chỉ mục bởi các số nguyên, các đường cong sẽ không dễ dàng chuyển và tất cả các điểm trên đường cong sẽ phải được tính toán, nhưng sẽ không khớp chính xác với các chỉ số danh sách.
Tôi giả định rằng trong khi một trong những phương pháp này có thể hoạt động (mặc dù có lẽ là không) thì chúng không hiệu quả khi đưa ra một hình ảnh lớn như vậy, và tồn tại một cách tốt hơn. Làm thế nào là tốt nhất (hiệu quả nhất và / hoặc với độ phức tạp ít nhất) được thực hiện? Thậm chí có một cách tốt nhất?
Rồi đến việc giải quyết mê cung. Nếu tôi sử dụng một trong hai phương thức đầu tiên, về cơ bản tôi sẽ kết thúc bằng một ma trận. Theo câu trả lời này , một cách tốt để thể hiện một mê cung là sử dụng cây và một cách tốt để giải quyết nó là sử dụng thuật toán A * . Làm thế nào một người sẽ tạo ra một cây từ hình ảnh? Có ý kiến gì không?
TL; DR
Cách tốt nhất để phân tích? Vào cấu trúc dữ liệu nào? Làm thế nào sẽ nói cấu trúc giúp / cản trở giải quyết?
CẬP NHẬT
Tôi đã thử thực hiện những gì @Mikhail đã viết bằng Python, sử dụng numpy
, như @Thomas khuyến nghị. Tôi cảm thấy rằng thuật toán là chính xác, nhưng nó không hoạt động như mong đợi. (Mã bên dưới.) Thư viện PNG là 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)
theo for.if
và thay thế nó bằng visited.append(np)
. Một đỉnh được truy cập khi nó được thêm vào hàng đợi. Trong thực tế, mảng này nên được đặt tên là "xếp hàng". Bạn cũng có thể chấm dứt BFS sau khi bạn hoàn thành.