Вы можете использовать тот факт, что если вы sum
находитесь над осью вашего трехмерного массива, тогда значение все равно будет 0, если в строке нет ни 1 (ни столбца, ни третьего измерения), в зависимости от того, какой axis
параметр.Затем, используя 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)
и некоторые 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)
ЭтоБыстрее.