|
1 | 1 | # Working with images as input |
2 | | -Because its easier to visualize maps as pictures and to manipulate you often want to work on images instead of providing the map as big array. |
| 2 | +Because its easier to visualize maps as pictures and to manipulate you often want to work on images instead of providing the map as big array. |
| 3 | + |
| 4 | +We use Pillow for this as it has a pretty straight-forward API. |
| 5 | + |
| 6 | +We define the green pixel in the image as start and the red pixel as end. To have some variation and combat compression we define them as ranges above a certain threshold (although the png-image in our lossless compressed): |
| 7 | + |
| 8 | +``` |
| 9 | +def green(pixel: list) -> bool: |
| 10 | + """Returns True if the pixel is green (the starting point)""" |
| 11 | + return pixel[RED] < 10 and pixel[GREEN] > 250 and pixel[BLUE] < 10 |
| 12 | +
|
| 13 | +
|
| 14 | +def red(pixel: list) -> bool: |
| 15 | + """Returns True if the pixel is red (the goal position)""" |
| 16 | + return pixel[RED] > 250 and pixel[GREEN] < 10 and pixel[BLUE] < 10 |
| 17 | +``` |
| 18 | + |
| 19 | +Pixel are defined as walkable grid cells if each of their color values is above 50, so a strong gray is enough to make it walkable: |
| 20 | + |
| 21 | +``` |
| 22 | +def pixel_walkable(pixel, x, y): |
| 23 | + """returns True if the pixel is walkable.""" |
| 24 | + return any([p > 50 for p in pixel]) # darker pixel are not walkable |
| 25 | +``` |
| 26 | + |
| 27 | +In the main loop we iterate over all pixel to find start and end and create a boolean matrix as input for our Grid: |
| 28 | +``` |
| 29 | + with Image.open(filename_map) as im: |
| 30 | + width, height = im.size |
| 31 | + for y in range(height): |
| 32 | + nodes.append([]) |
| 33 | + for x in range(width): |
| 34 | + pixel = im.getpixel((x, y)) |
| 35 | + node = pixel_walkable(pixel[:3], x, y) |
| 36 | + nodes[y].append(node) |
| 37 | + if red(pixel): |
| 38 | + _goal = (x, y) |
| 39 | + if green(pixel): |
| 40 | + _start = (x, y) |
| 41 | + grid = Grid(matrix=nodes) |
| 42 | + end = grid.node(*_goal) |
| 43 | + start = grid.node(*_start) |
| 44 | +
|
| 45 | + finder = AStarFinder(diagonal_movement=DiagonalMovement.never) |
| 46 | + path, runs = finder.find_path(start, end, grid) |
| 47 | +``` |
| 48 | +You can of course use another finder or use another digital_movement-strategy like `DiagonalMovement.always`. |
0 commit comments