Python 从卷裁剪空数组(填充)
我要做的是裁剪一个卷以删除所有不相关的数据。例如,假设我有一个100x100x100的卷,其中有一个50x50x50的卷,其中有一个卷填充了零。 如何从原始卷获取裁剪的50x50x50卷 这是我想出的天真的方法Python 从卷裁剪空数组(填充),python,numpy,Python,Numpy,我要做的是裁剪一个卷以删除所有不相关的数据。例如,假设我有一个100x100x100的卷,其中有一个50x50x50的卷,其中有一个卷填充了零。 如何从原始卷获取裁剪的50x50x50卷 这是我想出的天真的方法 import numpy as np import tensorflow as tf test=np.zeros((100,100,100)) # create an empty 100x100x100 volume rand=np.random.rand(66,25,34) # cr
import numpy as np
import tensorflow as tf
test=np.zeros((100,100,100)) # create an empty 100x100x100 volume
rand=np.random.rand(66,25,34) # create a 66x25x34 filled volume
test[10:76, 20:45, 30:64] = rand # partially fill the empty volume
# initialize the cropping coordinates
minx=miny=minz=0
maxx=maxy=maxz=0
maxx,maxy,maxz=np.subtract(test.shape,1)
# compute the optimal cropping coordinates
dimensions=test.shape
while(tf.reduce_max(test[minx,:,:]) == 0): # check for empty slices along the x axis
minx+=1
while(tf.reduce_max(test[:,miny,:]) == 0): # check for empty slices along the y axis
miny+=1
while(tf.reduce_max(test[:,:,minz]) == 0): # check for empty slices along the z axis
minz+=1
while(tf.reduce_max(test[maxx,:,:]) == 0):
maxx-=1
while(tf.reduce_max(test[:,maxy,:]) == 0):
maxy-=1
while(tf.reduce_max(test[:,:,maxz]) == 0):
maxz-=1
maxx,maxy,maxz=np.add((maxx,maxy,maxz),1)
crop = test[minx:maxx,miny:maxy,minz:maxz]
print(minx,miny,minz,maxx,maxy,maxz)
print(rand.shape)
print(crop.shape)
这张照片是:
10 20 30 76 45 64
(66, 25, 34)
(66, 25, 34)
,这是正确的。然而,它花费的时间太长,可能是次优的。我正在寻找更好的方法来实现同样的目标
注意:
- 子体积不一定是长方体,它可以是任何形状
- 我想保持子体积内的间隙,只删除要裁剪的形状“外部”的部分
- 当您等待合理的响应时(我猜这是某个图像处理库中的内置函数),这里有一种方法
y, x = np.where(np.any(test, 0))
z, _ = np.where(np.any(test, 1))
test[min(z):max(z)+1, min(y):max(y)+1, min(x):max(x)+1]
我认为把tf排除在外会提高你的表现
说明(基于二维阵列) 我们想把它种下来
[[1, 2]
[3, 0]]
np.any(…,0)
这将在轴0上“迭代”,并返回True
(如果切片中的任何元素是空的)。我在这里的评论中显示了这一结果:
np.array([
[0, 0, 0, 0, 0, ], # False
[0, 0, 1, 2, 0, ], # True
[0, 0, 3, 0, 0, ], # True
[0, 0, 0, 0, 0, ], # False
[0, 0, 0, 0, 0, ], # False
])
i、 它返回np.array([False,True,True,False,False])
np.任何(…,1)
执行与步骤2相同的操作,但通过轴1而不是轴零,即
np.array([
[0, 0, 0, 0, 0, ],
[0, 0, 1, 2, 0, ],
[0, 0, 3, 0, 0, ],
[0, 0, 0, 0, 0, ],
[0, 0, 0, 0, 0, ],
# False False True True False
])
请注意,对于三维阵列,这些步骤返回二维阵列np.where([False,True,True,False,False])
返回(数组([1,2]),
。请注意,这是一个元组,因此在2D情况下,我们需要调用(x,)=…
因此x
只是数组数组([1,2])
。2D情况下的语法更好,因为我们可以使用元组解包,即x,y=…
\uu
的变量中,按照惯例,这个变量是一个合理的地方,用来存储你实际上不想要的垃圾输出。注意,我需要执行z,=
,因为我希望元组解包,而不仅仅是z=
,否则z
将成为具有两个数组的元组+1
,因为python中的切片不包括:
后面的索引def get_nonzero_sub(arr):
arr\u slices=元组(对于arr\u arr.nonzero()中的curr\u arr.min():curr\u arr.max()+1)
返回arr[arr_切片]
在您的示例中,您有一个连续的“相关”数据区域-如果中间有间隙会怎样?您只是想裁剪一个numpy数组吗?为什么tensorflow会卷入其中?@Dan我实际上是在使用这个裁剪功能作为tensorflow网络的一部分。但你说得绝对正确,我可以不用。@fuppes先生,如果不清楚的话,很抱歉。我想保持差距。我只想移除“周围”的空白区域。谢谢。你的版本似乎是最快的。在1000x1000x1000卷上进行一次短测试,您可以得到2.5s,@Alexander为16s和9s,@Tensorflow为47s。“我有点不清楚你在做什么,你介意解释一下吗?”杰穆勒补充道。注意,我还从原始答案中取出了>0
s,因为它们不需要。非常感谢,这很有效。然而,这比@Dan的建议慢了很多(10秒对2.8秒)。啊,这太不幸了!我目前正在研究一个更快的解决方案,我相信我会找到一些东西。
np.array([
[0, 0, 0, 0, 0, ],
[0, 0, 1, 2, 0, ],
[0, 0, 3, 0, 0, ],
[0, 0, 0, 0, 0, ],
[0, 0, 0, 0, 0, ],
# False False True True False
])