将函数应用于数组中的窗口(如过滤器)

时间:2013-06-15 15:56:29

标签: python arrays image numpy convolution

假设我有一个图像作为Numpy数组加载到Python中。

我想在一个5x5窗口上运行一个函数,就像一个过滤器内核,但它不是真正的标准卷积。什么是最有效/ pythonic的方法呢?

一个具体的例子 - 我有一个带有相关3D坐标的点图像。我想计算图像上5x5窗口的平均法向量。我想象的是:

for each pixel in image:
    form an nxn window and extract a list of points
    fit a plane to the points
    calculate the normal
    associate this value with pixel (2,2) in the window

在Numpy中迭代数组通常是一种嗅觉,所以我希望有更好的方法来实现它。

1 个答案:

答案 0 :(得分:0)

如果你有scipy,你可以使用scipy.ndimage.filters.generic_filter

例如,

import numpy as np
import scipy.ndimage as ndimage

img = np.arange(100, dtype='float').reshape(10,10)
print(img)
# [[  0.   1.   2.   3.   4.   5.   6.   7.   8.   9.]
#  [ 10.  11.  12.  13.  14.  15.  16.  17.  18.  19.]
#  [ 20.  21.  22.  23.  24.  25.  26.  27.  28.  29.]
#  [ 30.  31.  32.  33.  34.  35.  36.  37.  38.  39.]
#  [ 40.  41.  42.  43.  44.  45.  46.  47.  48.  49.]
#  [ 50.  51.  52.  53.  54.  55.  56.  57.  58.  59.]
#  [ 60.  61.  62.  63.  64.  65.  66.  67.  68.  69.]
#  [ 70.  71.  72.  73.  74.  75.  76.  77.  78.  79.]
#  [ 80.  81.  82.  83.  84.  85.  86.  87.  88.  89.]
#  [ 90.  91.  92.  93.  94.  95.  96.  97.  98.  99.]]

def test(x):
    return x.mean()

result = ndimage.generic_filter(img, test, size=(5,5))
print(result)

打印

[[  8.8   9.2  10.   11.   12.   13.   14.   15.   15.8  16.2]
 [ 12.8  13.2  14.   15.   16.   17.   18.   19.   19.8  20.2]
 [ 20.8  21.2  22.   23.   24.   25.   26.   27.   27.8  28.2]
 [ 30.8  31.2  32.   33.   34.   35.   36.   37.   37.8  38.2]
 [ 40.8  41.2  42.   43.   44.   45.   46.   47.   47.8  48.2]
 [ 50.8  51.2  52.   53.   54.   55.   56.   57.   57.8  58.2]
 [ 60.8  61.2  62.   63.   64.   65.   66.   67.   67.8  68.2]
 [ 70.8  71.2  72.   73.   74.   75.   76.   77.   77.8  78.2]
 [ 78.8  79.2  80.   81.   82.   83.   84.   85.   85.8  86.2]
 [ 82.8  83.2  84.   85.   86.   87.   88.   89.   89.8  90.2]]

请务必查看mode参数,以控制当窗口离开边界边缘时应将哪些值传递给函数。

请注意,这主要是一个便利功能,用于组织计算。您仍在为每个窗口调用一次Python函数。这可能本来就很慢。