如何从无序numpy数组中提取四边形的左上、右上、左下、右下顶点坐标
你之前的实现逻辑问题在于仅依赖x坐标的排序拆分左右顶点,遇到x坐标交错的不规则四边形时就会判断错误,且多次调用np.where和unique逻辑冗余,容易出现边界异常。
解决方案
针对无序的四边形顶点排序,最优的实现方式是利用坐标的和与差特征区分四个方位,适配图像坐标系(y轴向下为正)下的顶点定位需求,完全不受输入数组顺序影响。
import numpy as np def sort_quad_vertices(pts): # 计算每个点x+y的和 sum_xy = np.sum(pts, axis=1) # 计算每个点x-y的差 diff_xy = pts[:, 0] - pts[:, 1] # 左上:x+y和最小 top_left = pts[np.argmin(sum_xy)] # 右下:x+y和最大 bottom_right = pts[np.argmax(sum_xy)] # 右上:x-y差最大 top_right = pts[np.argmax(diff_xy)] # 左下:x-y差最小 bottom_left = pts[np.argmin(diff_xy)] return top_left, top_right, bottom_left, bottom_right # 测试示例 if __name__ == "__main__": # 第一个测试用例 pts1 = np.array([(690, 110), (345, 130), (690, 300), (445, 298)]) tl, tr, bl, br = sort_quad_vertices(pts1) print("用例1结果:") print(f"左上{tl} 右上{tr} 左下{bl} 右下{br}") # 第二个测试用例 pts2 = np.array([[300,120], [213,306], [538, 171], [550, 374]]) tl, tr, bl, br = sort_quad_vertices(pts2) print("\n用例2结果:") print(f"左上{tl} 右上{tr} 左下{bl} 右下{br}") # 乱序测试用例 pts3 = np.array([[213,306],[300,120], [550, 374], [538, 171]]) tl, tr, bl, br = sort_quad_vertices(pts3) print("\n乱序用例结果:") print(f"左上{tl} 右上{tr} 左下{bl} 右下{br}")
逻辑说明
本方案基于图像坐标系的通用特性设计:
- 左上顶点的x、y数值都偏小,x+y的总和为四个点的最小值
- 右下顶点的x、y数值都偏大,x+y的总和为四个点的最大值
- 右上顶点x大、y小,x-y的差值为四个点的最大值
- 左下顶点x小、y大,x-y的差值为四个点的最小值
整个实现不需要对坐标做预排序,对所有凸四边形都可以准确输出四个方位的顶点。
内容的提问来源于stack exchange,提问作者Ahmad Anis
相关产品推荐
相关产品推荐

