2017-11-12 11 views
3

を画像として表すことができ、以下のnumpyの行列numpyの行列における正方形の座標

import numpy as np 
np_matrix = np.array([[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,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,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,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,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 
        ,[0,0,0,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,1,1,1,1,1,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0] 
        ,[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0] 
        ,[0,0,0,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,1,1,1,1,1,0,0,0] 
        ,[0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] 
        ,[0,0,0,1,0,0,0,0,0,1,0,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,1,0,0,0,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,0] 
        ,[1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0] 
        ,[2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0]]) 

print(np_matrix) 
print(np_matrix.shape) 

を考える受けます。ここ

enter image description here

入力行列に関するいくつかの仮定されている:

  • マトリクス状に変化させることができます。固定サイズではありません。
  • 2乗の数は行列ごとに異なります。しかし、マトリックスには必ず少なくとも1つの正方形があります。
  • 各緑色のドットの周りに正方形があり、四角形の中に単一のドットがあります。正方形内の点には番号2が付いています。
  • 正方形はX軸上で連続し、正方形の境界線は他の四角形の境界線と重ならないようにしてください。正方形の枠が空白が数0

でマークされている番号1

  • でマークされている私は2つの質問があります。最も効率的な方法で、どのようにすべての緑の点の座標を持つ配列を取得できますか?そして、どのように緑色の点の周りの正方形のすべての角を持つ配列を得ることができますか?ここで

    enter image description here

    私は、この例のために後に探していた結果である:

    green_dots_coordinates = [ 
        [0,0], # dot 1 with coordinates x1, y1 inside square 1 
        [7,12], # dot 2 with coordinates x2, y2 inside square 2 
        [16,27],# dot 3 with coordinates x3, y3 inside square 3 
        [29,21],# dot 4 with coordinates x4, y4 inside square 4 
        [34,7], # dot 5 with coordinates x5, y5 inside square 5 
    ] 
    
    
    
    sqaures_corners_coordinates = [ 
        #square nr 1 
        [ 
         [0,6], # x1, y1 
         [2,6], # x2, y2 
         [0,0], # x3, y3 
         [2,0], # x4, y4 
        ], 
    
        #square nr 2 
        [ 
         [3,14], # x1, y1 
         [9,14], # x2, y2 
         [3,7], # x3, y3 
         [9,7], # x4, y4 
        ], 
    
        #square nr 3 
        [ 
         [12,31], # x1, y1 
         [23,31], # x2, y2 
         [12,24], # x3, y3 
         [23,24], # x4, y4 
        ], 
    
        #square nr 4 
        [ 
         [25,22], # x1, y1 
         [32,22], # x2, y2 
         [25,15], # x3, y3 
         [32,15], # x4, y4 
        ] 
    
        ,#square nr 5 
        [ 
         [33,13], # x1, y1 
         [35,13], # x2, y2 
         [33,0], # x3, y3 
         [35,0], # x4, y4 
        ], 
    
    ] 
    
  • +2

    'xg、yg = np.where(m == 2)'は緑の点座標を与えます。残りのためのもう少し時間;) –

    +0

    'np_matrix'でどれくらいの大きさで、どれくらいのメモリがありますか? –

    +0

    np_matrixは最大10000x10000になる可能性があります。私は32GBのRAMを持っています – RaduS

    答えて

    1

    あなたの出力形式は、率直に言って、かなり奇妙で、インデックスの順序をたくさん逆転必要で、(および出力を行いかなり元の配列のインデックスを作成するための役に立たない)が、これは動作します:

    def find_boxes(np_matrix): 
        np_mat = np_matrix[::-1, :] # reversed in expected output 
        def find_extent(arr, val): 
         xn = arr.size 
         x0 = np.flatnonzero(arr == 1) 
         xi = np.searchsorted(x0, val, side = 'right') 
         if xi == x0.size: 
          x1 = x0[xi-1] 
          x2 = xn - 1 
         elif xi == 0: 
          x1 = 0 
          x2 = x0[xi] 
         else: 
          x1 = x0[xi-1] 
          x2 = x0[xi] 
         return np.array([x1, x2]) 
    
        green = np.where(np_mat == 2) 
        green = tuple(g[np.argsort(green[-1])] for g in green) 
        coords = np.empty((green[0].size, 2, 4)) 
    
        for i, (x, y) in enumerate(zip(*green)): 
         coords[i, 0] = np.tile(find_extent(np_mat[x, :], y),  2) 
         coords[i, 1] = np.repeat(find_extent(np_mat[:, y], x)[::-1], 2) # reversed again 
        return np.stack(green)[::-1].T, coords.swapaxes(1,2).astype(int) 
        # reversed again and transposed 
    

    テスト:

    find_boxes(np_matrix) 
    Out: 
    (array([[ 0, 0], 
         [ 7, 12], 
         [16, 27], 
         [29, 21], 
         [34, 7]], dtype=int32), 
    array([[[ 0, 6], 
         [ 2, 6], 
         [ 0, 0], 
         [ 2, 0]], 
    
         [[ 3, 14], 
         [ 9, 14], 
         [ 3, 7], 
         [ 9, 7]], 
    
         [[12, 31], 
         [23, 31], 
         [12, 24], 
         [23, 24]], 
    
         [[25, 22], 
         [32, 22], 
         [25, 15], 
         [32, 15]], 
    
         [[33, 13], 
         [35, 13], 
         [33, 0], 
         [35, 0]]])) 
    
    +0

    よろしくお願いします。@DanielFこれは完璧です:)リバースインデックス作成がちょっと変わっていることを知っています。機能に実装していただきありがとうございます。 – RaduS

    +1

    私はそれがあなたのシリアル投票です。気にしないでください、アップアップは削除されます。ちょうど私のために十分です:) –

    1

    4つの方向が対称型になり別の方法、:

    rm = m[::-1].T       # (j,-i) to (x,y) 
    green = np.where(rm==2)     # the costly operation 
    centers = np.vstack(green).T 
    
    rm[green] = 0 
    res = [] 
    
    for x,y in centers: 
        for s in (-1,1):      # rear/front 
         for t in range(2) :    # vertical/horizontal    
          v = *_,save = rm[x,y::s]    
          v[-1] = 1      # sentinel 
          res.append(y + s*v.argmax()) # find the first 1 
          v[-1] = save 
          x,y,rm = y,x,rm.T    # turn 
    
    rm[green] = 2 
    
    coordinates = np.array(res).reshape(-1,4) 
    corners = coordinates.take([[1,2],[3,2],[1,0],[3,0]],axis=1)  
    

    これは、Pythonのスライスの付属/除外行動に対処するために回避し、センチネルシステムとの国境を管理します。

    print(centers);print(corners) 
    
    [[ 0 0] 
    [ 7 12] 
    [16 27] 
    [29 21] 
    [34 7]] 
    ----------- 
    [[[ 0 6] 
        [ 2 6] 
        [ 0 0] 
        [ 2 0]] 
    
    [[ 3 14] 
        [ 9 14] 
        [ 3 7] 
        [ 9 7]] 
    
    [[12 31] 
        [23 31] 
        [12 24] 
        [23 24]] 
    
    [[25 22] 
        [32 22] 
        [25 15] 
        [32 15]] 
    
    [[33 13] 
        [35 13] 
        [33 0] 
        [35 0]]] 
    
    +0

    答えをBMにありがとう私はより大きい行列の性能をテストします – RaduS

    +0

    私は 'green = np.where(rm == 2) 'は' O(n²) 'です。あなたがセンターを追跡する別の方法を見つけるなら、私は試合について確信しています;) –

    関連する問題