我的二进制图像尺寸为256x256x256
,其中前景区域位于一个较小的区域中,并且我有很多零边距。我想通过查找图像中像素非零的点的最小和最大坐标来削减零边缘。它虽然有效,但花费时间。我发布了代码,您能否告诉我如何使它更快?
对于256x256x256
的图像大小,大约需要0.13024640083312988秒。这是代码,您可以在https://repl.it/repls/AnxiousExoticBackup
import numpy as np
import time
def cut_edge(image, keep_margin):
'''
function that cuts zero edge
'''
D, H, W = image.shape
D_s, D_e = 0, D - 1
H_s, H_e = 0, H - 1
W_s, W_e = 0, W - 1
while D_s < D:
if image[D_s].sum() != 0:
break
D_s += 1
while D_e > D_s:
if image[D_e].sum() != 0:
break
D_e -= 1
while H_s < H:
if image[:, H_s].sum() != 0:
break
H_s += 1
while H_e > H_s:
if image[:, H_e].sum() != 0:
break
H_e -= 1
while W_s < W:
if image[:, :, W_s].sum() != 0:
break
W_s += 1
while W_e > W_s:
if image[:, :, W_e].sum() != 0:
break
W_e -= 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 int(D_s), int(D_e)+1, int(H_s), int(H_e)+1, int(W_s), int(W_e)+1
image = np.zeros ((256,256,256),dtype=np.float32)
ones_D_min, ones_D_max, ones_H_min, ones_H_max,ones_W_min, ones_W_max= 100,200, 90,150, 60,200
image[ones_D_min: ones_D_max,ones_H_min:ones_H_max, ones_W_min:ones_W_max]=1
t0=time.time()
ones_D_min_result, ones_D_max_result, ones_H_min_result, ones_H_max_result, ones_W_min_result, ones_W_max_result= cut_edge(image,0)
t1=time.time()
print ('Time consuming ', t1-t0)
print (ones_D_min, ones_D_max, ones_H_min, ones_H_max,ones_W_min, ones_W_max)
print (ones_D_min_result, ones_D_max_result, ones_H_min_result, ones_H_max_result, ones_W_min_result, ones_W_max_result)
答案 0 :(得分:3)
使用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
答案 1 :(得分:1)
您可以使用以下事实:如果sum
越过3D数组的轴,则该值仍将是0,其中行(或列或第三维)中没有1,具体取决于哪个{ {1}}参数。然后,通过在其他两个方向之一上使用axis
和any
,您将获得在另一个轴上至少有一个1的索引。使用np.argwhere
和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)
:
timeit
更快。