How to convert an image whose mode is "1" between PIL and numpy?

I am new to image processing with Python and have encountered a strange problem.

For example, I have a 2 * 2 black and white bitmap image followed by the following pixels:

black White

White black

Use PIL and convert it to numpy:

>>> import Image >>> import numpy >>> im = Image.open('test.bmp') >>> im <BmpImagePlugin.BmpImageFile image mode=1 size=2x2 at 0x95A54EC> >>> numpy.asarray(im) array([[ True, True], [False, False]], dtype=bool) >>> 

What puzzles me is the order of the pixels in the array. Why not [[True, False], [False, True]] ? Thanks.


UPDATE: the bitmap is here: http://njuer.us/clippit/test.bmp

+4
source share
1 answer

It looks like there are some errors with converting to / from numpy with mode 1 .

If you convert it to L , it works fine:

 >>> im <BmpImagePlugin.BmpImageFile image mode=1 size=2x2 at 0x17F17E8> >>> im2 = im.convert('L') >>> numpy.asarray(im2) array([[ 0, 255], [255, 0]], dtype=uint8) 

Also, if you try to convert the bool numpy array to PIL, you will get strange results:

 >>> testarr = numpy.array([[True,False],[True,False]], dtype=numpy.bool) >>> testpil = Image.fromarray(testarr, mode='1') >>> numpy.asarray(testpil) array([[False, False], [False, False]], dtype=bool) 

However, the same thing with uint8 works fine:

 >>> testarr = numpy.array([[255,0],[0,255]], dtype=numpy.uint8) >>> Image.fromarray(testarr) <Image.Image image mode=L size=2x2 at 0x1B51320> >>> numpy.asarray(Image.fromarray(testarr)) array([[255, 0], [ 0, 255]], dtype=uint8) 

Therefore, I would suggest using L as an intermediate data type, and then go to 1 before saving if you need to save it in this format. Something like that:

 >>> im <BmpImagePlugin.BmpImageFile image mode=1 size=2x2 at 0x17F17E8> >>> im2 = im.convert('L') >>> arr = numpy.asarray(im2) >>> arr array([[ 0, 255], [255, 0]], dtype=uint8) >>> arr = arr == 255 >>> arr array([[False, True], [ True, False]], dtype=bool) 

Then to go back:

 >>> backarr = numpy.zeros(arr.shape, dtype=numpy.uint8) >>> backarr[arr] = 255 >>> backarr array([[ 0, 255], [255, 0]], dtype=uint8) >>> Image.fromarray(backarr).convert('1') <Image.Image image mode=1 size=2x2 at 0x1B41CB0> 
+3
source

All Articles