【问题标题】:Opencv python: apply arbitrary function to each pixel without iteratingOpencv python:将任意函数应用于每个像素而不进行迭代
【发布时间】:2016-01-28 05:33:36
【问题描述】:

在使用 numpy 的优化的同时,opencv 和 python 有没有一种方法可以对图像中的每个像素应用任意函数?

例如,我想获取单通道图像的 sigmoid:

out_image[:,:] = 1 / (1 + math.exp(-in_img[:,:]))

但这不起作用(不足为奇):TypeError: only length-1 arrays can be converted to Python scalars

有没有办法诱使 numpy 做这样的事情?

我当然可以遍历像素,这在 C++ 中可能很好,但在 python 中它非常慢。

【问题讨论】:

  • 尝试用np.exp替换math.exp
  • 这可以作为这个特定问题的解决方案。我是否还可以定义一个对单个像素进行操作的任意函数,并诱使 numpy 快速运行它?或者我写的任何函数都需要直接对 numpy 数组进行操作?

标签: python opencv numpy


【解决方案1】:

正如@Divakar 所建议的那样,将只知道标量的numpy.exp 替换为也知道ndarraynumpy.exp 是可行的方法。

附带说明,一些基准测试:

in_img = numpy.random.random((1000, 1000))

在 CPython 中:

%timeit (1 / (1 + numpy.exp(-in_img[:,:])))

10 个循环,3 个循环中的最佳值:每个循环 51.1 毫秒

使用 numexpr:

import numexpr
%timeit numexpr.evaluate("1 / (1 + exp(-in_img))")
10 loops, best of 3: 27.9 ms per loop

使用 Numba(假设您正确注释了您的函数,如下所示)

import numpy
from numba import vectorize, float64
@vectorize([float64(float64)])
def f(x):
    return 1 / (1 + numpy.exp(-x))

你得到:

%timeit f(in_img)
100 loops, best of 3: 5.34 ms per loop

使用pythran(假设你编译了以下函数)

#pythran export f(float[][])
def f(in_img):
    return 1 / (1 + numpy.exp(-in_img[:,:]))

编译:

pythran f.py -DUSE_BOOST_SIMD -march=native

然后把它放在板凳上:

100 loops, best of 3: 5.07 ms per loop

【讨论】:

  • 这可以作为这个特定问题的解决方案。我是否还可以定义一个对单个像素进行操作的任意函数,并诱使 numpy 快速运行它?或者我写的任何函数都需要直接对 numpy 数组进行操作吗?
猜你喜欢
  • 1970-01-01
  • 2020-03-27
  • 2020-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-13
  • 2022-01-21
  • 2016-08-19
相关资源
最近更新 更多