我正在读取通过opencv捕获的图像,并希望将函数映射到图像中的每个像素值。输出是一个m x n x 3 numpy数组,其中m和n是图像的长度和宽度的坐标,三个值是每个像素对应的蓝色,绿色和红色值。
我首先想到对图像中的每个值运行一个嵌套的for循环。但是,它需要很长时间才能运行,因此我正在寻找一种更有效的方法来快速遍历图像。
这是嵌套的for循环:
a = list()
for row in img:
for col in row:
a.append(np.sqrt(np.prod(col[1:])))
adjusted = np.asarray(a).reshape((img.shape[0], img.shape[1]))
此代码有效,但我想使其运行更快。我知道向量化可能是一种选择,但是我不知道如何将其仅应用于数组的一部分而不是整个数组。为此,我想可以将其重塑为img.reshape((np.prod(img.shape[:2]),3))
,然后遍历三个值的每组,但是我不知道要使用的正确函数/迭代器。
此外,如果opencv / numpy / scipy具有另一个执行此操作的功能,那将是一个很大的帮助。我也愿意接受其他选择,但我想提出一些想法。
最后,我要输入并计算红色和绿色值的几何平均值,并创建一个n x m的几何平均值数组。任何帮助将不胜感激!
答案 0 :(得分:2)
可以使用np.prod()
中的axis
参数将其向量化。设置axis=-1
将导致仅在最后一个轴上拍摄产品。
要仅在最后两个通道上执行此产品,请使用img[..., 1:]
您可以将代码替换为以下行:
adjusted = np.sqrt(np.prod(img[..., 1:], axis=-1))
为了娱乐,让我们使用一些模拟数据来介绍这两个功能:
import numpy as np
img = np.random.random((100,100,3))
def original_function(img):
a = []
for row in img:
for col in row:
a.append(np.sqrt(np.prod(col[1:])))
adjusted = np.asarray(a).reshape((img.shape[0], img.shape[1]))
return adjusted
def improved_function(img):
return np.sqrt(np.prod(img[:,:,1:], axis=-1))
>>> %timeit -n 100 original_function(img)
100 loops, best of 3: 55.5 ms per loop
>>> %timeit -n 100 improved_function(img)
100 loops, best of 3: 115 µs per loop
速度提高了500倍! numpy矢量化的美丽:)