带标注坐标点的最小坐标、交点及投影点求解技术求助
解决方案:定位正交直线上的最小标注点并计算交点与投影
核心逻辑拆解
- 从标注点集中提取中心坐标(包围框的中心是标注点的核心位置)和label信息
- 按x坐标分组得到所有平行Y轴的直线簇,按y坐标分组得到所有平行X轴的直线簇
- 每个簇内筛选出label最小的点(若需按坐标最小筛选可直接调整排序逻辑)
- 在筛选后的点中,分别找到x最小的平行Y轴直线、y最小的平行X轴直线,二者的正交交点即为目标点
- 生成所有点到这两条直线的投影点
代码实现
def process_annotation_points(points): # 提取每个点的中心坐标与label point_data = [(center[0], center[1], label) for _, center, label in points] # 处理平行Y轴的直线簇(x坐标相同为一组) y_parallel_clusters = {} for x, y, label in point_data: y_parallel_clusters.setdefault(x, []).append((y, label)) # 每个簇取label最小的点,再筛选出x最小的直线 y_parallel_min_label = [] for x, cluster in y_parallel_clusters.items(): # 按label升序排序,取第一个(最小label) cluster.sort(key=lambda p: p[1]) min_y, min_lbl = cluster[0] y_parallel_min_label.append((x, min_y, min_lbl)) # 按x升序排序,取第一个(最小x的直线) y_parallel_min_label.sort(key=lambda p: p[0]) target_x = y_parallel_min_label[0][0] # 处理平行X轴的直线簇(y坐标相同为一组) x_parallel_clusters = {} for x, y, label in point_data: x_parallel_clusters.setdefault(y, []).append((x, label)) # 每个簇取label最小的点,再筛选出y最小的直线 x_parallel_min_label = [] for y, cluster in x_parallel_clusters.items(): cluster.sort(key=lambda p: p[1]) min_x, min_lbl = cluster[0] x_parallel_min_label.append((y, min_x, min_lbl)) # 按y升序排序,取第一个(最小y的直线) x_parallel_min_label.sort(key=lambda p: p[0]) target_y = x_parallel_min_label[0][0] # 计算正交交点 intersection = [target_x, target_y] # 生成所有点的投影 projections = [] for _, center, label in points: proj_to_x_line = [center[0], target_y] # 到平行X轴直线的投影 proj_to_y_line = [target_x, center[1]] # 到平行Y轴直线的投影 projections.append({ "original_center": center, "label": label, "proj_x": proj_to_x_line, "proj_y": proj_to_y_line }) return { "intersection_point": intersection, "target_x_line": target_y, "target_y_line": target_x, "projections": projections }
测试示例
# 模拟用户提供的示例点集(包含两个label=0的目标点) sample_points = [ [[[10,300],[14,300],[14,320],[10,320]], [12,310], 0], [[[50,310],[200,310],[200,315],[50,315]], [125,310], 0], [[[20,200],[24,200],[24,220],[20,220]], [22,210], 1], [[[100,310],[150,310],[150,315],[100,315]], [125,312.5], 2] ] # 执行处理 result = process_annotation_points(sample_points) # 输出结果 print("正交交点:", result["intersection_point"]) print("\n所有点的投影信息:") for item in result["projections"]: print(f"Label {item['label']} | 原中心: {item['original_center']} | 到X轴平行线投影: {item['proj_x']} | 到Y轴平行线投影: {item['proj_y']}")
调整说明
- 若“最小标注点”指坐标最小而非label最小,只需将簇内排序逻辑改为按坐标排序:
# 平行Y轴簇内按y坐标升序取最小点 cluster.sort(key=lambda p: p[0]) # 平行X轴簇内按x坐标升序取最小点 cluster.sort(key=lambda p: p[0]) - 若需仅处理特定label的点(如只筛选label=0),在提取
point_data时添加过滤:point_data = [(center[0], center[1], label) for _, center, label in points if label == 0]
内容的提问来源于stack exchange,提问作者Eftal Gezer
相关产品推荐
相关产品推荐

