5

我有 2D numpy 数组和一个带有一些坐标 (i, j) 的中心(坐标表示行和列)。对于从 0 到图像边缘的每个可能距离,我需要对距中心相同距离(简单欧式距离)的所有数组元素求和,即结果是一维数组,其中第 0 个元素给出距离中的像素总和0 从中心(即只是中心),第一个元素是距离 1 像素处的所有像素的总和,依此类推。

我的感觉是,这应该可以在没有 for 循环的情况下完成,但不幸的是我不知道足够的矩阵 python 技巧来解决这个问题。

非常感谢你!

4

5 回答 5

3

我不确定这是否是您想要的,但它可能会有所帮助:

import numpy as np
#create data arrays to work with.
x = np.arange(10)
y = np.arange(10)
v = np.arange(100).reshape(10,10) 
#indices of the "center" of the grid
i,j = 5,5 

#Now calculated the distance of each point to the center point on the grid
#Note that `None` is the same as `np.newaxis`
r = np.sqrt((x[:,None] - x[i])**2 + (y[None,:]-y[j])**2)

#Now sum all the points that are closer than 10 units away.
np.sum(v[r<=10])
于 2012-09-18T15:56:03.423 回答
2

你可以使用np.bincount...

a = np.random.random((20, 22))

def distance(array, xpos, ypos):
    # probably a gazillion methods to create the actual distances...
    # if you array is large and you are only interested to a certain size
    # you sould probably slice out a smaller one first of course.
    dists = np.sqrt(np.arange(-xpos, array.shape [0]-xpos, dtype=float)[:,None]**2
          + np.arange(-ypos, array.shape [1]-ypos, dtype=float)[None,:]**2)
    return dists

# Prepare which bins to use:
dists = distance(a, 10, 11).astype(int)

# Do a bincount with weights.
result = np.bincount(dists.flat, weights=a.flat)
# and add them up:
result = np.add.accumulate(result)

Andresult是一个数组,result[distance]对所有距离更小或相等的值求和。

于 2012-09-18T19:02:06.363 回答
2

我会建议一个策略,但现在没有时间建议工作代码。执行以下操作:(请注意,您不能选择精确的距离,而是选择连续的、连续的距离范围,因为很少有点会处于精确的给定距离)。

  1. 从数组中创建一个KDTree;
  2. 取给定圆内每个点的总和,因为圆线性增加;
  3. 通过从外圆中减去内圆来计算每个圆之间的“外壳”值。

它应该是这样的(当然你必须填写一些空白):

import numpy
from scipy.spatial import KDTree

tree = scipy.spatial.KDTree(reshaped_array)
sums = [numpy.sum(tree.query_ball_point(dist)) for dist in xrange(desired_distances)]
desired_result = numpy.diff(sums)

希望这可以帮助!

于 2012-09-18T19:25:46.547 回答
1

创建一些样本点:

>>> import numpy as np
>>> vals = np.array([[1,2],[3,4.5],[5,6]])
>>> vals
array([[ 1. ,  2. ],
       [ 3. ,  4.5],
       [ 5. ,  6. ]])

计算中心点:

>>> center = np.mean(vals, axis=0)
>>> center
array([ 3.        ,  4.16666667])

计算距中心点的距离:

>>> d = vals - center
>>> dist_from_center = np.sqrt(d[:,0]*d[:,0] + d[:,1]*d[:,1])
>>> dist_from_center
array([ 2.94863434,  0.33333333,  2.71313677])
于 2012-09-18T16:03:56.467 回答
1

这不会很好地扩展到超大型阵列,而且它不是那么强大,但无论如何它有点可爱。

制作一个测试数组:

In [148]: import numpy as np

In [149]: m = np.random.random((8, 9))

