虽然循环可以工作,但遵循嵌套循环也可能很困难。您可能会考虑调用卷积定理来更轻松地执行卷积。看here http://en.wikipedia.org/wiki/Convolution_theorem.
使用 numpy 的 fft 模块,您可以计算原始图像堆栈的 n 维离散傅里叶变换,并将其乘以 n 维傅里叶变换(文档找到here https://docs.scipy.org/doc/numpy/reference/generated/numpy.fft.fftn.html)的内核相同尺寸。由于您的 2D 内核是一个 3x3 数组,因此它是一个 3x3xz 方形“柱子”。您只需用零填充该数组即可相应地增加维度。
尝试这个:
import numpy as np
import math
radius = 2
r2 = np.arange(-radius, radius+1)**2
sphere = r2[:, None, None] + r2[:, None] + r2
sphere -= np.max(sphere)
sphere = -sphere*2
array_len = 10*radius
array = np.zeros((array_len, array_len, array_len))
center = slice(array_len//2-radius,
array_len//2+radius+1), slice(array_len//2-radius,
array_len//2+radius+1),slice(array_len//2-radius,
array_len//2+radius+1)
array[center] = sphere
k_len = 3
kernel_2D = np.ones((k_len,k_len))
kernel = np.zeros_like(array)
center_k = slice(array_len//2-math.ceil(k_len/2),
array_len//2+k_len//2), slice(array_len//2-math.ceil(k_len/2),
array_len//2+k_len//2)
for i in range(kernel.shape[2]):
kernel[center_k+(i,)] = kernel_2D
def fft(array):
fft = np.fft.ifftshift(np.fft.fftn(np.fft.fftshift(array)))
return fft
def ifft(array):
ifft = np.fft.fftshift(np.fft.ifftn(np.fft.ifftshift(array)))
return ifft
def conv_3D(array, kernel):
conv = np.abs(ifft(fft(array)*fft(kernel)))
return conv
conv = conv_3D(array, kernel)
这将半径为 2 的球体与边长为 3 的柱子进行卷积。