【问题标题】:find polygon top-left, top-right, bottom-right and bottom-left points查找多边形左上角、右上角、右下角和左下角点
【发布时间】:2021-08-21 14:52:01
【问题描述】:

我有一组代表轮廓的 x,y 坐标如下:

array([[[   0,    0]],
       [[   0,    3]],
       [[   1,    3]],
       [[   2,    4]],
       ...,
       [[1189,    5]],
       [[1188,    5]],
       [[1183,    0]]], dtype=int32)

如何找到 TYPOLOGICAL 左上角、右上角、右下角和左下角的极值点?

以下评论后的澄清:寻求的点是 4 边四边形(例如正方形、矩形、人字形或梯形)的“明显”极值点/角。请注意,数据是有机的,并且可能看起来在同一水平/垂直线上的 2 个点可能不是,例如(10,60),(9,58)

到目前为止,我一直遵循以下逻辑(左上和右上的示例):

# slice k smallest y value elements
l = c[np.argsort(c.reshape(-1,2), axis=0)[:k][:,1]]

#ARBITRARAY - only examinie items whose y value is below 20
l = l[l[:,:,1]<20]

#sort by X value
l = sorted(l, key =lambda x:x[0])
    
minX = l[0][0]
maxX = l[len(l)-1][0]

然而这相当不完美和不雅。附上示例图片

【问题讨论】:

  • 您更新了原始问题,说您想要“典型的极值点”。我找不到它的定义,请提供一个。你所说的“明显”对我来说一点也不明显:不清楚你的形象与问题有何关系,你正在对点位置(y&lt;20)做出假设,而你对问题的解释是不合理的,你不提供示例输入或输出,对于您的问题,可能有比“Python”更多的相关标签。如果您寻求帮助,请特别改善您的问题,我无能为力。

标签: python


【解决方案1】:

编辑:根据您对此答案的 cmets 的精确度,这是更新版本:

import numpy as np


def find_corners(polygon):
    #    topmost,leftmost ───────────►xxxxxxxxxx◄────────── topmost,rightmost
    #                              xxxx         xx
    #    leftmost,topmost ──────►xxx             xx
    #                            x                xx◄────── rightmost,topmost
    #                            x                 x
    # leftmost,bottommost ──────►xx                x
    #                             xx              xx◄────── rightmost,bottommost
    #                              x             xx
    # bottommost,leftmost ────────►xxxxxxxxxxxxxxx◄──────── bottommost,rightmost

    # topmost is minimum Y
    # leftmost is minimum X
    # rightmost is maximum X, or minimum -X
    # bottommost is maximum Y, or minimum -Y
    # X is `pt[0][0]`, Y is `pt[0][1]`

    # going clock-wise :
    topmost_then_rightmost_point =    min(polygon, key=lambda pt: ( pt[0][1], -pt[0][0]))[0]
    rightmost_then_topmost_point =    min(polygon, key=lambda pt: (-pt[0][0],  pt[0][1]))[0]
    rightmost_then_bottommost_point = min(polygon, key=lambda pt: (-pt[0][0], -pt[0][1]))[0]
    bottommost_then_rightmost_point = min(polygon, key=lambda pt: (-pt[0][1], -pt[0][0]))[0]
    bottommost_then_leftmost_point =  min(polygon, key=lambda pt: (-pt[0][1],  pt[0][0]))[0]
    leftmost_then_bottommost_point =  min(polygon, key=lambda pt: ( pt[0][0], -pt[0][1]))[0]
    leftmost_then_topmost_point =     min(polygon, key=lambda pt: ( pt[0][0],  pt[0][1]))[0]
    topmost_then_leftmost_point =     min(polygon, key=lambda pt: ( pt[0][1],  pt[0][0]))[0]

    top_left = topmost_then_leftmost_point
    top_right = topmost_then_rightmost_point
    bottom_right = bottommost_then_rightmost_point
    bottom_left = bottommost_then_leftmost_point

    return tuple(top_left), tuple(top_right), tuple(bottom_right), tuple(bottom_left)


# example from OP :
a = np.array([[[   0,    0]],
              [[   0,    3]],
              [[   1,    3]],
              [[   2,    4]],
              [[1189,    5]],
              [[1188,    5]],
              [[1183,    0]]], dtype=np.int32)
assert find_corners(a) == ((0, 0), (1183, 0), (1189, 5), (1188, 5))


# another example, based on the polygon drawn in the function's comments :
# v---------------------------------------------v
#                x        x
#             x x
#
#           x                xx
#           x
#            x
#             x               x
#                            x
#              x            x
# ^---------------------------------------------^
# using the coordinates you get when putting it in a text editor (starting at line=Y=1, column=X=1) you get clock-wise :
b = np.array(
    [
        [[27, 1]],
        [[30, 4]],
        [[31, 4]],
        [[31, 7]],
        [[30, 8]],
        [[29, 9]],
        [[16, 9]],
        [[15, 7]],
        [[14, 6]],
        [[13, 5]],
        [[13, 4]],
        [[15, 2]],
        [[17, 2]],
        [[18, 1]],
    ], dtype=np.int32)
assert find_corners(b) == ((18, 1), (27, 1), (29, 9), (16, 9))

【讨论】:

  • 但是我的问题是如何从给定的一组坐标中找到(例如右上角)max_x 的 min_y?
  • @NoamNaveh 我将这些详细信息添加到我的答案中。
  • 感谢@lenormju,但这不是目的 - 此代码适用于 bbox,而我对显式多边形角感兴趣。对于上面的例子,函数应该返回类似 [(0,0), (900,0), (1189,250), (250,250)]
  • @NoamNaveh 你如何确定哪一点是拐角?如果你有两个点:(0, 1)(1, 0),哪一个是角?
  • ATM,对于每个点,我在两点之间进行交叉引用。例如,对于左上角,我得出 N 个最顶端的点,然后得出最左边的一个,然后是 K 个最左边的点,得出最顶端的一个。这是相当低效/不优雅,因此我的问题......
猜你喜欢
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
  • 1970-01-01
  • 2014-10-26
  • 2015-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多