2015-05-06 49 views
1

我有一個numpy的陣列,如下所示:(4,1,2)numpy的數組排序順時針

my_array = np.float32([[[ 323. , 143.]], [[ 237. , 143.]], [[ 227. , 230.]], [[ 318. , 233.]]]) 

這4個點表示位於一個圖像上的矩形的頂點,我需要重新排序順時針並將它保存到一個新的np數組中,(左上角 - >右上角 - >右下角 - >左下角)。在我的例子將是:

[237, 143] -> [323, 143] -> [318, 233] -> [227, 230] 

我已閱讀this但我對numpy的技能是沒有那麼好實現它...

謝謝!

+0

你看過這個嗎? http://stackoverflow.com/questions/2706605/sorting-a-2d-numpy-array-by-multiple-axes也許它有幫助 – RafaelC

回答

2

你可以做這樣的事情 -

import numpy as np 
from scipy.spatial import distance 

def sortpts_clockwise(A): 
    # Sort A based on Y(col-2) coordinates 
    sortedAc2 = A[np.argsort(A[:,1]),:] 

    # Get top two and bottom two points 
    top2 = sortedAc2[0:2,:] 
    bottom2 = sortedAc2[2:,:] 

    # Sort top2 points to have the first row as the top-left one 
    sortedtop2c1 = top2[np.argsort(top2[:,0]),:] 
    top_left = sortedtop2c1[0,:] 

    # Use top left point as pivot & calculate sq-euclidean dist against 
    # bottom2 points & thus get bottom-right, bottom-left sequentially 
    sqdists = distance.cdist(top_left[None], bottom2, 'sqeuclidean') 
    rest2 = bottom2[np.argsort(np.max(sqdists,0))[::-1],:] 

    # Concatenate all these points for the final output 
    return np.concatenate((sortedtop2c1,rest2),axis =0) 

樣品輸入,輸出 -

In [85]: A 
Out[85]: 
array([[ 281., 147.], 
     [ 213., 170.], 
     [ 239., 242.], 
     [ 307., 219.]], dtype=float32) 

In [86]: sortpts_clockwise(A) 
Out[86]: 
array([[ 213., 170.], 
     [ 281., 147.], 
     [ 307., 219.], 
     [ 239., 242.]], dtype=float32) 
+0

OP的注意事項:如果輸入數組的形狀爲'4 x 1 x 2',在開始執行代碼的其餘部分之前,它可能會被擠壓成「4 x 2」形狀。所以,在這種情況下,可以使用「A = np.squeeze(A)」。 – Divakar

+0

它工作的很好,但我需要改變一些矩陣,如A = np.float32([[281。,147。],[213。,170。],[239。,242。],[307., 219.]]),所以我做了一個變量容忍,任何建議如何挑選這個容差給定的分數? –

+0

@LuisEnrique請檢查編輯。現在,它使用eucl。因此必須更加健壯。 – Divakar

0

如果你需要這樣,你在你的例子顯示

new_array = my_array[[1,0,3,2]] 

或精確地順時針方向(在一般情況下,不僅爲4分)

n = len(my_array) 
order = [i for i in range(0, n-2)] 
order.insert(0, n-1) 
new_array = my_array[order]