从加载到numpy数组中的图像中按颜色计算像素数

时间:2016-03-16 22:07:05

标签: python numpy

我正在尝试计算天气雷达图像中每个dbz反射率水平的数字像素(绿色,橙色,黄色,红色等的彩色块),这样我就可以根据回声的类型。

我是numpy和numpy数组的新手,但我知道当我处理图像中的单个像素时它非常有效,所以我想了解更多。

我甚至不确定我是否正确选择了像素,但我认为我已经接近了。

我有一个使用numpy和基本像素迭代的样本来计算RGBA为(1,197,1,255)的绿色像素数。

希望我很接近,有人可以给我指导如何使用numpy选择像素,然后计算它们:

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

输出:

Numpy Count: 134573
Pillow Count: 9967

1 个答案:

答案 0 :(得分:3)

问题是numpy数组将是一个大小为X * Y * 4的数组,但是你将每个元素与一个元组进行比较 - 但它只是一个数字。这就是你的原因:

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

没有排除任何元素。

你最后有不同的计数是因为你计算了nonzero - 元素。但是在某些数组元素中有零,只有一种颜色,但仍为0 - 即使你不想要它也被排除在外!

首先,您要比较numpy数组,以便更好地转换color - 元组:

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

要获得条件的真实结果,您必须沿轴= 2使用np.all

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

这将检查沿轴2(颜色)的值是否等于color_dbz_20中的值以及每个像素的值。得到所有比赛的总和:

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

,它为您提供条件为True的像素数。 True被解释为1,False被解释为0 - 这样做总和就行了 - 换句话说你也可以count_nonzero而不是sum。始终假设您已将color_dbz_20 - 数组创建为np.array

也许图片具有不同的维度且不是width * height * depth,您只需将axis中的np.all调整为colors所在的维度(一个长度为4)。

相关问题