# Solving mazes with the watershed transform

I'd like to welcome back guest blogger Spandan Tiwari for today's post. Spandan, a developer on the Image Processing Toolbox team, posted here previously about circle finding and homomorphic filtering.

A few weeks ago Steve wrote about watershed transform and how to use it for image segmentation. I thought I would continue the topic and highlight another neat application for watershed transform - Maze Solving. Steve discussed this problem in his earlier post on Exploring Shortest Paths and showed a solution based on Geodesic distance transform (bwdistgeodesic). In this post I show another way for solving a maze using watershed transform.

Here's a maze. We would like to find the solution , i.e. a path between the two points (entry and exit points) shown in red.

I = imread('https://blogs.mathworks.com/images/steve/2011/maze-51x51.png');
I = logical(I);
imshow(I)
hold on;
plot([6 526], [497 517], 'ro', 'MarkerSize', 15,'LineWidth', 2);
hold off;


I should mention that in my approach I am considering only 'standard' or 'perfect' mazes that have one and only one path from the entry point to the exit point, and some other nice properties such as absence of loops. I will call these mazes well-behaved mazes.

Here is the key idea behind using watershed transform for solving a maze. The landscape (or surface) of the image of a well-behaved maze has two catchment basins. The watershed between those catchment basins is the solution path for the maze! (For more details on the definition of watershed and catchment basin see Steve's newsletter article The Watershed Transform: Strategies for Image Segmentation). Let's look at the catchment basins as produced by watershed.

L = watershed(I);
imshow(L,[])


The two basins are shown in grey and white. If you follow the interface (boundary) between the two basins (grey and white regions), you can see notice that it is the solution (path) to the maze.

The good news is that at this point we have already solved the bulk of the problem. All we need to do now is to extract the interface between the two basins. There are different ways to do this. Here's the one that I like, mainly because I find it to be robust. Another minor reason I like it is that the final path stays parallel to the maze lines which gives it a nice clean look.

First we create a new image retaining only the original image region from one of the catchment basins.

L1 = L == 2;
I1 = L1.*I;
imshow(I1)


Next we use watershed again to get catchment basins for this new image.

L2 = watershed(I1);
imshow(L2,[])


Notice that the catchment basin in this new image has shrunk roughly by half the width of the maze paths as compared to the same catchment basin in the original image. This can be seen clearly using imshowpair. It highlights the area where the images are different using color (green, in this case)

imshowpair(L,L2)


As the last step we just extract the path shown as the green region, which is the region where the two catchment basins differ.

img1 = L == 2;
img2 = L2 == 2;
path = img1 - img2;


We can visualize the path on the maze nicely using Steve's imoverlay function.

P = imoverlay(I, path, [1 0 0]);
imshow(P)


Here are few other results on different mazes.

Published with MATLAB® R2013b

|