python - 查找多边形左上角、右上角、右下角和左下角点
问题描述
我有一组代表轮廓的 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]
然而,这相当不完美和不雅。附上示例图片
解决方案
编辑:根据您对此答案评论的精确度,这是更新版本:
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))
推荐阅读
- tensorflow - tfrecord 文件的最佳大小
- sql - Convert Values with Timezone to timestamp
- android - 向 AOSP 配置添加新符号时,silentoldconfig 无法构建
- android - unity游戏白屏
- javascript - 删除 JQuery 中的单个单词属性
- javascript - 在 nodejs 中模拟 curl 请求
- java - Android kotlin - 取消图库选择时应用程序停止工作
- vim - 命令中的 Vim 反斜杠
- java - 在游戏图块 Java 上覆盖游戏块
- python - 您可以在散景应用程序中嵌入 https 证书吗?Python