Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 如何在python中执行快速剪切零边?_Arrays_Python 3.x_Numpy_Image Processing - Fatal编程技术网

Arrays 如何在python中执行快速剪切零边?

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的二值图像,前景区域位于一个小区域中,我有很多零边距。我想通过找到图像中像素不为零的点的最小和最大坐标来切割零边。它起作用了,但花了很多时间。我发布了我的代码,你能告诉我如何让它更快吗

对于
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
。对不起