我有一个数组的中心点,
center_point = (array.shape[0]/2.,array.shape[1]/2.)
我有一个二进制图像数组array
,其形状的相关像素设置为0(所有其他像素都是255)。
我需要从数组中心到所有像素设置为零的平均距离,我需要它进行矢量化(它不能在python级别解释 - 慢慢的方式)。
这就是我所拥有的,现在我被卡住了,因为我发现其他答案指向SciPy,但服务器仅支持numpy。
centerpoint = array_center_point(shape_array)
distance_shape = np.zeros(size=shape_array.shape,dtype=float)
distance_shape[shape==0] = ...???
avg_distance = np.sum(distance_shape) / len(np.where(shape_array == 0)[0])
我无法在不对np.where进行多次调用并使用python for循环遍历形状索引的情况下弄清楚如何执行此操作。必须有一种方法可以在numpy代码中完成这个... ??
以下是适用的非矢量化版本:
def avg_distance_from_center(shape_array):
center_point = array_center_point(shape_array)
distance_shape = np.zeros(shape=shape_array.shape, dtype=float)
shape_pixels = np.where(shape_array == 0)
total_distance = 0.
for i in range(len(shape_pixels[0])):
i_ind = float(shape_pixels[0][i])
j_ind = float(shape_pixels[1][i])
total_distance += ((i_ind - center_point[0])**2.0 + (j_ind - center_point[1])**2.0)**0.5
avg_distance = total_distance / len(shape_pixels[0])
return avg_distance
答案 0 :(得分:4)
方法#1:使用NumPy broadcasting
-
np.sqrt(((np.argwhere(shape_array==0) - center_point)**2).sum(1)).mean()
方法#2:使用np.einsum
-
subs = (np.argwhere(a==0) - center_point)
out = np.sqrt(np.einsum('ij,ij->i',subs,subs)).mean()
答案 1 :(得分:3)
仅用于说明我使用随机数组:
>>> import numpy as np
>>> arr = (np.random.random((5, 5)) > 0.5).astype(int)
>>> arr
array([[0, 0, 0, 1, 0],
[0, 0, 1, 1, 1],
[0, 1, 0, 0, 1],
[1, 0, 0, 1, 0],
[1, 0, 1, 0, 1]])
>>> center = (2, 2) # use your center here
要获得距离,我将使用meshgrid:
>>> grid_x, grid_y = np.mgrid[0:arr.shape[0], 0:arr.shape[1]]
>>> grid_x
array([[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]])
>>> grid_y
array([[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]])
我们将网格移动到中心的坐标:
>>> grid_x = grid_x - center[0]
>>> grid_y = grid_y - center[1]
最后,我们使用np.hypot
函数计算距离(几乎与np.sqrt(x**2 + y**2)
相同),但仅使用arr == 0
处的点:
>>> distances = np.hypot(grid_x[arr == 0], grid_y[arr == 0])
现在是时候计算距离的平均值/平均值了:
>>> np.mean(distances)
2.767080465988093