1

假设我有一个图像作为 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 中迭代数组通常是一种气味,所以我希望有更好的方法来做到这一点。

4

1 回答 1

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 函数。这可能天生就很慢。

于 2013-06-15T16:29:40.067 回答