Numpy: Выбор abritrary формы на основе формы углов

голоса
1

Я использую Numpy индексации на некоторое время теперь. Но я только когда - либо приходилось выбирать основные формы , такие как прямоугольники или диски

Тем не менее, я теперь должен иметь возможность выбрать более произвольные формы, и я не могу найти хороший способ сделать это. В идеале, я хотел бы быть в состоянии дать список углов и для всех показателей, содержащихся в этих углах должны быть выбраны. Можно предположить, данная форма является выпуклой

Например, если массив, заполненный нули формы (10, 10), пытаясь установить значение в пределах углов ((2,2), (6,3), (4,8) и (7,9) ) 1 заносить бы маску, как, например

  [[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
   [0., 0., 1., 1., 1., 0., 0., 0., 0., 0.],
   [0., 0., 1., 1., 1., 1., 0., 0., 0., 0.],
   [0., 0., 1., 1., 1., 1., 1., 1., 1., 0.],
   [0., 0., 0., 1., 1., 1., 1., 1., 1., 0.],
   [0., 0., 0., 1., 1., 1., 1., 1., 1., 1.],
   [0., 0., 0., 0., 0., 0., 1., 1., 1., 1.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
   [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]]

Сейчас одна из проблем состоит в том, что там вообще не единственное решение этой проблемы, но принимая правдоподобной достаточно хорошо для меня. Я не могу придумать способ сделать это с помощью NumPy однако, как кажутся, поддерживаются только базовые разрезания и четкие математические уравнения.

Кто-нибудь когда-нибудь столкнуться с такой проблемой? Есть ли у меня прибегнуть к более традиционным питона для петель?

Задан 09/10/2019 в 12:51
источник пользователем
На других языках...                            


1 ответов

голоса
2

Правда уродливое решение, но как насчет создания бинарных масок для выбора из вашего многоугольника с помощью OpenCV и используя эту один?

import cv2
import numpy as np

corners = np.asarray([(2,2), (6,3), (4,8), (7,9)])

target = np.zeros([10,10])
mask = cv2.fillPoly(np.zeros_like(target, dtype=np.uint8), [corners], 255).astype(bool)

target[mask] = 1

генерирует:

>>> target
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 1., 1., 1., 0., 0., 0., 0., 0.],
       [0., 0., 0., 1., 1., 1., 1., 0., 0., 0.],
       [0., 0., 0., 1., 1., 1., 1., 0., 0., 0.],
       [0., 0., 0., 0., 1., 1., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 1., 0., 0., 0., 0.],
       [0., 0., 0., 0., 1., 1., 1., 0., 0., 0.],
       [0., 0., 0., 0., 1., 1., 1., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 1., 1., 0., 0.]], dtype=float32)

Примечание : Я использую углы в том порядке , который вы дали им. Для OpenCV, точки в многоугольнике интерпретируются в-порядка (отсюда и разница в форме между моим выходом и вашим). Перегруппируйте углы соответственно , чтобы получить именно ту форму , что вам нужно (например, по часовой стрелке).

Примечание (2) : Я интерпретировать ваши углы как (х, у), а не как (строка, столбец), так как он не был указан в использовании вопросительных и OpenCV (х, у) конвенции точек ( в то время как Numpy использования (строка, столбец)).


Для того, чтобы сгенерировать вывод, который вы хотите, поменять местами координаты углу и изменить их следующим образом:

corners = np.asarray([(2,2), (6,3), (7,9), (4,8) ])[:,(1,0)]

При этом (и код выше) вы получите:

>>> target
array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 1., 1., 0., 0., 0., 0., 0., 0.],
       [0., 0., 1., 1., 1., 1., 1., 0., 0., 0.],
       [0., 0., 1., 1., 1., 1., 1., 1., 1., 0.],
       [0., 0., 0., 1., 1., 1., 1., 1., 1., 0.],
       [0., 0., 0., 1., 1., 1., 1., 1., 1., 1.],
       [0., 0., 0., 0., 0., 0., 0., 1., 1., 1.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)
Ответил 09/10/2019 в 13:08
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more