Arrays 如何在python中执行快速剪切零边?
我有一个大小为256x256x256的二值图像,前景区域位于一个小区域中,我有很多零边距。我想通过找到图像中像素不为零的点的最小和最大坐标来切割零边。它起作用了,但花了很多时间。我发布了我的代码,你能告诉我如何让它更快吗 对于Arrays 如何在python中执行快速剪切零边?,arrays,python-3.x,numpy,image-processing,Arrays,Python 3.x,Numpy,Image Processing,我有一个大小为256x256x256的二值图像,前景区域位于一个小区域中,我有很多零边距。我想通过找到图像中像素不为零的点的最小和最大坐标来切割零边。它起作用了,但花了很多时间。我发布了我的代码,你能告诉我如何让它更快吗 对于256x256x256的图像大小,大约需要0.13024640083312988秒。这是代码,您可以在 将numpy导入为np 导入时间 def切边(图像,保留边距): ''' 切零边的函数 ''' D、 H,W=图像形状 D_s,D_e=0,D-1 H_s,H_e=0,H
256x256x256
的图像大小,大约需要0.13024640083312988秒。这是代码,您可以在
将numpy导入为np
导入时间
def切边(图像,保留边距):
'''
切零边的函数
'''
D、 H,W=图像形状
D_s,D_e=0,D-1
H_s,H_e=0,H-1
W_s,W_e=0,W-1
当D_sD_s时:
如果图像[D_e].sum()!=0:
打破
D_e-=1
当H_sH_s时:
如果图像[:,H_e].sum()!=0:
打破
H_e-=1
当W_sW_s时:
如果图像[:,:,W_e].sum()!=0:
打破
W_e-=1
如果保持_边距!=0:
D_s=最大值(0,D_s-保持_余量)
D_e=最小值(D-1,D_e+保持裕度)
H_s=最大值(0,H_s-保持_裕度)
H_e=最小值(H-1,H_e+保持裕度)
W_s=最大值(0,W_s-保持裕度)
W_e=最小值(W-1,W_e+保持裕度)
返回int(D_-s),int(D_-e)+1,int(H_-s),int(H_-e)+1,int(W_-s),int(W_-e)+1
image=np.zeros((25625656),dtype=np.float32)
最小一个,最大一个,最小一个,最大一个,最大一个,最小一个,最小一个,最大一个=1002009015060200
图像[one_D_min:one_D_max,one_H_min:one_H_max,one_W_min:one_W_max]=1
t0=时间。时间()
一个最小值结果、一个最大值结果、一个最小值结果、一个最大值结果、一个最大值结果、一个最小值结果、一个最大值结果=剪切边(图像,0)
t1=时间。时间()
打印(“耗时”,t1-t0)
打印(最小值、最大值、最小值、最大值、最大值、最大值、最小值、最大值、最小值、最大值)
打印(一个最小值结果、一个最大值结果、一个最小值结果、一个最大值结果、一个最大值结果、一个最小值结果、一个最大值结果)
使用numpy的内置功能,您的功能可以得到显著改进:
def cut_edge(image, keep_margin):
'''
function that cuts zero edge
'''
#Calculate sum along each axis
D_sum = np.sum(image, axis=(1,2)) #0
H_sum = np.sum(image, axis=(0,2)) #1
W_sum = np.sum(image, axis=(0,1)) #2
#Find the non-zero values
W_nz = np.nonzero(W_sum)[0]
H_nz = np.nonzero(H_sum)[0]
D_nz = np.nonzero(D_sum)[0]
#Take the first and last entries for start and end
D_s = D_nz[0]
D_e = D_nz[-1]
H_s = H_nz[0]
H_e = H_nz[-1]
W_s = W_nz[0]
W_e = W_nz[-1]
if keep_margin != 0:
D_s = max(0, D_s - keep_margin)
D_e = min(D - 1, D_e + keep_margin)
H_s = max(0, H_s - keep_margin)
H_e = min(H - 1, H_e + keep_margin)
W_s = max(0, W_s - keep_margin)
W_e = min(W - 1, W_e + keep_margin)
return D_s, D_e+1, H_s, H_e+1, W_s, W_e+1
结果是:
Time consuming 0.0963144302368164
您可以使用这样一个事实,即如果对三维数组的某个轴进行求和,则该值仍将为0,其中行(或列或三维)中没有1,具体取决于哪个轴参数。然后,通过在另外两个方向中的一个方向上使用
any
和np.argwhere
可以得到另一个轴上至少有一个1的索引。使用min
和max
将给出您要查找的值。以下是函数:
def cut_edge_2(image, keep_margin):
im_sum0 = (image.sum(0) !=0)
im_sum1 = (image.sum(1) !=0)
ones_D = np.argwhere(im_sum1.any(1))
ones_H = np.argwhere(im_sum0.any(1))
ones_W = np.argwhere(im_sum0.any(0))
if keep_margin != 0:
D, H, W = image.shape
return (max( 0, ones_D.min() - keep_margin), min(D, ones_D.max() + keep_margin+1),
max( 0, ones_H.min() - keep_margin), min(H, ones_H.max() + keep_margin+1),
max( 0, ones_W.min() - keep_margin), min(W, ones_W.max() + keep_margin+1))
return (ones_D.min(), ones_D.max() +1,
ones_H.min(), ones_H.max() +1,
ones_W.min(), ones_W.max() +1)
print (cut_edge(image,0))
#(100, 200, 90, 150, 60, 200)
print (cut_edge_2(image,0))
#(100, 200, 90, 150, 60, 200)
print (cut_edge(image,60))
#(40, 256, 30, 210, 0, 256)
print (cut_edge_2(image,60))
#(40, 256, 30, 210, 0, 256)
得到的结果与函数相同:
def cut_edge_2(image, keep_margin):
im_sum0 = (image.sum(0) !=0)
im_sum1 = (image.sum(1) !=0)
ones_D = np.argwhere(im_sum1.any(1))
ones_H = np.argwhere(im_sum0.any(1))
ones_W = np.argwhere(im_sum0.any(0))
if keep_margin != 0:
D, H, W = image.shape
return (max( 0, ones_D.min() - keep_margin), min(D, ones_D.max() + keep_margin+1),
max( 0, ones_H.min() - keep_margin), min(H, ones_H.max() + keep_margin+1),
max( 0, ones_W.min() - keep_margin), min(W, ones_W.max() + keep_margin+1))
return (ones_D.min(), ones_D.max() +1,
ones_H.min(), ones_H.max() +1,
ones_W.min(), ones_W.max() +1)
print (cut_edge(image,0))
#(100, 200, 90, 150, 60, 200)
print (cut_edge_2(image,0))
#(100, 200, 90, 150, 60, 200)
print (cut_edge(image,60))
#(40, 256, 30, 210, 0, 256)
print (cut_edge_2(image,60))
#(40, 256, 30, 210, 0, 256)
还有一些timeit
:
%timeit cut_edge(image,0)
#93 ms ± 7.62 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit cut_edge_2(image,0)
#25.3 ms ± 8.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit cut_edge_2(image,1)
#26.2 ms ± 4.73 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit cut_edge(image,1)
#95.4 ms ± 6.63 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
它更快 太好了!。让我检查一下我的电脑T:我发现了一个bug。结果与设置不符。让我们在@John处查看一下,的确,这是一个糟糕的复制和粘贴。我在答案中修正了它。在
min
中,始终是D
,而不是H
,然后是W
。对不起