4

I have an image that is stored as an ndarray. I would like to iterate over each pixel in this array.

I can iterate over each element of the array like this:

from scipy import ndimage
import numpy as np

l = ndimage.imread('sample.gif', mode="RGB")

for x in np.nditer(l):
    print x

This gives ie:

...
153
253
153
222
253
111
...

These are the values of each color in the pixels, one after the other. What I would like instead is to read these values 3 by 3 to produce something like this:

...
(153, 253, 153)
(222, 253, 111)
...
Juicy
  • 11,840
  • 35
  • 123
  • 212

3 Answers3

3

Probably the easiest is to reshape the numpy array first, and then go about printing.

http://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html

Also, this should help you. Reshaping a numpy array in python

Community
  • 1
  • 1
EngineeredE
  • 741
  • 5
  • 4
3

You can try zipping the list with itself:

from itertools import izip
for x in izip(l[0::3],l[1::3],l[2::3]):
    print x

Output:

(153, 253, 153)
(222, 253, 111)

UPDATE: Welp, I was bad at numpy in 2015. Here is my updated answer:

scipy.ndimage.imread is now deprecated and it is recommended to use imageio.imread. However for the purpose of this question I tested both and they behave the same.

Since we are reading the image in as RGB, we will get an array of heightxwidthx3, which is already what you want. You are losing the shape when you iterate over the array with np.nditer.

>>> img = imageio.imread('sample.jpg')
>>> img.shape
(456, 400, 3)
>>> for r in img:
...     for s in r:
...         print(s)
... 
[63 46 52]
[63 44 50]
[64 43 50]
[63 42 47]
...
Imran
  • 12,950
  • 8
  • 64
  • 79
1

While the answer @Imran works, it is not an intuitive solution... this could make it difficult to debug. Personally, I'd avoid any manipulation of the image, and then process with for loops.

Alternative 1:

img = ndimage.imread('sample.gif')
rows, cols, depth = np.shape(img)

r_arr, c_arr = np.mgrid[0:rows, 0:cols]

for r, c in zip(r_arr.flatten(), c_arr.flatten()):
    print(img[r,c])

Or you could do this directly with nested for loops:

for row in img:
    for pixel in row:
        print(pixel)

Note that these are flexible; they work for any 2D image regardless of depth.