2

I'm trying to count the number pixels in a weather radar image for each dbz reflectivity level (the colored blocks of green, orange, yellow, red, etc.) so I can "score" the radar image based on the type of echos.

I'm new to numpy and numpy arrays, but I know it can be very efficient when I'm working with the individual pixels in an image, so I'd like to learn more.

I'm not even sure I'm selecting the pixels correctly, but I think I'm getting close.

I have a sample of using both numpy and basic pixel iteration to count the number of green pixels with an RGBA of (1, 197, 1, 255).

Hopefully I'm close and someone can give me guidance on how to select the pixels using numpy and then count them:

import io
import numpy as np
import PIL.Image
import urllib2
import sys

color_dbz_20 = (2, 253, 2, 255)
color_dbz_25 = (1, 197, 1, 255)
color_dbz_30 = (0, 142, 0, 255)

url = 'http://radar.weather.gov/ridge/RadarImg/N0R/DLH_N0R_0.gif'
image_bytes = io.BytesIO(urllib2.urlopen(url).read())

image = PIL.Image.open(image_bytes)
image = image.convert('RGBA')

total_pixels = image.height * image.width

# Count using numpy
np_pixdata = np.array(image)

# Didn't work, gave me the total size:
# np_counter = np_pixdata[(np_pixdata == color_dbz_20)].size

np_counter = np.count_nonzero(np_pixdata[(np_pixdata == color_dbz_20)])

# Count using pillow
pil_pixdata = image.load()

pil_counter = 0
for y in xrange(image.size[1]):
    for x in xrange(image.size[0]):
        if pil_pixdata[x, y] == color_dbz_20:
            pil_counter += 1

print "Numpy Count: %d" % np_counter
print "Pillow Count: %d" % pil_counter

Output:

Numpy Count: 134573
Pillow Count: 9967

1 Answer 1

4

The problem is that the numpy array will be an array of size X * Y * 4 but you compare each element with a tuple - but it's only a number. That's the reason why your:

 np_counter = np_pixdata[(np_pixdata == color_dbz_20)].size

didn't exclude any elements.

That you got different counts in the end is because you counted nonzero-elements. But there are zeros in some array elements, just for one color but nevertheless 0 - which are excluded even though you don't want that!

First you want to compare numpy arrays so better convert the color-tuples too:

color_dbz_20 = np.array([2, 253, 2, 255]), ...

To get the real result for your condition you must use np.all along axis=2:

np.all(np_pixdata == color_dbz_20, axis=2)

This checks if the values along axis 2 (colors) are equal to the ones in your color_dbz_20 and this for each pixel. To get the sum of all the matches:

np.sum(np.all(np_pixdata == color_dbz_20, axis=2)) # Sum of boolean array is integer!

which gives you the number of pixel where the condition is True. True is interpreted as 1 and False as 0 - that way doing the sum will work - alternativly you could also count_nonzero instead of sum here. Always assuming you created your color_dbz_20-array as np.array.

Maybe the image has a different dimensionality and it's not width * height * depth then you just need to adjust the axis in the np.all to the dimension where the colors are (the one with length 4).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.