scipy.ndimage.correlate,但在计算时更新值



我需要一个3x3个相邻单元格之和的数组,其乘积基于相同大小的不同数组的内核(到目前为止,这正是scipy.ndimage.correlate(。但是,当计算新数组的值时,必须立即更新它,而不是在涉及该值的下一次计算中使用原始数组中的值。我自己编写了这个缓慢的代码来实现它,它运行得非常好(尽管对我来说太慢了(,并提供了预期的结果:

for x in range(width):
for y in range(height):
AArr[y,x] += laplaceNeighborDifference(x,y)
def laplaceNeighborDifference(x,y,z):
global w, h, AArr
return -AArr[y,x]+AArr[(y+1)%h,x]*.2+AArr[(y-1)%h,x]*.2+AArr[y,(x+1)%w]*.2+AArr[y,(x-1)%w]*.2+AArr[(y+1)%h,(x+1)%w]*.05+AArr[(y-1)%h,(x+1)%w]*.05+AArr[(y+1)%h,(x-1)%w]*.05+AArr[(y-1)%h,(x-1)%w]*.05

在我的方法中,内核是直接编码的。尽管作为一个数组(用作内核(,它会被写成这样:

[[.05,.2,.05],
[.2 ,-1,.2 ],
[.05,.2,.05]]

SciPy的实现方式如下:

AArr += correlate(AArr, kernel, mode='wrap')

但很明显,当我使用scipy.ndimage.correlate时,它完全基于原始数组来计算值,并且在计算时不会更新它们。至少我认为这就是我的实现和SciPy实现之间的区别,如果我错过了其他区别,请随意指出。我的问题是,是否有一个类似于前面提到的函数,并得到期望的结果,或者是否有一种比我更快的方法来编码它?

感谢您抽出时间!

您可以使用Numba来高效地执行此操作:

import numba as nb
@nb.njit
def laplaceNeighborDifference(AArr,w,h,x,y):
return -AArr[y,x]+AArr[(y+1)%h,x]*.2+AArr[(y-1)%h,x]*.2+AArr[y,(x+1)%w]*.2+AArr[y,(x-1)%w]*.2+AArr[(y+1)%h,(x+1)%w]*.05+AArr[(y-1)%h,(x+1)%w]*.05+AArr[(y+1)%h,(x-1)%w]*.05+AArr[(y-1)%h,(x-1)%w]*.05
@nb.njit('void(float64[:,::1],int64,int64)')
def compute(AArr,width,height):
for x in range(width):
for y in range(height):
AArr[y,x] += laplaceNeighborDifference(AArr,width,height,x,y)

请注意,模量通常非常慢。最好通过单独计算主循环的边界来去除它们。在没有任何模数的情况下,生成的代码应该更快。

最新更新