简体   繁体   English

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

[英]How to map a function to RGB values in an opencv image

I am reading an image captured through opencv and want to map a function to every pixel value in the image.我正在读取通过 opencv 捕获的图像,并希望将函数映射到图像中的每个像素值。 The output is an mxnx 3 numpy array, where m and n are the coordinates of length and width of the image and the three values are the corresponding blue, green, and red values for each pixel.输出是一个 mxnx 3 numpy 数组,其中 m 和 n 是图像的长宽坐标,三个值是每个像素对应的蓝色、绿色和红色值。

I first thought to run a nested for loop to each value in the image.我首先想到对图像中的每个值运行一个嵌套的 for 循环。 However, it takes a long time to run, so I am looking for a more efficient way to loop over the image quickly.但是,运行需要很长时间,所以我正在寻找一种更有效的方法来快速循环图像。

Here is the nested for loop:这是嵌套的 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]))

This code works, but I would like to make it run faster.这段代码有效,但我想让它运行得更快。 I know vectorization could be an option, but I do not know how to apply it onto only part of an array and not a whole array.我知道矢量化可能是一种选择,但我不知道如何仅将其应用于数组的一部分而不是整个数组。 To do this, I think I could reshape it to img.reshape((np.prod(img.shape[:2]),3)) and then loop over each set of three values, but I do not know the correct function/iterator to use.为此,我想我可以将其重塑为img.reshape((np.prod(img.shape[:2]),3))然后循环遍历每组三个值,但我不知道正确的函数/迭代器使用。

Also, if opencv/numpy/scipy has another function that does just this, it would be a great help.此外,如果 opencv/numpy/scipy 有另一个功能可以做到这一点,那将是一个很大的帮助。 I'm also open to other options, but I wanted to give some ideas that I had.我也对其他选择持开放态度,但我想提出一些我的想法。

In the end, I want to take the input and calculate the geometric mean of the red and green values and create an nxm array of the geometric means.最后,我想获取输入并计算红色和绿色值的几何平均值并创建几何平均值的 nxm 数组。 Any help would be appreciated!任何帮助,将不胜感激!

This can be vectorized using the axis parameter in np.prod() .这可以使用np.prod()axis参数进行矢量化。 Setting axis=-1 will cause the product to only be taken on the last axis.设置axis=-1将导致产品只在最后一个轴上取。

To perform this product on only the last two channels, index the array to extract only those channels using img[..., 1:]要仅在最后两个通道上执行此乘积,请使用img[..., 1:]索引数组以仅提取那些通道

You can replace your code with the following line:您可以使用以下行替换您的代码:

adjusted = np.sqrt(np.prod(img[..., 1:], axis=-1))

For fun, let's profile these two functions using some simulated data:为了好玩,让我们使用一些模拟数据来分析这两个函数:

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

500x improvement in speed!速度提升 500 倍! The beauty of numpy vectorization :) numpy 向量化的美妙之处:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM