在numpy中对点数组进行排序

时间:2019-03-13 21:31:51

标签: python numpy

我得到了一系列这样声明的点:

found = np.empty(img_rgb.shape[:2])

它表示来自OpenCV模板匹配的值。 由于我只保留匹配中具有所需值的点,因此在进行迭代之前已将其重写:

found2 = np.where(found)

现在我像这样遍历它:

for pt in zip(*found2[::-1]):
    (x, y) = pt

但是如何对其进行排序,以使其从found[x][y]数组中的最低值到最高值进行迭代?

我尝试了np.argsort(),但似乎没有保留正确的x,y索引。实际上,我猜它根本不是按值排序的。

编辑:要清楚:

img_rgb = cv2.imread(os.path.join(DATA_DIR, 'some.png'))

(...)

res = cv2.matchTemplate(img_gray, tmpl, cv2.TM_CCOEFF)
loc = np.where(res > 230000)
for pt in zip(*loc[::-1]):
   (x, y) = pt
   found[y][x] = -res[y][x]

3 个答案:

答案 0 :(得分:1)

res = cv2.matchTemplate(img_gray, tmpl, cv2.TM_CCOEFF)
count = np.sum(res > 230000)
y, x = np.unravel_index((-res).argsort(None), res.shape)
for row, col in zip(y[:count], x[:count]):
    print(res[row, col], (row, col))

每行的说明:

count = np.sum(res > 230000)

获取要迭代的值的总数。

y, x = np.unravel_index((-res).argsort(None), res.shape)

在这里,argsort(None)将线性索引返回到对其进行排序的数组。我们想要(行,列)索引,而不是线性的,因此我们使用np.unravel_index()来获取2d索引。像在OP中一样,使用结果的负数从max到min进行排序。

最后,我们可以遍历以下几点:

for row, col in zip(y[:count], x[:count]):
    print(res[row, col], (row, col))

打印只是为了表明我们确实首先获得了最高值,并显示了这些相应值的(行,列)索引。


示例:

>>> import cv2
>>> import numpy as np
>>> img = np.uint8(255*np.random.rand(100, 100))
>>> tmp = np.uint8(255*np.random.rand(10, 10))
>>> res = cv2.matchTemplate(img, tmp, cv2.TM_CCOEFF)
>>> count = np.sum(res > 100000)
>>> y, x = np.unravel_index((-res).argsort(None), res.shape)
>>> for row, col in zip(y[:count], x[:count]):
>>>     print(res[row, col], (row, col))
206337.11 (19, 12)
177079.31 (76, 9)
173258.67 (63, 15)
...
100202.44 (56, 1)
100098.41 (0, 48)
100089.09 (68, 47)

请注意,这些最终值按(行,列)顺序排列,即与(x,y)点顺序相反,因此可以根据需要随意交换。

答案 1 :(得分:0)

不确定我是否正确理解您的意思,但是您想要以下内容吗?

he2325u_pyusb

这会根据它们引用的found = np.random.randint(0, 10, (3, 4)) found2 = np.where(found) found # array([[5, 6, 8, 6], # [0, 7, 7, 3], # [7, 6, 0, 5]]) found2 # (array([0, 0, 0, 0, 1, 1, 1, 2, 2, 2]), array([0, 1, 2, 3, 1, 2, 3, 0, 1, 3])) order = found[found2].argsort() x, y = found2[1][order], found2[0][order] found[y, x] # array([3, 5, 5, 6, 6, 6, 7, 7, 7, 8]) 中的点处的值对found2中的2d索引进行排序。

答案 2 :(得分:0)

解决方案:

sorted_pts = sorted(zip(*loc), key=lambda t:res[t])
print (sorted_pts)

尝试使用示例数据:

让我们以较小的比例获取一些样本数据(将res当作形状(3,4)数组,并将4当作threshold):

import numpy as np

res = np.arange(12).reshape(3,4)
print (res)

loc = np.where(res > 4)  # Dummy threshold == 4

sorted_pts = sorted(zip(*loc), key=lambda t:res[t[0],t[1]])
print (sorted_pts)

输出:

[[ 0  1  2  3]   # res
 [ 4  5  6  7]
 [ 8  9 10 11]]
# sorted_pts
[(1, 1), (2, 1), (3, 1), (0, 2), (1, 2), (2, 2), (3, 2)]

注意: (验证点是否根据res中的值排序)

[(1, 1), (2, 1), (3, 1), (0, 2), (1, 2), (2, 2), (3, 2)]
   |       |       |        |       |       |       |
   |       |       |        |       |       |       |
   V       V       V        V       V       V       V
   5       6       7        8       9       10      11