我有一个大小为8x512x512的3d堆栈,并希望基于两个单独的对应2d 512x512数组为每个8x --512x512-数组设置值。
Array1是具有所需形状的二进制,而Array2具有通过3d数组投影的值。我希望来自Array2的值出现在Array1值等于1的3d数组中的每个512x512切片上。因此,如果Array1是一个边界框,而Array2是一张猫脸,其面位于边界框的区域内...我希望将猫脸投影到8x512x512阵列的每个8x切片上。
我认为这是一个简单的问题,但只能想到我认为是愚蠢的方法:
Array1 = np.zeros((512,512)); Array1[10:20,40:60]=1
Array2 = np.load(somecatpicture)
Array3d = np.random.rand(8,512,512)
for imnum in range(Array3d.shape[0]):
tmp = np.copy(Array3d[imnum,...])
tmp[Array1==1] = Array2[Array1==1]
Array3d[imnum,...] = tmp
或:
Array1 = np.zeros((512,512)); Array1[10:20,40:60]=1
Array2 = np.load(somecatpicture)
Array3d = np.random.rand(8,512,512)
stack1 = np.array([Array1 for i in range(Array3d.shape[0])])
stack2 = np.array([Array2 for i in range(Array3d.shape[0])])
Array3d[stack1==1] = stack2[stack1==1]
我认为有某种方法可以做到无需循环或列表理解:
Array3d[:,[Array1==1]]=Array2[Array1==1]
?
让我们尝试一个可以可视化的较小示例
图像和蒙版。 mask==1
等同于将其转换为布尔值:
In [280]: img = np.arange(12).reshape(3,4)*10
In [281]: mask = np.zeros((3,4),int); mask[1,1:3]=1
In [282]: mask = mask.astype(bool)
In [283]: mask
Out[283]:
array([[False, False, False, False],
[False, True, True, False],
[False, False, False, False]])
所以图像的所选部分是:
In [284]: img[mask]
Out[284]: array([50, 60])
定义3d目标数组:
In [285]: arr = np.arange(24).reshape(2,3,4)
In [286]: arr
Out[286]:
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])
应用蒙版-第一维的[[0],[1]]
索引:
In [287]: arr[np.arange(arr.shape[0])[:,None],mask]
Out[287]:
array([[ 5, 6],
[17, 18]])
并执行插入操作:
In [288]: arr[np.arange(arr.shape[0])[:,None],mask]=img[mask]
In [289]: arr
Out[289]:
array([[[ 0, 1, 2, 3],
[ 4, 50, 60, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 50, 60, 19],
[20, 21, 22, 23]]])
np.arange(arr.shape[0])[:,None]
是将插入应用于所有块的键。