[英]3D convolution in python
我需要編寫一個代碼來使用 numpy 和 3x3 內核在 python 中執行 3D 卷積。 我已經對像黑白圖像這樣的 2D 陣列做了正確的處理,但是當我嘗試將它擴展到像 RGB 這樣的 3D 陣列時是一團糟。 我需要幫助來改進我的方法。 這是二維代碼:
def convolucion_3x3(arreglo, kernel):
(dim_x, dim_y) = arreglo.shape
(ker_x, ker_y) = kernel.shape
matriz_convolucionada = np.zeros((dim_x, dim_y))
for i in range(dim_x):
for j in range(dim_y):
resultado = 0
for x in range(-1, 2):
try:
if i + x not in range(dim_x):
raise ValueError()
for y in range(-1, 2):
try:
if j + y not in range(dim_y):
raise ValueError()
resultado += arreglo[i + x, j + y] * kernel[x + 1][y + 1]
'''
Para el kernel sumo un 1 a cada índice para que lo corra desde 0 hasta 2 y no de -1 a 1
'''
except ValueError:
pass
except ValueError:
pass
matriz_convolucionada[i][j] = resultado
return matriz_convolucionada
下一個是我對 RGB 圖像的嘗試:
def卷積(arreglo,內核):(dim_x,dim_y,dim_z)= arreglo.shape(ker_x,ker_y)= kernel.shape
matriz_convolucionada = np.zeros((dim_x, dim_y, dim_z))
for k in range(dim_z):
for i in range(dim_x):
for j in range(dim_y):
resultado = 0
for x in range(-1, 2):
try:
if i + x not in range(dim_x):
raise ValueError()
for y in range(-1, 2):
try:
if j + y not in range(dim_y):
raise ValueError()
resultado += arreglo[i + x, j + y, k] * kernel[x + 1][y + 1]
'''
Para el kernel sumo un 1 a cada índice para que lo corra desde 0 hasta 2 y no de -1 a 1
'''
except ValueError:
pass
except ValueError:
pass
matriz_convolucionada[i][j][k] = resultado
return matriz_convolucionada
雖然循環可以工作,但也很難遵循嵌套循環。 您可能會考慮調用卷積定理來更輕松地執行卷積。 見這里。
使用 numpy 的 fft 模塊,您可以計算原始圖像堆棧的 n 維離散傅里葉變換,並將其乘以相同大小的內核的 n 維傅里葉變換( 此處提供文檔)。 由於您的 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 的柱子進行卷積。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.