SciPy twórz maskę wielokąta 2D
Muszę utworzyć tablicę numpy 2D, która reprezentuje binarną maskę wielokąta, używając standardowych pakietów Pythona.
- wejście: wierzchołki wielokątów, wymiary obrazu
- Wyjście: binarna Maska wielokąta (tablica numpy 2D)
(większy kontekst: chcę uzyskać transformację odległości tego wielokąta za pomocą scipy.ndimage.morfologia.distance_transform_edt.)
Czy ktoś może mi pokazać jak to się robi?
5 answers
ODPOWIEDŹ okazuje się dość prosta:
import numpy
from PIL import Image, ImageDraw
# polygon = [(x1,y1),(x2,y2),...] or [x1,y1,x2,y2,...]
# width = ?
# height = ?
img = Image.new('L', (width, height), 0)
ImageDraw.Draw(img).polygon(polygon, outline=1, fill=1)
mask = numpy.array(img)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-17 01:35:44
Jako nieco bardziej bezpośrednia alternatywa dla odpowiedzi @Anil, matplotlib ma matplotlib.nxutils.points_inside_poly
które mogą być użyte do szybkiego rasteryzowania dowolnego wielokąta. Np.
import numpy as np
from matplotlib.nxutils import points_inside_poly
nx, ny = 10, 10
poly_verts = [(1,1), (5,1), (5,9),(3,2),(1,1)]
# Create vertex coordinates for each grid cell...
# (<0,0> is at the top left of the grid in this system)
x, y = np.meshgrid(np.arange(nx), np.arange(ny))
x, y = x.flatten(), y.flatten()
points = np.vstack((x,y)).T
grid = points_inside_poly(points, poly_verts)
grid = grid.reshape((ny,nx))
print grid
Co daje (boolean numpy array):
[[False False False False False False False False False False]
[False True True True True False False False False False]
[False False False True True False False False False False]
[False False False False True False False False False False]
[False False False False True False False False False False]
[False False False False True False False False False False]
[False False False False False False False False False False]
[False False False False False False False False False False]
[False False False False False False False False False False]
[False False False False False False False False False False]]
Powinieneś być w stanie przekazać grid
każdemu z scypiów.ndimage.morfologia funkcjonuje całkiem ładnie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 21:19:40
Aktualizacja komentarza Joego.
API Matplotlib zmieniło się od czasu opublikowania komentarza i teraz musisz użyć metody dostarczonej przez podmodule matplotlib.path
.
Roboczy kod znajduje się poniżej.
import numpy as np
from matplotlib.path import Path
nx, ny = 10, 10
poly_verts = [(1,1), (5,1), (5,9),(3,2),(1,1)]
# Create vertex coordinates for each grid cell...
# (<0,0> is at the top left of the grid in this system)
x, y = np.meshgrid(np.arange(nx), np.arange(ny))
x, y = x.flatten(), y.flatten()
points = np.vstack((x,y)).T
path = Path(poly_verts)
grid = path.contains_points(points)
grid = grid.reshape((ny,nx))
print grid
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-21 04:01:11
Możesz spróbować użyć biblioteki obrazów Pythona, PIL. Najpierw zainicjuj płótno. Następnie tworzysz obiekt rysunkowy i zaczynasz tworzyć linie. Przy założeniu, że wielokąt znajduje się w R^2 i że lista wierzchołków dla danych wejściowych jest w odpowiedniej kolejności.
Input = [(x1, y1), (x2, y2),..., (xn, yn)], (szerokość, wysokość)
from PIL import Image, ImageDraw
img = Image.new('L', (width, height), 0) # The Zero is to Specify Background Color
draw = ImageDraw.Draw(img)
for vertex in range(len(vertexlist)):
startpoint = vertexlist[vertex]
try: endpoint = vertexlist[vertex+1]
except IndexError: endpoint = vertexlist[0]
# The exception means We have reached the end and need to complete the polygon
draw.line((startpoint[0], startpoint[1], endpoint[0], endpoint[1]), fill=1)
# If you want the result as a single list
# You can make a two dimensional list or dictionary by iterating over the height and width variable
list(img.getdata())
# If you want the result as an actual Image
img.save('polgon.jpg', 'JPEG')
Tego szukałeś, czy pytałeś o coś innego?Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-06 21:30:15
Jako lekka alternatywa dla @Yusuke N. odpowiedz używając matplotlib.path
, tak samo wydajnego jak ten przez from PIL import Image, ImageDraw
(nie ma potrzeby instalowania Pillow
,, nie ma potrzeby rozważania integer
lub float
. przyda mi się, co?)
Kod roboczy znajduje się poniżej:
import pylab as plt
import numpy as np
from matplotlib.path import Path
width, height=2000, 2000
polygon=[(0.1*width, 0.1*height), (0.15*width, 0.7*height), (0.8*width, 0.75*height), (0.72*width, 0.15*height)]
poly_path=Path(polygon)
x, y = np.mgrid[:height, :width]
coors=np.hstack((x.reshape(-1, 1), y.reshape(-1,1))) # coors.shape is (4000000,2)
mask = poly_path.contains_points(coors)
plt.imshow(mask.reshape(height, width))
plt.show()
I obraz wynikowy jest poniżej, gdzie ciemny obszar jest False
, jasny obszar to True
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-06 10:46:44