Сортировать массив точек в NumPy - PullRequest
0 голосов
/ 14 марта 2019

Я получил массив точек, объявленных так:

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 ]

2 голосов
/ 14 марта 2019
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 индексы. Использование отрицательного результата для сортировки от максимального к минимальному, как вы делали в ОП.

Тогда, наконец, мы можем перебрать точки:

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 голос
/ 14 марта 2019

Решение:

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
1 голос
/ 14 марта 2019

Не уверен, что я вас правильно понимаю, но вы хотите что-то вроде:

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])

Это сортирует 2d-индексы в found2 по значениям в точках в found, на которые они ссылаются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...