如何将函数映射到OpenCV图像中的RGB值

时间:2019-05-04 03:42:55

标签: python arrays numpy opencv

我正在读取通过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的几何平均值数组。任何帮助将不胜感激!

1 个答案:

答案 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矢量化的美丽:)