0

I want to load a .PNG into a 2D structure of 1D structures of RGB values. For example, a 16x16 image would be represented as a 16x16x3 array, where the deepest subarray of length 3 is the RGB values.

I know of PIL and numpy, and tried something along the lines of:

from PIL import Image
from numpy import asarray

# ...

loaded_image = asarray(Image.open('filename.png'))

This does indeed make a 16x16x3 numpy array, but its of values between 0..255. I try to then iterate over them and make them between 0.00..1.00:

for row in range(len(loaded_image)):
  for col in range(len(loaded_image[0])):
    for channel in range(len(loaded_image[0][0])):
      loaded_image[row][col][channel] /= 256

But this tells me the array is read-only.

Is there a better method for this? If it matters, I only really care about greyscale (R = G = B), so it could actually be a 16x16x1 structure. Is there a method using Python standard libraries?

gator
  • 3,465
  • 8
  • 36
  • 76
  • "I try to then iterate over them" Have you used Numpy for other tasks before? The entire point is not to write iteration yourself, but rely on Numpy broadcasting. "But this tells me the array is read-only." Did you try making a copy? Or using an operation that produces a new array? – Karl Knechtel Mar 27 '21 at 22:05
  • @KarlKnechtel no, I'm not terribly familiar with `numpy` and in fact I'd love to find an alternative that didn't require it. I looked around for ways to load an image into an array and `numpy` and `PIL` is what I found. – gator Mar 27 '21 at 22:06
  • Also, what happened when you tried putting things like `pil numpy convert greyscale`, or `pil numpy rescale channels` into a search engine? – Karl Knechtel Mar 27 '21 at 22:07
  • The PIL documentation [has an example](https://pillow.readthedocs.io/en/3.1.x/handbook/tutorial.html#converting-between-modes) of the greyscale conversion which you can do before any Numpy stuff. For the rest, see the linked duplicate for an example (the problem you're facing is even simpler, I think). – Karl Knechtel Mar 27 '21 at 22:14
  • There are other image-loading libraries, but as far as I've seen, they all give you the underlying data as a Numpy array. You should learn how to work with this because it is much more convenient and powerful than using native Python lists for this kind of data. – Karl Knechtel Mar 27 '21 at 22:17

1 Answers1

2

The method numpy.asarray produces a read-only array. Try using numpy.array and then just divide it by 255, as in:

import numpy as np
from PIL import Image

loaded_image = np.array(Image.open('filename.png'))
loaded_image = loaded_image / 255.
leed
  • 312
  • 2
  • 6