【问题标题】:How do I sort a 2d array that stores xy coordinates in clock wise in python?如何在python中对存储xy坐标的二维数组进行排序?
【发布时间】:2021-11-04 17:35:17
【问题描述】:

从一个包含 1 和 0 的数组中,我试图获取该数组的边界并绘制它。这是我用来获取边界的代码

import numpy as np
import math
import matplotlib.pyplot as plt


binI = np.array([[0,0,0,0,1,0,0,0,0,0,0],
                 [0,0,0,1,1,1,1,0,0,0,0],
                 [0,0,1,1,1,1,1,0,0,0,0],
                 [0,1,1,1,1,0,0,0,0,0,0],
                 [0,1,1,1,0,0,0,0,0,0,0],
                 [0,0,1,1,1,1,0,0,0,0,0],
                 [0,0,0,1,1,1,0,0,0,0,0],
                 [0,0,0,1,1,0,0,0,0,0,0]])


def boundary_Tracer(arr):
    indices_list = []
    for i in range (np.shape(arr)[0]):
        for j in range (np.shape(arr)[1]):
            if arr[i,j] == 1:
                if i == 0 and j == 0:
                    if (arr[i+1,j] == 0) or (arr[i,j+1] == 0):
                        indices_list.append([i,j])
                elif (i == 0) and (j == np.shape(arr)[1]-1):
                    if (arr[i,j-1] == 0) or (arr[i+1,j] == 0):
                        indices_list.append([i,j])
                elif (i == (np.shape(arr)[0]-1)) and j == 0:
                    if (arr[i-1,j] == 0) or (arr[i,j+1] == 0):
                        indices_list.append([i,j])
                elif (i == np.shape(arr)[0]-1) and (j == np.shape(arr)[1]-1):
                    if (arr[i-1,j] == 0) or (arr[i,j-1] == 0):
                        indices_list.append([i,j])
                elif (i in range (1,np.shape(arr)[0]-1)) and (j == 0):
                    if (arr[i-1,j] == 0) or (arr[i,j+1] == 0) or (arr[i+1,j] == 0):
                        indices_list.append([i,j])
                elif (i in range (1,np.shape(arr)[0]-1)) and (j == np.shape(arr)[1]-1):
                    if (arr[i-1,j] == 0) or (arr[i,j-1] == 0) or (arr[i+1,j] == 0):
                        indices_list.append([i,j])
                elif (i == 0) and (j in range (1,np.shape(arr)[1]-1)):
                    if (arr[i,j-1] == 0) or (arr[i,j+1] == 0) or (arr[i+1,j] == 0):
                        indices_list.append([i,j])          
                elif (i == np.shape(arr)[0]-1) and (j in range (1,np.shape(arr)[1]-1)):
                    if (arr[i-1,j] == 0) or (arr[i,j-1] == 0) or (arr[i,j+1] == 0):
                        indices_list.append([i,j])
                else:
                    if (arr[i-1,j] == 0) or (arr[i+1,j] == 0) or (arr[i,j-1] == 0) or (arr[i,j+1] == 0):
                        indices_list.append([i,j])
                
    indicies_array = np.array(indices_list)
    x_all = indicies_array[:,1]
    x_init_bw = np.min(np.where(x_all == np.min(x_all)))
    origin = np.reshape(indicies_array[x_init_bw,:],(1,2))[0]
    indicies_array = np.vstack((indicies_array,origin))
    
    return indicies_array, origin

bw = boundary_Tracer(binI)[0]
origin = boundary_Tracer(binI)[1]

plt.plot(bw[:,1],bw[:,0])
plt.gca().invert_yaxis()

我知道这很丑,我确信有更好的方法来做到这一点,但这是我最好的。无论如何,当我绘制这个时,情节在点之间曲折。我想让情节只是连接边界而不跨越标有 1 的区域的中间。

用边界的 xy 坐标(bw)重新排列数组的最佳方法是什么?

【问题讨论】:

  • 经过一番研究,我找到了一个解释,为什么这是not possible 有一组点,没有更多信息。我希望我的回答能在某种程度上有所帮助。

标签: python arrays sorting coordinates boundary


【解决方案1】:

您可以将数据转换为原点,并使用复杂的角度对数据进行排序

bw = boundary_Tracer(binI)[0]
origin = boundary_Tracer(binI)[1]

xs = (bw - bw.mean(0))
x_sort = bw[np.angle((xs[:,0] + 1j*xs[:,1])).argsort()]

# Plot to test your trace
plt.imshow(binI, cmap='gray')
plt.plot(x_sort[:,1],x_sort[:,0])
plt.gca().invert_yaxis()
plt.axis('off');

输出

这个顺时针的解决方案不是想要的结果。不在凸包上的点被排错了位置。

一个可用的排序来证明问题不在您的数据中,例如

x_sort = bw[[18,  7,  4,  1,  0,  2,  3,  6,  5,  8, 10, 12, 13, 15, 17, 16, 14, 11,  9]]
plt.imshow(binI, cmap='gray')
plt.plot(x_sort[:,1],x_sort[:,0], 'ro--')
plt.gca().invert_yaxis()
plt.axis('off');

输出

'star shaped' 非凸形状的算法,但no general unique solution 没有更多信息。

【讨论】:

  • 我喜欢你使用 np.angle 进行排序的方式。我实际上尝试了这个,它似乎工作得相当好,但线仍然穿透内部,而不是仅仅绘制边界。例如,点 (5,1) 应该连接到 (0,4) 和 (6,1),但您的答案似乎将它连接到 (0,4) 和 (4,3)。你认为有没有办法安排点,让情节只画边界而不越过内部?
  • 请注意,此方法仅适用于凸多边形。示例中的形状是凹形的,这会带来两个问题:1)质心不能保证在多边形的范围内; 2)沿周长的点的“角度值”可能不会单调增加,这意味着对它们进行排序会使它们“乱序”。
猜你喜欢
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 2021-03-30
  • 1970-01-01
  • 2013-09-13
相关资源
最近更新 更多