In [150]: m
Out[150]: 
array([[ 0.36254361,  0.92449435,  0.36954906,  0.13007562,  0.95031795,
         0.1341706 ,  0.6417435 ,  0.25467616,  0.72431605],
       [ 0.75959927,  0.53992222,  0.76544104,  0.94409118,  0.27048638,
         0.44747388,  0.42691671,  0.75695594,  0.10366086],
       [ 0.12424304,  0.06642197,  0.08953764,  0.66546555,  0.30932551,
         0.50375697,  0.1344662 ,  0.31008366,  0.13953257],
       [ 0.28643294,  0.12986936,  0.39022482,  0.72869735,  0.84537494,
         0.62683481,  0.88539889,  0.35697751,  0.96332492],
       [ 0.67678959,  0.60373389,  0.15151052,  0.53586538,  0.50470088,
         0.39664842,  0.93584004,  0.97386657,  0.50405521],
       [ 0.04613492,  0.53676995,  0.60119919,  0.5559467 ,  0.09392262,
         0.69938864,  0.35719754,  0.79775878,  0.16634076],
       [ 0.00879703,  0.60874483,  0.25390384,  0.48368248,  0.52770161,
         0.64563258,  0.27353424,  0.86046696,  0.04489414],
       [ 0.80883157,  0.44484305,  0.52325907,  0.49172028,  0.46731106,
         0.06400542,  0.75671515,  0.55930335,  0.70721442]])

获取索引:

In [151]: centre = (3,5)

In [152]: ii = np.indices(m.shape)

In [153]: ii
Out[153]: 
array([[[0, 0, 0, 0, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1, 1, 1, 1, 1],
        [2, 2, 2, 2, 2, 2, 2, 2, 2],
        [3, 3, 3, 3, 3, 3, 3, 3, 3],
        [4, 4, 4, 4, 4, 4, 4, 4, 4],
        [5, 5, 5, 5, 5, 5, 5, 5, 5],
        [6, 6, 6, 6, 6, 6, 6, 6, 6],
        [7, 7, 7, 7, 7, 7, 7, 7, 7]],

       [[0, 1, 2, 3, 4, 5, 6, 7, 8],
        [0, 1, 2, 3, 4, 5, 6, 7, 8],
        [0, 1, 2, 3, 4, 5, 6, 7, 8],
        [0, 1, 2, 3, 4, 5, 6, 7, 8],
        [0, 1, 2, 3, 4, 5, 6, 7, 8],
        [0, 1, 2, 3, 4, 5, 6, 7, 8],
        [0, 1, 2, 3, 4, 5, 6, 7, 8],
        [0, 1, 2, 3, 4, 5, 6, 7, 8]]])

In [154]: di = ii[0]-centre[0], ii[1]-centre[1]

获取平方距离:

In [155]: dr2 = (di[0]**2+di[1]**2)

In [156]: dr2
Out[156]: 
array([[34, 25, 18, 13, 10,  9, 10, 13, 18],
       [29, 20, 13,  8,  5,  4,  5,  8, 13],
       [26, 17, 10,  5,  2,  1,  2,  5, 10],
       [25, 16,  9,  4,  1,  0,  1,  4,  9],
       [26, 17, 10,  5,  2,  1,  2,  5, 10],
       [29, 20, 13,  8,  5,  4,  5,  8, 13],
       [34, 25, 18, 13, 10,  9, 10, 13, 18],
       [41, 32, 25, 20, 17, 16, 17, 20, 25]])

并用于bincount获得总和:

In [158]: np.bincount(dr2.flat, m.flat)
Out[158]: 
array([ 0.62683481,  2.63117922,  1.88433263,  0.        ,  2.23253738,
        3.63380441,  0.        ,  0.        ,  3.05475259,  2.13335292,
        3.27793323,  0.        ,  0.        ,  3.36554308,  0.        ,
        0.        ,  0.19387479,  1.89418207,  1.3926631 ,  0.        ,
        2.12771579,  0.        ,  0.        ,  0.        ,  0.        ,
        3.05014562,  0.80103263,  0.        ,  0.        ,  0.8057342 ,
        0.        ,  0.        ,  0.44484305,  0.        ,  0.37134064,
        0.        ,  0.        ,  0.        ,  0.        ,  0.        ,
        0.        ,  0.80883157])
于 2012-09-18T17:05:24.860 回答