12

I have a NumPy array of 3,076,568 binary values (1s and 0s). I would like to convert this to a matrix, and then to a grayscale image in Python.

However, when I try to reshape the array into a 1,538,284 x 1,538,284 matrix, I get a memory error.

How can I reduce the size of the matrix so that it will turn into an image that will fit on a screen without losing the uniqueness/data?

Furthermore, how would I turn it into a grayscale image?

Any help or advice would be appreciated. Thank you.

4 Answers4

23

Your array of "binary values" is an array of bytes?

If so, you can do (using Pillow) after resizing it:

from PIL import Image
im = Image.fromarray(arr)

And then im.show() to see it.

If your array has only 0's and 1's (1-bit depth or b/w) you may have to multiply it to 255

im = Image.fromarray(arr * 255)

Here an example:

>>> arr = numpy.random.randint(0,256, 100*100) #example of a 1-D array
>>> arr.resize((100,100))
>>> im = Image.fromarray(arr)
>>> im.show()

Random image

Edit (2018):

This question was written in 2011 and Pillow changed ever since requiring to use the mode='L' parameter when loading with fromarray.

Also on comments below it was said arr.astype(np.uint8) was needed as well, but I have not tested it

JBernardo
  • 32,262
  • 10
  • 90
  • 115
  • 4
    I'm getting an error "Cannot handle this data type" when trying the example above. I needed to pass mode="L" like: im = Image.fromarray(arr, mode="L") – barbolo Jul 08 '16 at 11:31
  • @barbolo mine didn't raise an error, it just made the whole picture white. But using mode "L" fixed it, thanks! – Arthur Dent May 26 '17 at 19:47
  • 1
    I had to use `arr.astype(np.uint8)` and `mode='L'` (as mentioned above) to get the correct output (see https://stackoverflow.com/questions/47290668/image-fromarray-just-produces-black-image). – dexteritas Apr 05 '18 at 14:13
12

Using PIL is not really needed, you can plot the array directly with pyplot (see below). To save to a file, you could use plt.imsave('fname.png', im).

enter image description here

Code below.

import numpy as np
import matplotlib.pyplot as plt

x = (np.random.rand(1754**2) < 0.5).astype(int)

im = x.reshape(1754, 1754)
plt.gray()
plt.imshow(im)

You can also use plt.show(im) to display image in new window.

wim
  • 338,267
  • 99
  • 616
  • 750
3

You can do so with scipy.misc.toimage and im.save("foobar.png"):

#!/usr/bin/env python

# your data is "array" - I just made this for testing
width, height = 512, 100
import numpy as np
array = (np.random.rand(width*height) < 0.5).astype(int)
array = array.reshape(height, width)

# what you need
from scipy.misc import toimage

im = toimage(array)
im.save("foobar.png")

which gives

enter image description here

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
1

If you have as example a txt file in your PC with some data (an image), in order to visualize such data as gray scale image you can use this:

with open("example.txt", "r") as f:
data = [i.strip("\n").split() for i in f.readlines()]
data1 = np.array(data, dtype=float)
plt.figure(1)
plt.gray()
plt.imshow(data1)
plt.show()
vittorio
  • 143
  • 3
  • 14