Свернуть трехмерный массив с тремя ядрами (x, y, z) в python - PullRequest
1 голос
/ 18 февраля 2020

У меня есть 3D-изображение и три ядра k1, k2, k3 в направлении x, y и z.

img = np.random.rand(64, 64, 54) #three dimensional image
k1 = np.array([0.114, 0.141, 0.161, 0.168, 0.161, 0.141, 0.114]) #the kernel along the 1st dimension
k2 = k1 #the kernel along the 2nd dimension
k3 = k1 #the kernel along the 3nd dimension

Я могу использовать numpy.convolve итеративно для вычисления свертки следующим образом:

for i in np.arange(img.shape[0])
   for j in np.arange(img.shape[1])
      oneline=img[i,j,:]
      img[i,j,:]=np.convolve(oneline, k1, mode='same')

for i in np.arange(img.shape[1])
   for j in np.arange(img.shape[2])
      oneline=img[:,i,j]
      img[:,i,j]=np.convolve(oneline, k2, mode='same') 

for i in np.arange(img.shape[0])
   for j in np.arange(img.shape[2])
      oneline=img[i,:,j]
      img[i,:,j]=np.convolve(oneline, k3, mode='same') 

Есть ли более простой способ сделать это? Спасибо.

Ответы [ 2 ]

2 голосов
/ 19 февраля 2020

Вы можете использовать scipy.ndimage.convolve1d , который позволяет указать аргумент axis.

import numpy as np
import scipy

img = np.random.rand(64, 64, 54) #three dimensional image
k1 = np.array([0.114, 0.141, 0.161, 0.168, 0.161, 0.141, 0.114]) #the kernel along the 1st dimension
k2 = k1 #the kernel along the 2nd dimension
k3 = k1 #the kernel along the 3nd dimension

# Convolve over all three axes in a for loop
out = img.copy()
for i, k in enumerate((k1, k2, k3)):
    out = scipy.ndimage.convolve1d(out, k, axis=i)
1 голос
/ 18 февраля 2020

Вы можете использовать Scipy's convolve. Однако ядро ​​обычно имеет то же число измерений, что и входные данные. Вместо вектора для каждого измерения. Не уверен, как именно это отразится на том, что вы пытаетесь сделать, но я просто представил пример ядра для шоу:

# Sample kernel
n = 4
kern = np.ones((n+1, n+1, n+1))
vals = np.arange(n+1)
for i in vals:
    for j in vals:
        for k in vals:
            kern[i , j, k] = n/2 - np.sqrt((i-n/2)**2 + (j-n/2)**2 + (k-n/2)**2)

# 3d convolve
scipy.signal.convolve(img, kern, mode='same')
...