NumPy: Selectarea forme abritrary bazate pe colțuri de formă

voturi
1

Am folosit indexare NumPy pentru un timp acum. Dar am avut doar vreodată pentru a selecta forme de bază , cum ar fi dreptunghiuri sau discuri

Cu toate acestea, am acum nevoie pentru a putea selecta mai multe forme arbitrare și nu pot găsi o modalitate bună de a face acest lucru. În mod ideal, aș dori să fie în măsură să dea o listă de colțuri și pentru toți indicii conținute în aceste colțuri să fie selectate. Putem asuma forma dată este convexă

De exemplu, având în vedere o matrice umplut cu zerouri de formă (10, 10), prin încercarea de a stabili valorile în colțuri ((2,2), (6,3), (4,8) și (7,9) ) la 1 acest lucru se va întoarce o masca ca o astfel

  [[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.]]

Acum, una dintre probleme este că nu există, în general, există o soluție unică pentru această problemă, dar luând una plauzibilă este destul de bun pentru mine. Nu mă pot gândi la o modalitate de a face acest lucru, folosind NumPy cu toate acestea, deoarece numai slicings baza și ecuații matematice clare par să fie susținute.

Are cineva alerga vreodată într-o astfel de provocare? Trebuie să recurgă la mai mult Python tradiționale pentru bucle?

Întrebat 09/10/2019 la 12:51
sursa de către utilizator
În alte limbi...                            


1 răspunsuri

voturi
2

Desigur o soluție urât, dar cum despre generarea unei măști binare pentru selecție din poligon prin OpenCV si folosind ca unul?

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

generează:

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

Notă : Sunt folosind colțuri în ordinea în care le -a dat. De OpenCV, puncte într - un poligon sunt interpretate în ordine (deci diferența de formă dintre producția mea și a ta). Reordonarea colțurile în consecință , pentru a obține exact forma care aveți nevoie ( de exemplu, sensul acelor de ceasornic).

Nota (2) : Sunt interpretând colțurile voastre ca (x, y), nu ca (rând, col), deoarece nu a fost specificat în întrebare și OpenCV utilizări (x, y) Convenția pentru puncte ( în timp ce utilizări NumPy (rând, col)).


Pentru a genera ieșire dorit, schimbați coordonatele de colț și le rearanja după cum urmează:

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

Cu aceasta (și codul de mai sus) se obtine:

>>> 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)
Publicat 09/10/2019 la 13:08
sursa de către utilizator

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