shapeが(10, 9, 14)のような3次元配列(volume)を周りをゼロで埋めて立方体にしたい場合
numpy.padが便利です。
numpy.pad(array, pad_width, mode='constant', **kwargs)
pad_widthに((1,1),(1,1),(1,1)) かつmodeを'constant'にすると周りを0で埋めてくれます。
次のような3次元配列があるとして
arr = [[[1 2] [3 4]] [[5 6] [7 8]]] arr = np.pad(arr, ((1, 1), (1, 1), (1, 1))) [[[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]] [[0 0 0 0] [0 1 2 0] [0 3 4 0] [0 0 0 0]] [[0 0 0 0] [0 5 6 0] [0 7 8 0] [0 0 0 0]] [[0 0 0 0] [0 0 0 0] [0 0 0 0] [0 0 0 0]]] #constant_value という引数があってpaddingの値として使われる,defaultはゼロだが、変更できる。 #linear_rampにするとend_values(defaultは0)に向かって、edge_valueと滑らかにつないでくれる arr = np.pad(arr, ((2, 2), (2, 2), (2, 2)), mode="linear_ramp") [[[0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 1 0 0] [0 0 1 2 1 0] [0 0 0 1 0 0] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 0 0 1 0 0] [0 0 1 2 1 0] [0 1 3 4 2 0] [0 0 1 2 1 0] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 1 2 3 1 0] [0 2 5 6 3 0] [0 3 7 8 4 0] [0 1 3 4 2 0] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 0 1 1 0 0] [0 1 2 3 1 0] [0 1 3 4 2 0] [0 0 1 2 1 0] [0 0 0 0 0 0]] [[0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0] [0 0 0 0 0 0]]] #edgeを選択するとedgeの値をそのままつなぐ arr = np.pad(arr, ((2, 2), (2, 2), (2, 2)), mode="edge") [[[1 1 1 2 2 2] [1 1 1 2 2 2] [1 1 1 2 2 2] [3 3 3 4 4 4] [3 3 3 4 4 4] [3 3 3 4 4 4]] [[1 1 1 2 2 2] [1 1 1 2 2 2] [1 1 1 2 2 2] [3 3 3 4 4 4] [3 3 3 4 4 4] [3 3 3 4 4 4]] [[1 1 1 2 2 2] [1 1 1 2 2 2] [1 1 1 2 2 2] [3 3 3 4 4 4] [3 3 3 4 4 4] [3 3 3 4 4 4]] [[5 5 5 6 6 6] [5 5 5 6 6 6] [5 5 5 6 6 6] [7 7 7 8 8 8] [7 7 7 8 8 8] [7 7 7 8 8 8]] [[5 5 5 6 6 6] [5 5 5 6 6 6] [5 5 5 6 6 6] [7 7 7 8 8 8] [7 7 7 8 8 8] [7 7 7 8 8 8]] [[5 5 5 6 6 6] [5 5 5 6 6 6] [5 5 5 6 6 6] [7 7 7 8 8 8] [7 7 7 8 8 8] [7 7 7 8 8 8]]] arr = np.pad(arr, ((2, 2), (2, 2), (2, 2)), mode="reflect") [[[1 2 1 2 1 2] [3 4 3 4 3 4] [1 2 1 2 1 2] [3 4 3 4 3 4] [1 2 1 2 1 2] [3 4 3 4 3 4]] [[5 6 5 6 5 6] [7 8 7 8 7 8] [5 6 5 6 5 6] [7 8 7 8 7 8] [5 6 5 6 5 6] [7 8 7 8 7 8]] [[1 2 1 2 1 2] [3 4 3 4 3 4] [1 2 1 2 1 2] [3 4 3 4 3 4] [1 2 1 2 1 2] [3 4 3 4 3 4]] [[5 6 5 6 5 6] [7 8 7 8 7 8] [5 6 5 6 5 6] [7 8 7 8 7 8] [5 6 5 6 5 6] [7 8 7 8 7 8]] [[1 2 1 2 1 2] [3 4 3 4 3 4] [1 2 1 2 1 2] [3 4 3 4 3 4] [1 2 1 2 1 2] [3 4 3 4 3 4]] [[5 6 5 6 5 6] [7 8 7 8 7 8] [5 6 5 6 5 6] [7 8 7 8 7 8] [5 6 5 6 5 6] [7 8 7 8 7 8]]]
という感じになる。
numpy.pad のmodeの説明
modeを使いこなすと、簡単にedgeの感じを調整できる
上で見たようにmodeを使うとpaddingする感じを色々調整できる。
滑らかにpadding領域と繋ぎたい場合はlinear_rampを使うと良い。
立方体でない3次元配列をpaddingする場合は以下のようにする。
import numpy as np
def padding(trimed_vol):
max_val = np.amax(trimed_vol.shape)
xd = max_val - trimed_vol.shape[0]
yd = max_val - trimed_vol.shape[1]
zd = max_val - trimed_vol.shape[2]
hxd = int((max_val - trimed_vol.shape[0])/2)
hyd = int((max_val - trimed_vol.shape[1])/2)
hzd = int((max_val - trimed_vol.shape[2])/2)
new_vol = np.pad(trimed_vol,((hxd, xd-hxd),(hyd, yd-hyd),(hzd, zd-hzd)),'constant')
return new_vol
コメント