我正在尝试计算天气雷达图像中每个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
答案 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
)。