2014-02-07 46 views
3

循環我在python定義的一些形狀,其具有相應的角點,這樣的:通過節點和提取的屬性在Networkx

square = [[251, 184], 
      [22, 192], 
      [41, 350], 
      [244, 346]] 

triangle = [[250, 181], 
      [133, 43], 
      [21, 188]] 

pentagon = [[131, 37], 
      [11, 192], 
      [37, 354], 
      [247, 350], 
      [256, 182]] 

然後,我使用NetworkX包以創建圖表:

G = nx.DiGraph() 

然後,我在圖中爲每個形狀創建節點:

G.add_node('square', points = square, center = (139, 265)) 
G.add_node('triangle', points = triangle, center = (139, 135)) 
G.add_node('pentagon', points = pentagon, center = (138, 223)) 

現在的問題,我如果條件滿足,必須創建連接兩個節點的邊。以滿足該條件是如果形狀的中心是內部或外部的另一形狀,然後創建這樣的邊緣:

G.add_edge('triangle', 'pentagon', relation = 'inside') 
G.add_edge('triangle', 'square', relation = 'outside') 

爲此,我要通過節點循環,提取center的形狀,提取其他形狀(不是它們自己,它是無用的)並且使pointPolygonTest提取的

我一直頗多,但沒有任何解決辦法就出來了。最近的(沒有真正有效的)解決方案,我得到的是這樣的:

nodes_p=dict([((u),d['points']) for u,d in G.nodes(data=True)]) 
nodes_c=dict([((u),d['center']) for u,d in G.nodes(data=True)]) 
for z,c in nodes_c.items(): 
    print z + ' with center', c 
    for z,p in nodes_p.items(): 
     p_array = np.asarray(p) 
     if cv2.pointPolygonTest(p_array,c,False)>=0: 
      print 'inside ' + z 
      #create edge 
     else: 
      print 'outside ' + z 
      #create edge 

這給了我下面的輸出,這不是最優的,因爲有一些關係應該避免的(如triangle inside triangle)或一些錯誤的關係(如pentagon inside square

triangle with center (139, 135) 
inside triangle 
outside square 
inside pentagon 
square with center (139, 265) 
outside triangle 
inside square 
inside pentagon 
pentagon with center (138, 223) 
outside triangle 
inside square 
inside pentagon 

我該如何解決這個問題?任何建議都是有好處的。提醒:主要問題是如何遍歷節點並提取信息。我導入整個腳本的程序包有:

import numpy as np 
import networkx as nx 
import cv2 
+0

您應該添加您的導入語句('numpy'和'cv2')來幫助未來的讀者 – yardsale8

回答

3

這是你的多邊形的圖像 Polygon image

首先,有沒有需要轉換的節點字典,我們可以對他們直接進行迭代。這個代碼是基於關閉的this example

for u,outer_d in G.nodes(data=True): 
    center = outer_d['center'] 
    print u, "with center", center 
    for v, inner_d in G.nodes(data=True): 
     #Don't compare self to self 
     if u != v: 
      # Create a source image 
      src = np.zeros((400,400),np.uint8)   
      # draw an polygon on image src 
      points = np.array(inner_d['points'],np.int0) 
      cv2.polylines(src,[points],True,255,3) 
      contours,_ = cv2.findContours(src,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 
      if cv2.pointPolygonTest(contours[0],center,True) <= 0: 
       print 'outside',v 
      else: 
       print 'inside',v 

輸出是

pentagon with center (138, 223) 
inside square 
outside triangle 
square with center (139, 265) 
inside pentagon 
outside triangle 
triangle with center (139, 135) 
inside pentagon 
outside square 

既然目標是確定一個多邊形完全是另一個裏面,我們應該檢查所有一個多邊形的頂點是在另一個。這是一個暫定(不幸未經測試)的解決方案。

def checkPoint(point, poly,r=400): 
    ''' determine if point is on the interior of poly''' 
    # Create a source image 
    src = np.zeros((r,r),np.uint8)  
    # draw an polygon on image src 
    verts = np.array(poly,np.int0) 
    cv2.polylines(src,[verts],True,255,3) 
    contours,_ = cv2.findContours(src,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) 
    return cv2.pointPolygonTest(contours[0],tuple(point),True) > 0: 


for u,outer_d in G.nodes(data=True): 
    points = outer_d['points'] 
    center = outer_d['center'] 
    print u, "with center", center 
    for v, inner_d in G.nodes(data=True): 
     poly = inner_d['points'] 
     if u != v: 
      if all([checkPoint(point,poly) for point in points]): 
       print 'inside',v 
      else: 
       print 'outside',v 

該示例的輸出如下,現在應該是正確的。

pentagon with center (138, 223) 
outside square 
outside triangle 
square with center (139, 265) 
inside pentagon 
outside triangle 
triangle with center (139, 135) 
inside pentagon 
outside square 

請注意,我已經假設多邊形是凸的。如果不是這樣,那麼你可以檢查輪廓上的所有點,而不是隻檢查角點。您也可以使用cv2進行凸形檢查,詳情請參閱this blog

+0

抱歉,混淆了不平等。現在是否正確? – yardsale8

+0

輸出錯誤。它應該是:五角形外三角形,外部正方形,五角形內部,外部三角形,五角形內部三角形,外部正方形 –

+0

「內部」表示中心在裏面,對嗎?如果是這樣,它應該是三角形外面的五邊形,**裏面的**正方形,五邊形內的正方形,三角形外面,五角形內的三角形,外面的正方形 – yardsale8

相關問題