2

I'm doing some analysis of images, and I have a generator that gives me all pixels in image:

def pixels_g(img):
    w, h = img.shape
    for y in range(0, h):
        for x in range(0, w):
            yield img[y][x]

It's output if converted to list would be something like

[0, 1, 2, 5, 240, 5, ... ]

Now I'd like to get "frequency table" for it:

{
    0: 0,
    1: 5,
    2: 10,
    3: 0,
    4: 0,
    #snip
    255: 7
}

I've found some useful options in this question, but they all work with list, and I don't think that creating a list from my generator is a good idea - it can have millions of elements.

I'm therefore looking for a way to do this while preserving the benefits of generator. I'll process many images and don't want to hog resources too much.

Community
  • 1
  • 1
MightyPork
  • 18,270
  • 10
  • 79
  • 133

1 Answers1

0

Use Counter from "collections". It works with any iterable, not just lists.

from collections import Counter

pixels = pixels_g(img)
c = Counter(pixels)

print c[4]

If you need to reuse the contents of 'pixels' generator instance after running it through Counter, use 'tee' from itertools:

from collections import Counter
from itertools import tee

(pixels, hist) = tee(pixels_g(img))
c = Counter(pixels)
# can use hist for something else
pbkhrv
  • 647
  • 4
  • 11