Numpy: Velge abritrary figurer basert på form hjørner

stemmer
1

Jeg har brukt numpy indeksering for en stund nå. Men jeg har bare hatt å velge grunnleggende former som rektangler eller plater

Men trenger jeg nå å kunne velge mer vilkårlige former, og jeg kan ikke finne en god måte å gjøre dette. Ideelt sett ville jeg gjerne være i stand til å gi en liste over hjørner og for alle indeksene som finnes i disse hjørnene for å bli valgt. Vi kan anta den gitte formen er konveks

For eksempel, gis en matrise fylt med nuller av form (10, 10), ved å forsøke å sette verdiene innenfor hjørnene ((2,2), (6,3), (4,8) og (7,9) ) til 1 dette vil returnere en maske som slike

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

Nå er en av problemene er at det generelt ikke er noen unik løsning på dette problemet, men tar en plausibel man er god nok for meg. Jeg kan ikke tenke på en måte å gjøre dette ved hjelp numpy men som bare grunnleggende slicings og klare matematiske ligninger synes å bli støttet.

Har noen kjørt inn i en slik utfordring? Må jeg ty til mer tradisjonelle python for sløyfer?

Publisert på 09/10/2019 klokken 12:51
kilden bruker
På andre språk...                            


1 svar

stemmer
2

Riktignok en stygg løsning, men hva med å generere en binær maske for utvalg fra polygon via OpenCV og bruke den?

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

genererer:

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

Merk : Jeg bruker hjørnene i den rekkefølgen du ga dem. For OpenCV, blir punkter i et polygon tolket i-rekkefølge (derav forskjellen i form mellom min utgang og din). Omorganiser hjørnene tilsvarende for å få akkurat den formen du trenger (for eksempel klokken).

Note (2) : Jeg tolker dine hjørner som (x, y), ikke som (rekke, kol), siden det ikke ble spesifisert i spørsmålet og OpenCV bruker (x, y) konvensjonen om poeng (mens numpy bruksområder (rad, kol)).


For å generere output du vil, bytte hjørne koordinater og omorganisere dem som følger:

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

Med dette (og koden ovenfor) får du:

>>> 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)
Svarte 09/10/2019 kl. 13:08
kilden bruker

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