I'm trying to convert a colored image to a black and white one.
The original image is the following:
I have a few problems. First:
import pylab as pl
import Image
im = Image.open('joconde.png')
pl.imshow(im)
pl.axis('off')
pl.show()
I get this:
Why is it rotated? That's not the point but I'd like to know why.
im_gray = im.convert('1')
pl.imshow(im_gray)
pl.show()
And here is the processed black and white image:
Now everything looks working. But I need to use that image as a numpy array in order to do some image processing. All I have to do is this:
import numpy as np
im_arr = np.array(im_gray)
pl.imshow(im_arr)
pl.axis('off')
pl.show()
But I get this:
Why is this happening? I tried also:
im_arr = np.array(im_gray, dtype='float')
or:
im_arr = np.asarray(im_gray)
But nothing seems working. Maybe the problem is in the show
method but I don't know.
Images are an easier way to represent the working model. In Machine Learning, Python uses the image data in the format of Height, Width, Channel format. i.e. Images are converted into Numpy Array in Height, Width, Channel format.
Converting an image to an array is an important task to train a machine learning model based on the features of an image. We mainly use the NumPy library in Python to work with arrays so we can also use it to convert images to an array. Other than NumPy, we can also use the Keras library in Python for the same task.
Your image is rotated because of an origin problem.
If you use this snippet, the image will not be rotated upside-down.
pl.imshow(im, origin='lower')
pl.show()
You could also simply use im.show()
to display the image.
Now, back to the original question. I think the problem comes from the fact that pylab cannot handle bilevel images. You certainly want to use a greyscale image and thus do this
import pylab as pl
import matplotlib.cm as cm
import numpy as np
import Image
im = Image.open('your/image/path')
im_grey = im.convert('L') # convert the image to *greyscale*
im_array = np.array(im_grey)
pl.imshow(im_array, cmap=cm.Greys_r)
pl.show()
The problem is in the way you convert the image into numpy array. If you look at what the outputs from the functions are this becomes clear
>> np.array(im_gray)
array([[False, False, False, ..., True, False, False],
[ True, True, True, ..., True, True, False],
[ True, True, True, ..., True, True, False],
...,
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False],
[False, False, False, ..., False, False, False]], dtype=bool)
That can't be right. pl.imshow
takes an array of floats
uint8
or PIL
image, not an array of booleans. So you need to do the conversion into an array more explicitly, making sure to
cols,rows = im_gray.size
pixels = list(im_gray.getdata())
# an indexer into the flat list of pixels
# head ranges from 0 to len(pixels) with step cols
# tail ranges from cols to len(pixels) with step cols
head_tail = zip(range(0,len(pixels)+1,cols),range(cols,len(pixels)+1,cols))
im_data = np.ndarray(shape=(cols,rows), dtype=np.uint8)
# extract each row of pixels and save it to the numpy array
for i,(head,tail) in enumerate(head_tail):
im_data[i] = np.array(pixels[head:tail], dtype=np.uint8)
pl.imshow(im_data, cmap='bone')
The final pl.imshow
requires you to define a colormap. The 'bone'
colormap is black and white. I presume passing a PIL
image into the functions defines the colormap automagically.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With