web-dev-qa-db-ja.com

SciPy Create 2Dポリゴンマスク

標準のPythonパッケージを使用して、ポリゴンのバイナリマスクを表す数の多い2D配列を作成する必要があります。

  • 入力:ポリゴン頂点、画像寸法
  • 出力:ポリゴンのバイナリマスク(numpy 2D配列)

(より大きなコンテキスト:scipy.ndimage.morphology.distance_transform_edtを使用して、このポリゴンの距離変換を取得します。)

誰でもこれを行う方法を教えてもらえますか?

43

答えは非常に簡単であることがわかります:

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

@Anilの回答の少し直接的な代替手段として、matplotlibには matplotlib.nxutils.points_inside_poly 任意のポリゴンをすばやくラスタライズするために使用できます。例えば。

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

これは(ブール値のnumpy配列)を生成します:

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

gridを任意のscipy.ndimage.morphology関数にうまく渡すことができるはずです。

25
Joe Kington

Joeのコメントの更新。 Matplotlib APIはコメントが投稿されてから変更されており、サブモジュールmatplotlib.pathによって提供されるメソッドを使用する必要があります。

作業コードは以下のとおりです。

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
16
Yusuke N.

Pythonの画像ライブラリ、PILを使用してみることができます。まず、キャンバスを初期化します。次に、描画オブジェクトを作成し、線の作成を開始します。これは、ポリゴンがR ^ 2に存在し、入力の頂点リストが正しい順序にある​​ことを前提としています。

入力= [(x1、y1)、(x2、y2)、...、(xn、yn)]、(幅、高さ)

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

これはあなたが探していたものですか、それとも何か違うものを求めていましたか?

4
Anil