2016-05-09 47 views
1

我正在尋找一種基於一組多邊形頂點將填充的多邊形「繪製」爲numpy數組的方法。我寧願儘可能少地使用外部庫。例如:我有一個20x20的numpy數組,我希望區域由點(3,12),(8,18),(13,14),(11,6)和(4, 6)填充1.0而陣列的其餘部分包含0.0在numpy數組中生成填充的多邊形

+0

人妖,看看這是你的問題的重複(考慮到答案允許任意多邊形):http://stackoverflow.com/questions/12638790/drawing-a-rectangle-inside-a -2d-numpy-array –

+1

@將 - 實際上不是繪圖或GUI。只需填充一個和零的數組。 – Christian

+0

[這是一種使用matplotlib的方法](http://stackoverflow.com/a/21567205/1461210)(特別是我生成'mask'的部分) –

回答

5

以下解決方案僅需要numpy。它適用於頂點(在[Row,Column]座標系中按順時針順序定義)凸多邊形。凹面多邊形將起作用,但最終會切斷突出點。

import numpy as np 

def check(p1, p2, base_array): 
    """ 
    Uses the line defined by p1 and p2 to check array of 
    input indices against interpolated value 

    Returns boolean array, with True inside and False outside of shape 
    """ 
    idxs = np.indices(base_array.shape) # Create 3D array of indices 

    p1 = p1.astype(float) 
    p2 = p2.astype(float) 

    # Calculate max column idx for each row idx based on interpolated line between two points 
    max_col_idx = (idxs[0] - p1[0])/(p2[0] - p1[0]) * (p2[1] - p1[1]) + p1[1]  
    sign = np.sign(p2[0] - p1[0]) 
    return idxs[1] * sign <= max_col_idx * sign 

def create_polygon(shape, vertices): 
    """ 
    Creates np.array with dimensions defined by shape 
    Fills polygon defined by vertices with ones, all other values zero""" 
    base_array = np.zeros(shape, dtype=float) # Initialize your array of zeros 

    fill = np.ones(base_array.shape) * True # Initialize boolean array defining shape fill 

    # Create check array for each edge segment, combine into fill array 
    for k in range(vertices.shape[0]): 
     fill = np.all([fill, check(vertices[k-1], vertices[k], base_array)], axis=0) 

    # Set all values inside polygon to one 
    base_array[fill] = 1 

    return base_array 


# (Row, Col) Vertices of Polygon (Defined Clockwise) 
vertices = np.array([ 
    [5,12], 
    [8,18], 
    [13,14], 
    [11,6], 
    [4,6], 
]) 

polygon_array = create_polygon([20,20], vertices) 

# This section prints numbers at each vertex for visual check, just comment out 
# to print an array of only zeros and ones 
for n, vertex in enumerate(vertices): 
    polygon_array[vertex[0],vertex[1]] = 10*(n+1) 

# Simple routine to print the final array 
for row in polygon_array.tolist(): 
    for c in row: 
     print '{:4.1f}'.format(c), 
    print '' 
+0

哦,謝謝!我正在努力與cv2多邊形,這種解決方案甚至更快! –