mikepound / mazesolving

A variety of algorithms to solve mazes from an input image
The Unlicense
1.74k stars 411 forks source link

Crashes when using 1-bit grayscale PNG input #4

Closed ghost closed 7 years ago

ghost commented 7 years ago

Just tested it with the attached image maze.

It is an "PNG image data, 619 x 995, 1-bit grayscale, non-interlaced"

The result was a crash

python3 solve.py maze.png solution.bmp
Loading Image
Creating Maze
Node Count: 101050
Time elapsed: 0.5865614414215088 

Starting Solve: Breadth first search
Nodes explored:  100926
Path found, length 1461
Time elapsed:  0.14136648178100586 

Saving Image
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2195, in fromarray
    mode, rawmode = _fromarray_typemap[typekey]
KeyError: ((1, 1, 3), '|b1')

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "solve.py", line 88, in <module>
    img = Image.fromarray(out)
  File "/usr/lib/python3/dist-packages/PIL/Image.py", line 2198, in fromarray
    raise TypeError("Cannot handle this data type")
TypeError: Cannot handle this data type

It works fine when converting the input to "PNG image data, 619 x 995, 1-bit colormap, non-interlaced"

mikepound commented 7 years ago

This issue can be fixed by specifying a uint8 datatype on line 60, which prevents the numpy array being created as a boolean array, which won't work with my RGB code. This causes further problems though, it seems numpy isn't playing well with the 1bpp non-indexed datatype. The solution I found is to replace lines 58-62 with this:

print ("Saving Image");
dt = im.getdata(0);
imout = np.array(dt, dtype=np.uint8).reshape((im.height, im.width));
imout[imout>0] = 255;
out = imout[:,:,np.newaxis];
out = np.repeat(out, 3, axis=2);

Going via the im underlying data seems to play better, but you then have to reshape it, and make sure that any 1s become 255 etc. I probably won't commit this change at the moment, because without further testing I'm not 100% sure it'll work with all other datatypes. There may also be a much more efficient way of doing this, perhaps skipping numpy complete.

P.s. Interesting choice of image :)

mikepound commented 7 years ago

I've now adjusted the code to completely avoid numpy, as it isn't necessary here. It should be faster, and doesn't have a problem with 1bpp image types. Hopefully it'll work for you!

Mike

ghost commented 7 years ago

works perfectly fine. Thanks