วิธีที่ดีที่สุดในการเป็นตัวแทนและแก้ไขเขาวงกตที่ได้รับภาพคืออะไร?
เมื่อพิจารณาจากรูปภาพ JPEG (ดังที่แสดงไว้ด้านบน) วิธีที่ดีที่สุดในการอ่านข้อมูลคือแยกวิเคราะห์ข้อมูลลงในโครงสร้างข้อมูลบางส่วนและแก้ปัญหาเขาวงกต สัญชาตญาณแรกของฉันคือการอ่านภาพทีละพิกเซลและเก็บไว้ในรายการ (อาร์เรย์) ของค่าบูลีน: True
สำหรับพิกเซลสีขาวและพิกเซลFalse
ที่ไม่ใช่สีขาว (สีสามารถละทิ้ง) ปัญหาด้วยวิธีนี้คือภาพอาจจะไม่ "สมบูรณ์แบบพิกเซล" โดยที่ฉันเพียงแค่หมายความว่าหากมีพิกเซลสีขาวบางแห่งบนผนังก็อาจสร้างเส้นทางที่ไม่ได้ตั้งใจ
อีกวิธีหนึ่ง (ซึ่งมาหาฉันหลังจากคิดไปเล็กน้อย) ก็คือการแปลงภาพเป็นไฟล์ SVG ซึ่งเป็นรายการของเส้นทางที่วาดบนผืนผ้าใบ ด้วยวิธีนี้เส้นทางสามารถอ่านได้ในรายการประเภทเดียวกัน (ค่าบูลีน) ซึ่งTrue
ระบุเส้นทางหรือกำแพงเพื่อFalse
ระบุพื้นที่ที่สามารถเดินทางได้ ปัญหาด้วยวิธีนี้เกิดขึ้นหากการแปลงไม่ถูกต้อง 100% และไม่เชื่อมต่อกำแพงทั้งหมดอย่างเต็มที่ทำให้เกิดช่องว่าง
นอกจากนี้ปัญหาเกี่ยวกับการแปลงเป็น SVG ก็คือเส้นไม่ตรง "สมบูรณ์แบบ" ซึ่งส่งผลในเส้นทางเป็นลูกบาศก์ bezier โค้ง ด้วยรายการ (อาร์เรย์) ของค่าบูลีนที่จัดทำดัชนีโดยจำนวนเต็มเส้นโค้งจะไม่ถ่ายโอนได้อย่างง่ายดายและทุกจุดที่เส้นบนเส้นโค้งจะต้องถูกคำนวณ แต่จะไม่ตรงกับดัชนีรายการทั้งหมด
ฉันคิดว่าในขณะที่หนึ่งในวิธีการเหล่านี้อาจใช้งานได้ (แม้ว่าอาจจะไม่ใช่) ว่าพวกเขาไม่มีประสิทธิภาพมากนักเนื่องจากภาพขนาดใหญ่ดังกล่าวและมีวิธีที่ดีกว่า วิธีนี้ดีที่สุด (มีประสิทธิภาพมากที่สุดและ / หรือมีความซับซ้อนน้อยที่สุด) ทำอย่างไร มีวิธีที่ดีที่สุดหรือไม่?
จากนั้นการแก้ปัญหาของเขาวงกตมา ถ้าฉันใช้วิธีใดวิธีหนึ่งจากสองวิธีแรกฉันจะต้องใช้เมทริกซ์เป็นหลัก ตามคำตอบนี้เป็นวิธีที่ดีที่จะเป็นตัวแทนเขาวงกตใช้ต้นไม้และเป็นวิธีที่ดีที่จะแก้ปัญหาได้คือการใช้A * อัลกอริทึม เราจะสร้างต้นไม้จากภาพได้อย่างไร ความคิดใด ๆ
TL; DR
วิธีแยกวิเคราะห์ที่ดีที่สุด? โครงสร้างข้อมูลอะไร โครงสร้างดังกล่าวจะช่วย / แก้ปัญหาได้อย่างไร?
อัปเดต
ฉันได้ลองใช้สิ่งที่ @Mailail เขียนไว้ใน Python โดยใช้numpy
ตามที่ @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)
เยี่ยมชมจุดสุดยอดเมื่อมันถูกเพิ่มลงในคิว อันที่จริงแล้วอาร์เรย์นี้ควรมีชื่อว่า "อยู่ในคิว" นอกจากนี้คุณยังสามารถยกเลิก BFS เมื่อคุณทำเสร็จแล้ว