python - 找到多边形的左上角、右上角、右下角和左下角点

标签 python

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

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

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

以下评论的澄清:所寻求的点是 4 边四边形(例如正方形、矩形、V 形或梯形)的“明显”极值点/角。请注意,数据是有机的,并且明显看起来位于同一水平/垂直线上的 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]

然而,这相当不完美且不优雅。附示例图片

smample image

最佳答案

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

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))

关于python - 找到多边形的左上角、右上角、右下角和左下角点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67822179/

相关文章:

python - 如何使 math 和 numpy 模块中的现有函数支持用户定义的对象?

python - Anaconda Acclerate/NumbaPro CUDA 链接错误 OSX

python - 为什么 Python 代码使用 len() 函数而不是长度方法?

使用 httplib 发送 Python HTTPConnection 文件,检索进度

python - 当电子邮件正文中包含中文字符时,email.retr 检索奇怪的 =20 个字符

python - 相关系数说明-特征选择

python - 对 paramiko 使用不同的密码

python:将每个元素转换为列表中的字符串,而不使用for循环

python - 将内容添加到 python 3 中字符串中每个(非空白)行的末尾

python - 如何修复接收未注册任务错误 - Celery