Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I'm new to image processing with Python and met a strange problem.

For example I have a 2*2 black-white bitmap image which pixels are following:

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 pixel in the array. Why not [[True, False], [False, True]]? Thanks.


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

like image 228
Clippit Avatar asked Sep 29 '11 12:09

Clippit


People also ask

How to use PIL to create thumbnails in Python?

Using PIL to create thumbnails is very simple. The thumbnail () method takes a tuple specifying the new size and converts the image to a thumbnail image with size that fits within the tuple. To create a thumbnail with longest side 128 pixels, use the method like this: Cropping a region from an image is done using the crop () method:

Where do I put PiL and NumPy in my code examples?

From Chapter 2 and onward, we assume PIL, NumPy, and Matplotlib are included at the top of every file you create and in every code example as: This makes the example code cleaner and the presentation easier to follow.

What is the difference between matplotlib and Pil?

The leftmost image is the original, followed by a grayscale version, a rotated crop pasted in, and a thumbnail image. When working with mathematics and plotting graphs or drawing points, lines, and curves on images, Matplotlib is a good graphics library with much more powerful features than the plotting available in PIL.

How do I use PIL to read and write images?

With PIL, you can read images from most formats and write to the most common ones. The most important module is the Image module. To read an image, use: The return value, pil_im, is a PIL image object. Color conversions are done using the convert () method. To read an image and convert it to grayscale, just add convert ('L') like this:


1 Answers

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

If you convert it to L first, 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 and convert a bool numpy array to PIL, you 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 exact 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)

So I would suggest using L as an intermediate datatype and then converting to 1 before saving if you need to save it in that format. Something like this:

>>> 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 convert 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>
like image 138
jterrace Avatar answered Sep 27 '22 22:09

jterrace