我一直试图找到一种更有效的方法来迭代图像并将其属性分割为阈值。在网上搜索并与一些编程朋友讨论时,他们向我介绍了向量化(特别是使用numpy)函数的概念。经过大量的搜索和反复试验,我似乎无法掌握它。有人可以给我一个链接,或建议如何使以下代码更有效率?
Im = plt.imread(img)
Imarray = np.array(Im)
for line in Imarray:
for pixel in line:
if pixel <= 20000:
dim_sum += pixel
dim_counter += 1
if pixel > 20000:
bright_sum += pixel
bright_counter += 1
bright_mean = bright_sum/bright_counter
dim_mean = dim_sum/dim_counter
基本上,每个像素保持0到30000之间的亮度,并且我试图分别平均低于20000和高于20000的所有像素。我知道如何做到这一点的最好方法是使用for循环(在python中很慢)并使用if语句搜索每个像素。
答案 0 :(得分:6)
NumPy通过其arrays
和ufuncs
支持并鼓励向量化。在您的情况下,您将NumPy数组作为输入图像。因此,这些比较可以一次性/矢量化方式完成,以便为我们提供与输入数组相同形状的布尔数组。那些用于索引输入数组的布尔数组将从中选择有效元素。这被称为boolean-indexing
,并在这种矢量化选择中形成一个关键特征。
最后,我们使用NumPy ufunc ndarray.mean
再次以矢量化方式操作,为我们提供所选元素的平均值。
因此,要将所有这些放入代码中,我们会有 -
bright_mean, dim_mean = Im[Im > 20000].mean(), Im[Im <= 20000].mean()
对于这个特定问题,从代码效率的角度来看,执行一次比较会更有意义。比较会给我们一个布尔数组,可以在以后使用两次,一次使用,第二次反转。因此,我们也可以 -
mask = Im > 20000
bright_mean, dim_mean = Im[mask].mean(), Im[~mask].mean()